diff --git a/src/renderer/__mocks__/notifications-mocks.ts b/src/renderer/__mocks__/notifications-mocks.ts index f4dadb94b..a113761db 100644 --- a/src/renderer/__mocks__/notifications-mocks.ts +++ b/src/renderer/__mocks__/notifications-mocks.ts @@ -1,10 +1,5 @@ import type { AccountNotifications, GitifyError } from '../types'; -import type { - Notification, - StateType, - Subject, - SubjectType, -} from '../typesGitHub'; +import type { Notification, StateType, SubjectType } from '../typesGitHub'; import { mockEnterpriseNotifications, mockGitHubNotifications, @@ -36,18 +31,20 @@ export const mockSingleAccountNotifications: AccountNotifications[] = [ }, ]; -export function createSubjectMock(mocks: { +export function mockNotificationWithSubject(mocks: { title?: string; type?: SubjectType; state?: StateType; -}): Subject { +}): Notification { return { - title: mocks.title ?? 'Mock Subject', - type: mocks.type ?? ('Unknown' as SubjectType), - state: mocks.state ?? ('Unknown' as StateType), - url: null, - latest_comment_url: null, - }; + subject: { + title: mocks.title ?? 'Mock Subject', + type: mocks.type ?? ('Unknown' as SubjectType), + state: mocks.state ?? ('Unknown' as StateType), + url: null, + latest_comment_url: null, + }, + } as Notification; } export function mockAccountWithError(error: GitifyError): AccountNotifications { @@ -58,7 +55,7 @@ export function mockAccountWithError(error: GitifyError): AccountNotifications { }; } -export function createMockNotificationForRepoName( +export function mockNotificationWithRepoName( id: string, repoFullName: string | null, ): Notification { diff --git a/src/renderer/components/notifications/NotificationRow.tsx b/src/renderer/components/notifications/NotificationRow.tsx index 976f46bc7..2f4d40f6d 100644 --- a/src/renderer/components/notifications/NotificationRow.tsx +++ b/src/renderer/components/notifications/NotificationRow.tsx @@ -63,11 +63,11 @@ export const NotificationRow: FC = ({ }; const handler = createNotificationHandler(notification); - const NotificationIcon = handler.iconType(notification.subject); - const iconColor = handler.iconColor(notification.subject); - const notificationType = handler.formattedNotificationType(notification); - const notificationNumber = handler.formattedNotificationNumber(notification); - const notificationTitle = handler.formattedNotificationTitle(notification); + const NotificationIcon = handler.iconType(); + const iconColor = handler.iconColor(); + const notificationType = handler.formattedNotificationType(); + const notificationNumber = handler.formattedNotificationNumber(); + const notificationTitle = handler.formattedNotificationTitle(); const groupByDate = settings.groupBy === GroupBy.DATE; diff --git a/src/renderer/utils/notifications/group.test.ts b/src/renderer/utils/notifications/group.test.ts index ba9d39642..88ec55865 100644 --- a/src/renderer/utils/notifications/group.test.ts +++ b/src/renderer/utils/notifications/group.test.ts @@ -1,4 +1,4 @@ -import { createMockNotificationForRepoName } from '../../__mocks__/notifications-mocks'; +import { mockNotificationWithRepoName } from '../../__mocks__/notifications-mocks'; import { mockSettings } from '../../__mocks__/state-mocks'; import { GroupBy } from '../../types'; import type { Notification } from '../../typesGitHub'; @@ -24,9 +24,9 @@ describe('renderer/utils/notifications/group.ts', () => { describe('groupNotificationsByRepository', () => { it('groups notifications by repository full_name', () => { const notifications: Notification[] = [ - createMockNotificationForRepoName('1', 'owner/repo-a'), - createMockNotificationForRepoName('2', 'owner/repo-b'), - createMockNotificationForRepoName('3', 'owner/repo-a'), + mockNotificationWithRepoName('1', 'owner/repo-a'), + mockNotificationWithRepoName('2', 'owner/repo-b'), + mockNotificationWithRepoName('3', 'owner/repo-a'), ]; const result = groupNotificationsByRepository(notifications); @@ -38,10 +38,10 @@ describe('renderer/utils/notifications/group.ts', () => { it('preserves first-seen repository order', () => { const notifications: Notification[] = [ - createMockNotificationForRepoName('1', 'owner/repo-c'), - createMockNotificationForRepoName('2', 'owner/repo-a'), - createMockNotificationForRepoName('3', 'owner/repo-b'), - createMockNotificationForRepoName('4', 'owner/repo-a'), + mockNotificationWithRepoName('1', 'owner/repo-c'), + mockNotificationWithRepoName('2', 'owner/repo-a'), + mockNotificationWithRepoName('3', 'owner/repo-b'), + mockNotificationWithRepoName('4', 'owner/repo-a'), ]; const result = groupNotificationsByRepository(notifications); @@ -52,9 +52,9 @@ describe('renderer/utils/notifications/group.ts', () => { it('skips notifications without repository data', () => { const notifications: Notification[] = [ - createMockNotificationForRepoName('1', 'owner/repo-a'), - createMockNotificationForRepoName('2', null), - createMockNotificationForRepoName('3', 'owner/repo-a'), + mockNotificationWithRepoName('1', 'owner/repo-a'), + mockNotificationWithRepoName('2', null), + mockNotificationWithRepoName('3', 'owner/repo-a'), ]; const result = groupNotificationsByRepository(notifications); @@ -73,8 +73,8 @@ describe('renderer/utils/notifications/group.ts', () => { it('returns empty map when all notifications lack repository data', () => { const notifications: Notification[] = [ - createMockNotificationForRepoName('1', null), - createMockNotificationForRepoName('2', null), + mockNotificationWithRepoName('1', null), + mockNotificationWithRepoName('2', null), ]; const result = groupNotificationsByRepository(notifications); @@ -87,10 +87,10 @@ describe('renderer/utils/notifications/group.ts', () => { it('returns repository-grouped order when groupBy is REPOSITORY', () => { const settings = { ...mockSettings, groupBy: GroupBy.REPOSITORY }; const notifications: Notification[] = [ - createMockNotificationForRepoName('1', 'owner/repo-b'), - createMockNotificationForRepoName('2', 'owner/repo-a'), - createMockNotificationForRepoName('3', 'owner/repo-b'), - createMockNotificationForRepoName('4', 'owner/repo-a'), + mockNotificationWithRepoName('1', 'owner/repo-b'), + mockNotificationWithRepoName('2', 'owner/repo-a'), + mockNotificationWithRepoName('3', 'owner/repo-b'), + mockNotificationWithRepoName('4', 'owner/repo-a'), ]; const result = getFlattenedNotificationsByRepo(notifications, settings); @@ -102,9 +102,9 @@ describe('renderer/utils/notifications/group.ts', () => { it('returns natural account order when groupBy is DATE', () => { const settings = { ...mockSettings, groupBy: GroupBy.DATE }; const notifications: Notification[] = [ - createMockNotificationForRepoName('1', 'owner/repo-b'), - createMockNotificationForRepoName('2', 'owner/repo-a'), - createMockNotificationForRepoName('3', 'owner/repo-b'), + mockNotificationWithRepoName('1', 'owner/repo-b'), + mockNotificationWithRepoName('2', 'owner/repo-a'), + mockNotificationWithRepoName('3', 'owner/repo-b'), ]; const result = getFlattenedNotificationsByRepo(notifications, settings); @@ -125,9 +125,9 @@ describe('renderer/utils/notifications/group.ts', () => { it('handles notifications without repository data when grouped', () => { const settings = { ...mockSettings, groupBy: GroupBy.REPOSITORY }; const notifications: Notification[] = [ - createMockNotificationForRepoName('1', 'owner/repo-a'), - createMockNotificationForRepoName('2', null), - createMockNotificationForRepoName('3', 'owner/repo-a'), + mockNotificationWithRepoName('1', 'owner/repo-a'), + mockNotificationWithRepoName('2', null), + mockNotificationWithRepoName('3', 'owner/repo-a'), ]; const result = getFlattenedNotificationsByRepo(notifications, settings); @@ -139,9 +139,9 @@ describe('renderer/utils/notifications/group.ts', () => { it('preserves notifications without repository data when not grouped', () => { const settings = { ...mockSettings, groupBy: GroupBy.DATE }; const notifications: Notification[] = [ - createMockNotificationForRepoName('1', 'owner/repo-a'), - createMockNotificationForRepoName('2', null), - createMockNotificationForRepoName('3', 'owner/repo-a'), + mockNotificationWithRepoName('1', 'owner/repo-a'), + mockNotificationWithRepoName('2', null), + mockNotificationWithRepoName('3', 'owner/repo-a'), ]; const result = getFlattenedNotificationsByRepo(notifications, settings); diff --git a/src/renderer/utils/notifications/handlers/checkSuite.test.ts b/src/renderer/utils/notifications/handlers/checkSuite.test.ts index 8f50f8af1..30f781bc3 100644 --- a/src/renderer/utils/notifications/handlers/checkSuite.test.ts +++ b/src/renderer/utils/notifications/handlers/checkSuite.test.ts @@ -1,7 +1,8 @@ -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; -import { checkSuiteHandler, getCheckSuiteAttributes } from './checkSuite'; +import type { StateType } from '../../../typesGitHub'; +import { createCheckSuiteHandler, getCheckSuiteAttributes } from './checkSuite'; describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { describe('enrich', () => { @@ -11,10 +12,8 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: 'cancelled', @@ -28,10 +27,8 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: 'failure', @@ -45,10 +42,8 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: 'failure', @@ -62,10 +57,8 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: 'failure', @@ -79,10 +72,8 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: 'skipped', @@ -96,10 +87,8 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: 'success', @@ -113,10 +102,8 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toBeNull(); }); @@ -127,57 +114,29 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => { type: 'CheckSuite', }); - const result = await checkSuiteHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createCheckSuiteHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toBeNull(); }); }); - it('iconType', () => { - expect( - checkSuiteHandler.iconType( - createSubjectMock({ type: 'CheckSuite', state: null }), - ).displayName, - ).toBe('RocketIcon'); - - expect( - checkSuiteHandler.iconType( - createSubjectMock({ - type: 'CheckSuite', - state: 'cancelled', - }), - ).displayName, - ).toBe('StopIcon'); - - expect( - checkSuiteHandler.iconType( - createSubjectMock({ - type: 'CheckSuite', - state: 'failure', - }), - ).displayName, - ).toBe('XIcon'); - - expect( - checkSuiteHandler.iconType( - createSubjectMock({ - type: 'CheckSuite', - state: 'skipped', - }), - ).displayName, - ).toBe('SkipIcon'); - - expect( - checkSuiteHandler.iconType( - createSubjectMock({ - type: 'CheckSuite', - state: 'success', - }), - ).displayName, - ).toBe('CheckIcon'); + describe('iconType', () => { + const cases: Array<[StateType, string]> = [ + [null, 'RocketIcon'], + ['cancelled', 'StopIcon'], + ['failure', 'XIcon'], + ['skipped', 'SkipIcon'], + ['success', 'CheckIcon'], + ]; + + it.each(cases)('returns expected icon for %s', (state, expectedIcon) => { + const handler = createCheckSuiteHandler( + mockNotificationWithSubject({ type: 'CheckSuite', state }), + ); + + expect(handler.iconType().displayName).toBe(expectedIcon); + }); }); describe('getCheckSuiteState', () => { diff --git a/src/renderer/utils/notifications/handlers/checkSuite.ts b/src/renderer/utils/notifications/handlers/checkSuite.ts index e4a6fcf36..39787cfaa 100644 --- a/src/renderer/utils/notifications/handlers/checkSuite.ts +++ b/src/renderer/utils/notifications/handlers/checkSuite.ts @@ -15,18 +15,15 @@ import type { CheckSuiteStatus, GitifySubject, Notification, - Subject, } from '../../../typesGitHub'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; class CheckSuiteHandler extends DefaultHandler { readonly type = 'CheckSuite'; - async enrich( - notification: Notification, - _settings: SettingsState, - ): Promise { - const state = getCheckSuiteAttributes(notification)?.status; + async enrich(_settings: SettingsState): Promise { + const state = getCheckSuiteAttributes(this.notification)?.status; if (state) { return { @@ -38,8 +35,8 @@ class CheckSuiteHandler extends DefaultHandler { return null; } - iconType(subject: Subject): FC | null { - switch (subject.state) { + iconType(): FC | null { + switch (this.notification.subject.state) { case 'cancelled': return StopIcon; case 'failure': @@ -54,7 +51,11 @@ class CheckSuiteHandler extends DefaultHandler { } } -export const checkSuiteHandler = new CheckSuiteHandler(); +export function createCheckSuiteHandler( + notification: Notification, +): NotificationTypeHandler { + return new CheckSuiteHandler(notification); +} /** * Ideally we would be using a GitHub API to fetch the CheckSuite / WorkflowRun state, diff --git a/src/renderer/utils/notifications/handlers/commit.test.ts b/src/renderer/utils/notifications/handlers/commit.test.ts index bf9d26ba9..ea98c8f0d 100644 --- a/src/renderer/utils/notifications/handlers/commit.test.ts +++ b/src/renderer/utils/notifications/handlers/commit.test.ts @@ -1,14 +1,14 @@ import axios from 'axios'; import nock from 'nock'; -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification, partialMockUser, } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; import type { Link } from '../../../types'; -import { commitHandler } from './commit'; +import { createCommitHandler } from './commit'; describe('renderer/utils/notifications/handlers/commit.ts', () => { describe('enrich', () => { @@ -40,7 +40,8 @@ describe('renderer/utils/notifications/handlers/commit.ts', () => { .get('/repos/gitify-app/notifications-test/comments/141012658') .reply(200, { user: mockCommenter }); - const result = await commitHandler.enrich(mockNotification, mockSettings); + const handler = createCommitHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: null, @@ -67,7 +68,8 @@ describe('renderer/utils/notifications/handlers/commit.ts', () => { ) .reply(200, { author: mockAuthor }); - const result = await commitHandler.enrich(mockNotification, mockSettings); + const handler = createCommitHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: null, @@ -88,7 +90,8 @@ describe('renderer/utils/notifications/handlers/commit.ts', () => { latest_comment_url: null, }); - const result = await commitHandler.enrich(mockNotification, { + const handler = createCommitHandler(mockNotification); + const result = await handler.enrich({ ...mockSettings, filterStates: ['closed'], }); @@ -98,8 +101,12 @@ describe('renderer/utils/notifications/handlers/commit.ts', () => { }); it('iconType', () => { - expect( - commitHandler.iconType(createSubjectMock({ type: 'Commit' })).displayName, - ).toBe('GitCommitIcon'); + const handler = createCommitHandler( + mockNotificationWithSubject({ + type: 'Commit', + }), + ); + + expect(handler.iconType().displayName).toBe('GitCommitIcon'); }); }); diff --git a/src/renderer/utils/notifications/handlers/commit.ts b/src/renderer/utils/notifications/handlers/commit.ts index 882134f03..bcea66cc3 100644 --- a/src/renderer/utils/notifications/handlers/commit.ts +++ b/src/renderer/utils/notifications/handlers/commit.ts @@ -8,21 +8,18 @@ import type { GitifySubject, Notification, StateType, - Subject, User, } from '../../../typesGitHub'; import { getCommit, getCommitComment } from '../../api/client'; import { isStateFilteredOut } from '../filters/filter'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; import { getSubjectUser } from './utils'; class CommitHandler extends DefaultHandler { readonly type = 'Commit'; - async enrich( - notification: Notification, - settings: SettingsState, - ): Promise { + async enrich(settings: SettingsState): Promise { const commitState: StateType = null; // Commit notifications are stateless // Return early if this notification would be hidden by filters @@ -32,18 +29,21 @@ class CommitHandler extends DefaultHandler { let user: User; - if (notification.subject.latest_comment_url) { + if (this.notification.subject.latest_comment_url) { const commitComment = ( await getCommitComment( - notification.subject.latest_comment_url, - notification.account.token, + this.notification.subject.latest_comment_url, + this.notification.account.token, ) ).data; user = commitComment.user; } else { const commit = ( - await getCommit(notification.subject.url, notification.account.token) + await getCommit( + this.notification.subject.url, + this.notification.account.token, + ) ).data; user = commit.author; @@ -55,9 +55,13 @@ class CommitHandler extends DefaultHandler { }; } - iconType(_subject: Subject): FC | null { + iconType(): FC | null { return GitCommitIcon; } } -export const commitHandler = new CommitHandler(); +export function createCommitHandler( + notification: Notification, +): NotificationTypeHandler { + return new CommitHandler(notification); +} diff --git a/src/renderer/utils/notifications/handlers/default.test.ts b/src/renderer/utils/notifications/handlers/default.test.ts index d1abc5f7c..07784c97b 100644 --- a/src/renderer/utils/notifications/handlers/default.test.ts +++ b/src/renderer/utils/notifications/handlers/default.test.ts @@ -1,9 +1,9 @@ -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; import { IconColor } from '../../../types'; import type { StateType } from '../../../typesGitHub'; -import { defaultHandler } from './default'; +import { createDefaultHandler } from './default'; describe('renderer/utils/notifications/handlers/default.ts', () => { describe('enrich', () => { @@ -14,19 +14,17 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { type: 'RepositoryInvitation', }); - const result = await defaultHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDefaultHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toBeNull(); }); }); it('iconType', () => { - expect(defaultHandler.iconType(createSubjectMock({})).displayName).toBe( - 'QuestionIcon', - ); + const handler = createDefaultHandler(mockNotificationWithSubject({})); + + expect(handler.iconType().displayName).toBe('QuestionIcon'); }); describe('iconColor', () => { @@ -50,8 +48,11 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { ]; it.each(cases)('returns correct color for state %s', (state, expected) => { - const subject = createSubjectMock({ state }); - expect(defaultHandler.iconColor(subject)).toBe(expected); + const handler = createDefaultHandler( + mockNotificationWithSubject({ state }), + ); + + expect(handler.iconColor()).toBe(expected); }); }); @@ -63,9 +64,9 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { state: 'open', }); - expect(defaultHandler.formattedNotificationType(notification)).toBe( - 'Open Pull Request', - ); + const handler = createDefaultHandler(notification); + + expect(handler.formattedNotificationType()).toBe('Open Pull Request'); }); it('handles missing state (null) gracefully', () => { @@ -75,9 +76,9 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { state: null, }); - expect(defaultHandler.formattedNotificationType(notification)).toBe( - 'Issue', - ); + const handler = createDefaultHandler(notification); + + expect(handler.formattedNotificationType()).toBe('Issue'); }); }); @@ -89,9 +90,10 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { state: 'open', }); notification.subject.number = 42; - expect(defaultHandler.formattedNotificationNumber(notification)).toBe( - '#42', - ); + + const handler = createDefaultHandler(notification); + + expect(handler.formattedNotificationNumber()).toBe('#42'); }); it('returns empty string when number absent', () => { @@ -100,7 +102,10 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { type: 'Issue', state: 'open', }); - expect(defaultHandler.formattedNotificationNumber(notification)).toBe(''); + + const handler = createDefaultHandler(notification); + + expect(handler.formattedNotificationNumber()).toBe(''); }); }); @@ -112,9 +117,10 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { state: 'open', }); notification.subject.number = 101; - expect(defaultHandler.formattedNotificationTitle(notification)).toBe( - 'Fix bug [#101]', - ); + + const handler = createDefaultHandler(notification); + + expect(handler.formattedNotificationTitle()).toBe('Fix bug [#101]'); }); it('returns title unchanged when number missing', () => { @@ -123,9 +129,10 @@ describe('renderer/utils/notifications/handlers/default.ts', () => { type: 'Issue', state: 'open', }); - expect(defaultHandler.formattedNotificationTitle(notification)).toBe( - 'Improve docs', - ); + + const handler = createDefaultHandler(notification); + + expect(handler.formattedNotificationTitle()).toBe('Improve docs'); }); }); }); diff --git a/src/renderer/utils/notifications/handlers/default.ts b/src/renderer/utils/notifications/handlers/default.ts index 99f66b474..4e5953832 100644 --- a/src/renderer/utils/notifications/handlers/default.ts +++ b/src/renderer/utils/notifications/handlers/default.ts @@ -8,7 +8,6 @@ import { IconColor } from '../../../types'; import type { GitifySubject, Notification, - Subject, SubjectType, } from '../../../typesGitHub'; import type { NotificationTypeHandler } from './types'; @@ -16,20 +15,22 @@ import { formatForDisplay } from './utils'; export class DefaultHandler implements NotificationTypeHandler { type?: SubjectType; + notification: Notification; - async enrich( - _notification: Notification, - _settings: SettingsState, - ): Promise { + constructor(notification: Notification) { + this.notification = notification; + } + + async enrich(_settings: SettingsState): Promise { return null; } - iconType(_subject: Subject): FC | null { + iconType(): FC | null { return QuestionIcon; } - iconColor(subject: Subject): IconColor { - switch (subject.state) { + iconColor(): IconColor { + switch (this.notification.subject.state) { case 'open': case 'reopened': case 'ANSWERED': @@ -47,25 +48,29 @@ export class DefaultHandler implements NotificationTypeHandler { } } - formattedNotificationType(notification: Notification): string { + formattedNotificationType(): string { return formatForDisplay([ - notification.subject.state, - notification.subject.type, + this.notification.subject.state, + this.notification.subject.type, ]); } - formattedNotificationNumber(notification: Notification): string { - return notification.subject?.number - ? `#${notification.subject.number}` + formattedNotificationNumber(): string { + return this.notification.subject?.number + ? `#${this.notification.subject.number}` : ''; } - formattedNotificationTitle(notification: Notification): string { - let title = notification.subject.title; + formattedNotificationTitle(): string { + let title = this.notification.subject.title; - if (notification.subject?.number) { - title = `${title} [${this.formattedNotificationNumber(notification)}]`; + if (this.notification.subject?.number) { + title = `${title} [${this.formattedNotificationNumber()}]`; } return title; } } -export const defaultHandler = new DefaultHandler(); +export function createDefaultHandler( + notification: Notification, +): NotificationTypeHandler { + return new DefaultHandler(notification); +} diff --git a/src/renderer/utils/notifications/handlers/discussion.test.ts b/src/renderer/utils/notifications/handlers/discussion.test.ts index e81878886..be1d1f6d3 100644 --- a/src/renderer/utils/notifications/handlers/discussion.test.ts +++ b/src/renderer/utils/notifications/handlers/discussion.test.ts @@ -1,7 +1,7 @@ import axios from 'axios'; import nock from 'nock'; -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; import type { Link } from '../../../types'; @@ -10,8 +10,9 @@ import type { DiscussionAuthor, DiscussionStateType, Repository, + StateType, } from '../../../typesGitHub'; -import { discussionHandler } from './discussion'; +import { createDiscussionHandler } from './discussion'; const mockDiscussionAuthor: DiscussionAuthor = { login: 'discussion-author', @@ -52,10 +53,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -82,10 +81,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -112,10 +109,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -142,10 +137,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -172,10 +165,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -202,10 +193,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -240,10 +229,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -270,7 +257,8 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }, }); - const result = await discussionHandler.enrich(mockNotification, { + const handler = createDiscussionHandler(mockNotification); + const result = await handler.enrich({ ...mockSettings, filterStates: ['closed'], }); @@ -279,29 +267,21 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => { }); }); - it('iconType', () => { - expect( - discussionHandler.iconType(createSubjectMock({ type: 'Discussion' })) - .displayName, - ).toBe('CommentDiscussionIcon'); - - expect( - discussionHandler.iconType( - createSubjectMock({ type: 'Discussion', state: 'DUPLICATE' }), - ).displayName, - ).toBe('DiscussionDuplicateIcon'); - - expect( - discussionHandler.iconType( - createSubjectMock({ type: 'Discussion', state: 'OUTDATED' }), - ).displayName, - ).toBe('DiscussionOutdatedIcon'); - - expect( - discussionHandler.iconType( - createSubjectMock({ type: 'Discussion', state: 'RESOLVED' }), - ).displayName, - ).toBe('DiscussionClosedIcon'); + describe('iconType', () => { + const cases: Array<[StateType, string]> = [ + [null, 'CommentDiscussionIcon'], + ['DUPLICATE', 'DiscussionDuplicateIcon'], + ['OUTDATED', 'DiscussionOutdatedIcon'], + ['RESOLVED', 'DiscussionClosedIcon'], + ]; + + it.each(cases)('returns expected icon for %s', (state, expectedIcon) => { + const handler = createDiscussionHandler( + mockNotificationWithSubject({ type: 'Discussion', state }), + ); + + expect(handler.iconType().displayName).toBe(expectedIcon); + }); }); }); diff --git a/src/renderer/utils/notifications/handlers/discussion.ts b/src/renderer/utils/notifications/handlers/discussion.ts index 255cd68b1..af61434a5 100644 --- a/src/renderer/utils/notifications/handlers/discussion.ts +++ b/src/renderer/utils/notifications/handlers/discussion.ts @@ -16,21 +16,18 @@ import type { DiscussionStateType, GitifySubject, Notification, - Subject, SubjectUser, } from '../../../typesGitHub'; import { getLatestDiscussion } from '../../api/client'; import { isStateFilteredOut } from '../filters/filter'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; class DiscussionHandler extends DefaultHandler { readonly type = 'Discussion'; - async enrich( - notification: Notification, - settings: SettingsState, - ): Promise { - const discussion = await getLatestDiscussion(notification); + async enrich(settings: SettingsState): Promise { + const discussion = await getLatestDiscussion(this.notification); let discussionState: DiscussionStateType = 'OPEN'; if (discussion) { @@ -49,7 +46,7 @@ class DiscussionHandler extends DefaultHandler { } const latestDiscussionComment = getClosestDiscussionCommentOrReply( - notification, + this.notification, discussion.comments.nodes, ); @@ -77,8 +74,8 @@ class DiscussionHandler extends DefaultHandler { }; } - iconType(subject: Subject): FC | null { - switch (subject.state) { + iconType(): FC | null { + switch (this.notification.subject.state) { case 'DUPLICATE': return DiscussionDuplicateIcon; case 'OUTDATED': @@ -91,7 +88,11 @@ class DiscussionHandler extends DefaultHandler { } } -export const discussionHandler = new DiscussionHandler(); +export function createDiscussionHandler( + notification: Notification, +): NotificationTypeHandler { + return new DiscussionHandler(notification); +} export function getClosestDiscussionCommentOrReply( notification: Notification, diff --git a/src/renderer/utils/notifications/handlers/index.test.ts b/src/renderer/utils/notifications/handlers/index.test.ts index 7964c41fd..1f3ea1b6c 100644 --- a/src/renderer/utils/notifications/handlers/index.test.ts +++ b/src/renderer/utils/notifications/handlers/index.test.ts @@ -1,42 +1,47 @@ import { partialMockNotification } from '../../../__mocks__/partial-mocks'; import type { SubjectType } from '../../../typesGitHub'; -import { checkSuiteHandler } from './checkSuite'; -import { commitHandler } from './commit'; -import { defaultHandler } from './default'; -import { discussionHandler } from './discussion'; +import { createCheckSuiteHandler } from './checkSuite'; +import { createCommitHandler } from './commit'; +import { createDefaultHandler } from './default'; +import { createDiscussionHandler } from './discussion'; import { createNotificationHandler } from './index'; -import { issueHandler } from './issue'; -import { pullRequestHandler } from './pullRequest'; -import { releaseHandler } from './release'; -import { repositoryDependabotAlertsThreadHandler } from './repositoryDependabotAlertsThread'; -import { repositoryInvitationHandler } from './repositoryInvitation'; -import { repositoryVulnerabilityAlertHandler } from './repositoryVulnerabilityAlert'; -import { workflowRunHandler } from './workflowRun'; +import { createIssueHandler } from './issue'; +import { createPullRequestHandler } from './pullRequest'; +import { createReleaseHandler } from './release'; +import { createRepositoryDependabotAlertsThreadHandler } from './repositoryDependabotAlertsThread'; +import { createRepositoryInvitationHandler } from './repositoryInvitation'; +import { createRepositoryVulnerabilityAlertHandler } from './repositoryVulnerabilityAlert'; +import { createWorkflowRunHandler } from './workflowRun'; describe('renderer/utils/notifications/handlers/index.ts', () => { describe('createNotificationHandler', () => { const cases: Array<[SubjectType, object]> = [ - ['CheckSuite', checkSuiteHandler], - ['Commit', commitHandler], - ['Discussion', discussionHandler], - ['Issue', issueHandler], - ['PullRequest', pullRequestHandler], - ['Release', releaseHandler], + ['CheckSuite', createCheckSuiteHandler], + ['Commit', createCommitHandler], + ['Discussion', createDiscussionHandler], + ['Issue', createIssueHandler], + ['PullRequest', createPullRequestHandler], + ['Release', createReleaseHandler], [ 'RepositoryDependabotAlertsThread', - repositoryDependabotAlertsThreadHandler, + createRepositoryDependabotAlertsThreadHandler, ], - ['RepositoryInvitation', repositoryInvitationHandler], - ['RepositoryVulnerabilityAlert', repositoryVulnerabilityAlertHandler], - ['WorkflowRun', workflowRunHandler], + ['RepositoryInvitation', createRepositoryInvitationHandler], + [ + 'RepositoryVulnerabilityAlert', + createRepositoryVulnerabilityAlertHandler, + ], + ['WorkflowRun', createWorkflowRunHandler], ]; it.each(cases)( 'returns expected handler instance for %s', (type, expected) => { const notification = partialMockNotification({ type }); - const handler = createNotificationHandler(notification); - expect(handler).toBe(expected); + + createNotificationHandler(notification); + + expect(expected).toHaveBeenCalledWith(notification); }, ); @@ -44,8 +49,10 @@ describe('renderer/utils/notifications/handlers/index.ts', () => { const notification = partialMockNotification({ type: 'SomeFutureType' as SubjectType, }); - const handler = createNotificationHandler(notification); - expect(handler).toBe(defaultHandler); + + createNotificationHandler(notification); + + expect(createDefaultHandler).toHaveBeenCalledWith(notification); }); }); }); diff --git a/src/renderer/utils/notifications/handlers/index.ts b/src/renderer/utils/notifications/handlers/index.ts index b6e5d539f..babf7e1b5 100644 --- a/src/renderer/utils/notifications/handlers/index.ts +++ b/src/renderer/utils/notifications/handlers/index.ts @@ -1,56 +1,42 @@ import type { Notification } from '../../../typesGitHub'; -import { checkSuiteHandler } from './checkSuite'; -import { commitHandler } from './commit'; -import { defaultHandler } from './default'; -import { discussionHandler } from './discussion'; -import { issueHandler } from './issue'; -import { pullRequestHandler } from './pullRequest'; -import { releaseHandler } from './release'; -import { repositoryDependabotAlertsThreadHandler } from './repositoryDependabotAlertsThread'; -import { repositoryInvitationHandler } from './repositoryInvitation'; -import { repositoryVulnerabilityAlertHandler } from './repositoryVulnerabilityAlert'; +import { createCheckSuiteHandler } from './checkSuite'; +import { createCommitHandler } from './commit'; +import { createDefaultHandler } from './default'; +import { createDiscussionHandler } from './discussion'; +import { createIssueHandler } from './issue'; +import { createPullRequestHandler } from './pullRequest'; +import { createReleaseHandler } from './release'; +import { createRepositoryDependabotAlertsThreadHandler } from './repositoryDependabotAlertsThread'; +import { createRepositoryInvitationHandler } from './repositoryInvitation'; +import { createRepositoryVulnerabilityAlertHandler } from './repositoryVulnerabilityAlert'; import type { NotificationTypeHandler } from './types'; -import { workflowRunHandler } from './workflowRun'; +import { createWorkflowRunHandler } from './workflowRun'; export function createNotificationHandler( notification: Notification, ): NotificationTypeHandler { switch (notification.subject.type) { case 'CheckSuite': - return checkSuiteHandler; + return createCheckSuiteHandler(notification); case 'Commit': - return commitHandler; + return createCommitHandler(notification); case 'Discussion': - return discussionHandler; + return createDiscussionHandler(notification); case 'Issue': - return issueHandler; + return createIssueHandler(notification); case 'PullRequest': - return pullRequestHandler; + return createPullRequestHandler(notification); case 'Release': - return releaseHandler; + return createReleaseHandler(notification); case 'RepositoryDependabotAlertsThread': - return repositoryDependabotAlertsThreadHandler; + return createRepositoryDependabotAlertsThreadHandler(notification); case 'RepositoryInvitation': - return repositoryInvitationHandler; + return createRepositoryInvitationHandler(notification); case 'RepositoryVulnerabilityAlert': - return repositoryVulnerabilityAlertHandler; + return createRepositoryVulnerabilityAlertHandler(notification); case 'WorkflowRun': - return workflowRunHandler; + return createWorkflowRunHandler(notification); default: - return defaultHandler; + return createDefaultHandler(notification); } } - -export const handlers = { - checkSuiteHandler, - commitHandler, - discussionHandler, - issueHandler, - pullRequestHandler, - releaseHandler, - repositoryDependabotAlertsThreadHandler, - repositoryInvitationHandler, - repositoryVulnerabilityAlertHandler, - workflowRunHandler, - defaultHandler, -}; diff --git a/src/renderer/utils/notifications/handlers/issue.test.ts b/src/renderer/utils/notifications/handlers/issue.test.ts index 511aaeee6..643dc1736 100644 --- a/src/renderer/utils/notifications/handlers/issue.test.ts +++ b/src/renderer/utils/notifications/handlers/issue.test.ts @@ -1,15 +1,15 @@ import axios from 'axios'; import nock from 'nock'; -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification, partialMockUser, } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; import type { Link } from '../../../types'; -import type { Notification } from '../../../typesGitHub'; -import { issueHandler } from './issue'; +import type { Notification, StateType } from '../../../typesGitHub'; +import { createIssueHandler } from './issue'; describe('renderer/utils/notifications/handlers/issue.ts', () => { describe('enrich', () => { @@ -46,7 +46,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await issueHandler.enrich(mockNotification, mockSettings); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -75,7 +76,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await issueHandler.enrich(mockNotification, mockSettings); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -105,7 +107,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await issueHandler.enrich(mockNotification, mockSettings); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -135,7 +138,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await issueHandler.enrich(mockNotification, mockSettings); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -165,7 +169,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await issueHandler.enrich(mockNotification, mockSettings); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -194,7 +199,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { labels: [], }); - const result = await issueHandler.enrich(mockNotification, mockSettings); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -224,10 +230,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await issueHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -256,10 +260,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await issueHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -285,7 +287,8 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { labels: [], }); - const result = await issueHandler.enrich(mockNotification, { + const handler = createIssueHandler(mockNotification); + const result = await handler.enrich({ ...mockSettings, filterStates: ['closed'], }); @@ -294,51 +297,22 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => { }); }); - it('iconType', () => { - expect( - issueHandler.iconType(createSubjectMock({ type: 'Issue' })).displayName, - ).toBe('IssueOpenedIcon'); - - expect( - issueHandler.iconType( - createSubjectMock({ type: 'Issue', state: 'draft' }), - ).displayName, - ).toBe('IssueDraftIcon'); - - expect( - issueHandler.iconType( - createSubjectMock({ - type: 'Issue', - state: 'closed', - }), - ).displayName, - ).toBe('IssueClosedIcon'); - - expect( - issueHandler.iconType( - createSubjectMock({ - type: 'Issue', - state: 'completed', - }), - ).displayName, - ).toBe('IssueClosedIcon'); - - expect( - issueHandler.iconType( - createSubjectMock({ - type: 'Issue', - state: 'not_planned', - }), - ).displayName, - ).toBe('SkipIcon'); - - expect( - issueHandler.iconType( - createSubjectMock({ - type: 'Issue', - state: 'reopened', - }), - ).displayName, - ).toBe('IssueReopenedIcon'); + describe('iconType', () => { + const cases: Array<[StateType, string]> = [ + [null, 'IssueOpenedIcon'], + ['draft', 'IssueDraftIcon'], + ['closed', 'IssueClosedIcon'], + ['completed', 'IssueClosedIcon'], + ['not_planned', 'SkipIcon'], + ['reopened', 'IssueReopenedIcon'], + ]; + + it.each(cases)('returns expected icon for %s', (state, expectedIcon) => { + const handler = createIssueHandler( + mockNotificationWithSubject({ type: 'Issue', state }), + ); + + expect(handler.iconType().displayName).toBe(expectedIcon); + }); }); }); diff --git a/src/renderer/utils/notifications/handlers/issue.ts b/src/renderer/utils/notifications/handlers/issue.ts index 74b637aad..14ef8c1af 100644 --- a/src/renderer/utils/notifications/handlers/issue.ts +++ b/src/renderer/utils/notifications/handlers/issue.ts @@ -10,26 +10,22 @@ import { } from '@primer/octicons-react'; import type { SettingsState } from '../../../types'; -import type { - GitifySubject, - Notification, - Subject, - User, -} from '../../../typesGitHub'; +import type { GitifySubject, Notification, User } from '../../../typesGitHub'; import { getIssue, getIssueOrPullRequestComment } from '../../api/client'; import { isStateFilteredOut } from '../filters/filter'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; import { getSubjectUser } from './utils'; class IssueHandler extends DefaultHandler { readonly type = 'Issue'; - async enrich( - notification: Notification, - settings: SettingsState, - ): Promise { + async enrich(settings: SettingsState): Promise { const issue = ( - await getIssue(notification.subject.url, notification.account.token) + await getIssue( + this.notification.subject.url, + this.notification.account.token, + ) ).data; const issueState = issue.state_reason ?? issue.state; @@ -41,11 +37,11 @@ class IssueHandler extends DefaultHandler { let issueCommentUser: User; - if (notification.subject.latest_comment_url) { + if (this.notification.subject.latest_comment_url) { const issueComment = ( await getIssueOrPullRequestComment( - notification.subject.latest_comment_url, - notification.account.token, + this.notification.subject.latest_comment_url, + this.notification.account.token, ) ).data; issueCommentUser = issueComment.user; @@ -61,8 +57,8 @@ class IssueHandler extends DefaultHandler { }; } - iconType(subject: Subject): FC | null { - switch (subject.state) { + iconType(): FC | null { + switch (this.notification.subject.state) { case 'draft': return IssueDraftIcon; case 'closed': @@ -78,4 +74,8 @@ class IssueHandler extends DefaultHandler { } } -export const issueHandler = new IssueHandler(); +export function createIssueHandler( + notification: Notification, +): NotificationTypeHandler { + return new IssueHandler(notification); +} diff --git a/src/renderer/utils/notifications/handlers/pullRequest.test.ts b/src/renderer/utils/notifications/handlers/pullRequest.test.ts index c70f264bd..10d7c1620 100644 --- a/src/renderer/utils/notifications/handlers/pullRequest.test.ts +++ b/src/renderer/utils/notifications/handlers/pullRequest.test.ts @@ -1,18 +1,22 @@ import axios from 'axios'; import nock from 'nock'; -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification, partialMockUser, } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; import type { Link } from '../../../types'; -import type { Notification, PullRequest } from '../../../typesGitHub'; +import type { + Notification, + PullRequest, + StateType, +} from '../../../typesGitHub'; import { + createPullRequestHandler, getLatestReviewForReviewers, parseLinkedIssuesFromPr, - pullRequestHandler, } from './pullRequest'; describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { @@ -58,10 +62,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -98,10 +100,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -138,10 +138,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -178,10 +176,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -217,10 +213,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -255,10 +249,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -296,10 +288,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -336,10 +326,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/pulls/1/reviews') .reply(200, []); - const result = await pullRequestHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ number: 123, @@ -405,7 +393,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { labels: [], }); - const result = await pullRequestHandler.enrich(mockNotification, { + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich({ ...mockSettings, filterStates: ['closed'], }); @@ -429,7 +418,8 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { .get('/repos/gitify-app/notifications-test/issues/comments/302888448') .reply(200, { user: mockCommenter }); - const result = await pullRequestHandler.enrich(mockNotification, { + const handler = createPullRequestHandler(mockNotification); + const result = await handler.enrich({ ...mockSettings, filterUserTypes: ['Bot'], }); @@ -438,38 +428,21 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { }); }); - it('iconType', () => { - expect( - pullRequestHandler.iconType(createSubjectMock({ type: 'PullRequest' })) - .displayName, - ).toBe('GitPullRequestIcon'); - - expect( - pullRequestHandler.iconType( - createSubjectMock({ - type: 'PullRequest', - state: 'draft', - }), - ).displayName, - ).toBe('GitPullRequestDraftIcon'); - - expect( - pullRequestHandler.iconType( - createSubjectMock({ - type: 'PullRequest', - state: 'closed', - }), - ).displayName, - ).toBe('GitPullRequestClosedIcon'); - - expect( - pullRequestHandler.iconType( - createSubjectMock({ - type: 'PullRequest', - state: 'merged', - }), - ).displayName, - ).toBe('GitMergeIcon'); + describe('iconType', () => { + const cases: Array<[StateType, string]> = [ + [null, 'GitPullRequestIcon'], + ['draft', 'GitPullRequestDraftIcon'], + ['closed', 'GitPullRequestClosedIcon'], + ['merged', 'GitMergeIcon'], + ]; + + it.each(cases)('returns expected icon for %s', (state, expectedIcon) => { + const handler = createPullRequestHandler( + mockNotificationWithSubject({ type: 'PullRequest', state }), + ); + + expect(handler.iconType().displayName).toBe(expectedIcon); + }); }); describe('Pull Request Reviews - Latest Reviews By Reviewer', () => { diff --git a/src/renderer/utils/notifications/handlers/pullRequest.ts b/src/renderer/utils/notifications/handlers/pullRequest.ts index f58eccd98..72a2c2f16 100644 --- a/src/renderer/utils/notifications/handlers/pullRequest.ts +++ b/src/renderer/utils/notifications/handlers/pullRequest.ts @@ -16,7 +16,6 @@ import type { PullRequest, PullRequestReview, PullRequestStateType, - Subject, User, } from '../../../typesGitHub'; import { @@ -26,17 +25,18 @@ import { } from '../../api/client'; import { isStateFilteredOut, isUserFilteredOut } from '../filters/filter'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; import { getSubjectUser } from './utils'; class PullRequestHandler extends DefaultHandler { readonly type = 'PullRequest' as const; - async enrich( - notification: Notification, - settings: SettingsState, - ): Promise { + async enrich(settings: SettingsState): Promise { const pr = ( - await getPullRequest(notification.subject.url, notification.account.token) + await getPullRequest( + this.notification.subject.url, + this.notification.account.token, + ) ).data; let prState: PullRequestStateType = pr.state; @@ -53,13 +53,14 @@ class PullRequestHandler extends DefaultHandler { let prCommentUser: User; if ( - notification.subject.latest_comment_url && - notification.subject.latest_comment_url !== notification.subject.url + this.notification.subject.latest_comment_url && + this.notification.subject.latest_comment_url !== + this.notification.subject.url ) { const prComment = ( await getIssueOrPullRequestComment( - notification.subject.latest_comment_url, - notification.account.token, + this.notification.subject.latest_comment_url, + this.notification.account.token, ) ).data; prCommentUser = prComment.user; @@ -72,7 +73,7 @@ class PullRequestHandler extends DefaultHandler { return null; } - const reviews = await getLatestReviewForReviewers(notification); + const reviews = await getLatestReviewForReviewers(this.notification); const linkedIssues = parseLinkedIssuesFromPr(pr); return { @@ -87,8 +88,8 @@ class PullRequestHandler extends DefaultHandler { }; } - iconType(subject: Subject): FC | null { - switch (subject.state) { + iconType(): FC | null { + switch (this.notification.subject.state) { case 'draft': return GitPullRequestDraftIcon; case 'closed': @@ -101,7 +102,11 @@ class PullRequestHandler extends DefaultHandler { } } -export const pullRequestHandler = new PullRequestHandler(); +export function createPullRequestHandler( + notification: Notification, +): NotificationTypeHandler { + return new PullRequestHandler(notification); +} export async function getLatestReviewForReviewers( notification: Notification, diff --git a/src/renderer/utils/notifications/handlers/release.test.ts b/src/renderer/utils/notifications/handlers/release.test.ts index 49e6f87a4..d0da4d82a 100644 --- a/src/renderer/utils/notifications/handlers/release.test.ts +++ b/src/renderer/utils/notifications/handlers/release.test.ts @@ -1,14 +1,14 @@ import axios from 'axios'; import nock from 'nock'; -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification, partialMockUser, } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; import type { Link } from '../../../types'; -import { releaseHandler } from './release'; +import { createReleaseHandler } from './release'; describe('renderer/utils/notifications/handlers/release.ts', () => { describe('enrich', () => { @@ -33,10 +33,8 @@ describe('renderer/utils/notifications/handlers/release.ts', () => { .get('/repos/gitify-app/notifications-test/releases/1') .reply(200, { author: mockAuthor }); - const result = await releaseHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createReleaseHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: null, @@ -58,7 +56,8 @@ describe('renderer/utils/notifications/handlers/release.ts', () => { 'https://api.github.com/repos/gitify-app/notifications-test/releases/1' as Link, }); - const result = await releaseHandler.enrich(mockNotification, { + const handler = createReleaseHandler(mockNotification); + const result = await handler.enrich({ ...mockSettings, filterStates: ['closed'], }); @@ -68,12 +67,12 @@ describe('renderer/utils/notifications/handlers/release.ts', () => { }); it('iconType', () => { - expect( - releaseHandler.iconType( - createSubjectMock({ - type: 'Release', - }), - ).displayName, - ).toBe('TagIcon'); + const handler = createReleaseHandler( + mockNotificationWithSubject({ + type: 'Release', + }), + ); + + expect(handler.iconType().displayName).toBe('TagIcon'); }); }); diff --git a/src/renderer/utils/notifications/handlers/release.ts b/src/renderer/utils/notifications/handlers/release.ts index 9caadc1a7..a7651d6a5 100644 --- a/src/renderer/utils/notifications/handlers/release.ts +++ b/src/renderer/utils/notifications/handlers/release.ts @@ -8,20 +8,17 @@ import type { GitifySubject, Notification, StateType, - Subject, } from '../../../typesGitHub'; import { getRelease } from '../../api/client'; import { isStateFilteredOut } from '../filters/filter'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; import { getSubjectUser } from './utils'; class ReleaseHandler extends DefaultHandler { readonly type = 'Release'; - async enrich( - notification: Notification, - settings: SettingsState, - ): Promise { + async enrich(settings: SettingsState): Promise { const releaseState: StateType = null; // Release notifications are stateless // Return early if this notification would be hidden by filters @@ -30,7 +27,10 @@ class ReleaseHandler extends DefaultHandler { } const release = ( - await getRelease(notification.subject.url, notification.account.token) + await getRelease( + this.notification.subject.url, + this.notification.account.token, + ) ).data; return { @@ -39,9 +39,13 @@ class ReleaseHandler extends DefaultHandler { }; } - iconType(_subject: Subject): FC | null { + iconType(): FC | null { return TagIcon; } } -export const releaseHandler = new ReleaseHandler(); +export function createReleaseHandler( + notification: Notification, +): NotificationTypeHandler { + return new ReleaseHandler(notification); +} diff --git a/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.test.ts b/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.test.ts index b6fd92706..e880a4408 100644 --- a/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.test.ts +++ b/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.test.ts @@ -1,14 +1,14 @@ -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; -import { repositoryDependabotAlertsThreadHandler } from './repositoryDependabotAlertsThread'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; +import { createRepositoryDependabotAlertsThreadHandler } from './repositoryDependabotAlertsThread'; describe('renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.ts', () => { it('iconType', () => { - expect( - repositoryDependabotAlertsThreadHandler.iconType( - createSubjectMock({ - type: 'RepositoryDependabotAlertsThread', - }), - ).displayName, - ).toBe('AlertIcon'); + const handler = createRepositoryDependabotAlertsThreadHandler( + mockNotificationWithSubject({ + type: 'RepositoryDependabotAlertsThread', + }), + ); + + expect(handler.iconType().displayName).toBe('AlertIcon'); }); }); diff --git a/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.ts b/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.ts index cd06771be..3fc934140 100644 --- a/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.ts +++ b/src/renderer/utils/notifications/handlers/repositoryDependabotAlertsThread.ts @@ -3,16 +3,20 @@ import type { FC } from 'react'; import type { OcticonProps } from '@primer/octicons-react'; import { AlertIcon } from '@primer/octicons-react'; -import type { Subject } from '../../../typesGitHub'; +import type { Notification } from '../../../typesGitHub'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; class RepositoryDependabotAlertsThreadHandler extends DefaultHandler { readonly type = 'RepositoryDependabotAlertsThread'; - iconType(_subject: Subject): FC | null { + iconType(): FC | null { return AlertIcon; } } -export const repositoryDependabotAlertsThreadHandler = - new RepositoryDependabotAlertsThreadHandler(); +export function createRepositoryDependabotAlertsThreadHandler( + notification: Notification, +): NotificationTypeHandler { + return new RepositoryDependabotAlertsThreadHandler(notification); +} diff --git a/src/renderer/utils/notifications/handlers/repositoryInvitation.test.ts b/src/renderer/utils/notifications/handlers/repositoryInvitation.test.ts index 69062a277..c4e2db6d7 100644 --- a/src/renderer/utils/notifications/handlers/repositoryInvitation.test.ts +++ b/src/renderer/utils/notifications/handlers/repositoryInvitation.test.ts @@ -1,14 +1,14 @@ -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; -import { repositoryInvitationHandler } from './repositoryInvitation'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; +import { createRepositoryInvitationHandler } from './repositoryInvitation'; describe('renderer/utils/notifications/handlers/repositoryInvitation.ts', () => { it('iconType', () => { - expect( - repositoryInvitationHandler.iconType( - createSubjectMock({ - type: 'RepositoryInvitation', - }), - ).displayName, - ).toBe('MailIcon'); + const handler = createRepositoryInvitationHandler( + mockNotificationWithSubject({ + type: 'RepositoryInvitation', + }), + ); + + expect(handler.iconType().displayName).toBe('MailIcon'); }); }); diff --git a/src/renderer/utils/notifications/handlers/repositoryInvitation.ts b/src/renderer/utils/notifications/handlers/repositoryInvitation.ts index 38bf30470..2a97c79f2 100644 --- a/src/renderer/utils/notifications/handlers/repositoryInvitation.ts +++ b/src/renderer/utils/notifications/handlers/repositoryInvitation.ts @@ -2,15 +2,20 @@ import type { FC } from 'react'; import { MailIcon, type OcticonProps } from '@primer/octicons-react'; -import type { Subject } from '../../../typesGitHub'; +import type { Notification } from '../../../typesGitHub'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; class RepositoryInvitationHandler extends DefaultHandler { readonly type = 'RepositoryInvitation'; - iconType(_subject: Subject): FC | null { + iconType(): FC | null { return MailIcon; } } -export const repositoryInvitationHandler = new RepositoryInvitationHandler(); +export function createRepositoryInvitationHandler( + notification: Notification, +): NotificationTypeHandler { + return new RepositoryInvitationHandler(notification); +} diff --git a/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.test.ts b/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.test.ts index f6055ed3d..616df80da 100644 --- a/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.test.ts +++ b/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.test.ts @@ -1,14 +1,14 @@ -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; -import { repositoryVulnerabilityAlertHandler } from './repositoryVulnerabilityAlert'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; +import { createRepositoryVulnerabilityAlertHandler } from './repositoryVulnerabilityAlert'; describe('renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.ts', () => { it('iconType', () => { - expect( - repositoryVulnerabilityAlertHandler.iconType( - createSubjectMock({ - type: 'RepositoryVulnerabilityAlert', - }), - ).displayName, - ).toBe('AlertIcon'); + const handler = createRepositoryVulnerabilityAlertHandler( + mockNotificationWithSubject({ + type: 'RepositoryVulnerabilityAlert', + }), + ); + + expect(handler.iconType().displayName).toBe('AlertIcon'); }); }); diff --git a/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.ts b/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.ts index f3b8e77e7..f01760183 100644 --- a/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.ts +++ b/src/renderer/utils/notifications/handlers/repositoryVulnerabilityAlert.ts @@ -2,16 +2,20 @@ import type { FC } from 'react'; import { AlertIcon, type OcticonProps } from '@primer/octicons-react'; -import type { Subject } from '../../../typesGitHub'; +import type { Notification } from '../../../typesGitHub'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; class RepositoryVulnerabilityAlertHandler extends DefaultHandler { readonly type = 'RepositoryVulnerabilityAlert'; - iconType(_subject: Subject): FC | null { + iconType(): FC | null { return AlertIcon; } } -export const repositoryVulnerabilityAlertHandler = - new RepositoryVulnerabilityAlertHandler(); +export function createRepositoryVulnerabilityAlertHandler( + notification: Notification, +): NotificationTypeHandler { + return new RepositoryVulnerabilityAlertHandler(notification); +} diff --git a/src/renderer/utils/notifications/handlers/types.ts b/src/renderer/utils/notifications/handlers/types.ts index 686e3ef50..4e4ada71a 100644 --- a/src/renderer/utils/notifications/handlers/types.ts +++ b/src/renderer/utils/notifications/handlers/types.ts @@ -6,43 +6,40 @@ import type { SettingsState } from '../../../types'; import type { GitifySubject, Notification, - Subject, SubjectType, } from '../../../typesGitHub'; export interface NotificationTypeHandler { readonly type?: SubjectType; + readonly notification: Notification; /** * Enrich a notification. Settings may be unused for some handlers. */ - enrich( - notification: Notification, - settings: SettingsState, - ): Promise; + enrich(settings: SettingsState): Promise; /** * Return the icon component for this notification type. */ - iconType(subject: Subject): FC | null; + iconType(): FC | null; /** * Return the icon color for this notification type. */ - iconColor(subject: Subject): string | undefined; + iconColor(): string | undefined; /** * Return the formatted notification type for this notification. */ - formattedNotificationType(notification: Notification): string; + formattedNotificationType(): string; /** * Return the formatted notification number for this notification. */ - formattedNotificationNumber(notification: Notification): string; + formattedNotificationNumber(): string; /** * Return the formatted notification title for this notification. */ - formattedNotificationTitle(notification: Notification): string; + formattedNotificationTitle(): string; } diff --git a/src/renderer/utils/notifications/handlers/workflowRun.test.ts b/src/renderer/utils/notifications/handlers/workflowRun.test.ts index 5d843cf1d..7ae7da0ad 100644 --- a/src/renderer/utils/notifications/handlers/workflowRun.test.ts +++ b/src/renderer/utils/notifications/handlers/workflowRun.test.ts @@ -1,7 +1,10 @@ -import { createSubjectMock } from '../../../__mocks__/notifications-mocks'; +import { mockNotificationWithSubject } from '../../../__mocks__/notifications-mocks'; import { partialMockNotification } from '../../../__mocks__/partial-mocks'; import { mockSettings } from '../../../__mocks__/state-mocks'; -import { getWorkflowRunAttributes, workflowRunHandler } from './workflowRun'; +import { + createWorkflowRunHandler, + getWorkflowRunAttributes, +} from './workflowRun'; describe('renderer/utils/notifications/handlers/workflowRun.ts', () => { describe('enrich', () => { @@ -11,10 +14,8 @@ describe('renderer/utils/notifications/handlers/workflowRun.ts', () => { type: 'WorkflowRun', }); - const result = await workflowRunHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createWorkflowRunHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toEqual({ state: 'waiting', @@ -29,10 +30,8 @@ describe('renderer/utils/notifications/handlers/workflowRun.ts', () => { type: 'WorkflowRun', }); - const result = await workflowRunHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createWorkflowRunHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toBeNull(); }); @@ -43,23 +42,21 @@ describe('renderer/utils/notifications/handlers/workflowRun.ts', () => { type: 'WorkflowRun', }); - const result = await workflowRunHandler.enrich( - mockNotification, - mockSettings, - ); + const handler = createWorkflowRunHandler(mockNotification); + const result = await handler.enrich(mockSettings); expect(result).toBeNull(); }); }); it('iconType', () => { - expect( - workflowRunHandler.iconType( - createSubjectMock({ - type: 'WorkflowRun', - }), - ).displayName, - ).toBe('RocketIcon'); + const handler = createWorkflowRunHandler( + mockNotificationWithSubject({ + type: 'WorkflowRun', + }), + ); + + expect(handler.iconType().displayName).toBe('RocketIcon'); }); describe('getWorkflowRunAttributes', () => { diff --git a/src/renderer/utils/notifications/handlers/workflowRun.ts b/src/renderer/utils/notifications/handlers/workflowRun.ts index 9dfd7df2e..3f4929a52 100644 --- a/src/renderer/utils/notifications/handlers/workflowRun.ts +++ b/src/renderer/utils/notifications/handlers/workflowRun.ts @@ -8,19 +8,16 @@ import type { CheckSuiteStatus, GitifySubject, Notification, - Subject, WorkflowRunAttributes, } from '../../../typesGitHub'; import { DefaultHandler } from './default'; +import type { NotificationTypeHandler } from './types'; class WorkflowRunHandler extends DefaultHandler { readonly type = 'WorkflowRun'; - async enrich( - notification: Notification, - _settings: SettingsState, - ): Promise { - const state = getWorkflowRunAttributes(notification)?.status; + async enrich(_settings: SettingsState): Promise { + const state = getWorkflowRunAttributes(this.notification)?.status; if (state) { return { @@ -32,12 +29,16 @@ class WorkflowRunHandler extends DefaultHandler { return null; } - iconType(_subject: Subject): FC | null { + iconType(): FC | null { return RocketIcon; } } -export const workflowRunHandler = new WorkflowRunHandler(); +export function createWorkflowRunHandler( + notification: Notification, +): NotificationTypeHandler { + return new WorkflowRunHandler(notification); +} /** * Ideally we would be using a GitHub API to fetch the CheckSuite / WorkflowRun state, diff --git a/src/renderer/utils/notifications/notifications.test.ts b/src/renderer/utils/notifications/notifications.test.ts index 8bed45437..4b98f1b28 100644 --- a/src/renderer/utils/notifications/notifications.test.ts +++ b/src/renderer/utils/notifications/notifications.test.ts @@ -2,7 +2,7 @@ import axios from 'axios'; import nock from 'nock'; import { - createMockNotificationForRepoName, + mockNotificationWithRepoName, mockSingleAccountNotifications, } from '../../__mocks__/notifications-mocks'; import { partialMockNotification } from '../../__mocks__/partial-mocks'; @@ -83,9 +83,9 @@ describe('renderer/utils/notifications/notifications.ts', () => { const acc1: AccountNotifications = { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('a1', 'owner/repo-1'), - createMockNotificationForRepoName('a2', 'owner/repo-2'), - createMockNotificationForRepoName('a3', 'owner/repo-1'), + mockNotificationWithRepoName('a1', 'owner/repo-1'), + mockNotificationWithRepoName('a2', 'owner/repo-2'), + mockNotificationWithRepoName('a3', 'owner/repo-1'), ], error: null, }; @@ -93,9 +93,9 @@ describe('renderer/utils/notifications/notifications.ts', () => { const acc2: AccountNotifications = { account: mockGitHubEnterpriseServerAccount, notifications: [ - createMockNotificationForRepoName('b1', 'owner/repo-3'), - createMockNotificationForRepoName('b2', 'owner/repo-4'), - createMockNotificationForRepoName('b3', 'owner/repo-3'), + mockNotificationWithRepoName('b1', 'owner/repo-3'), + mockNotificationWithRepoName('b2', 'owner/repo-4'), + mockNotificationWithRepoName('b3', 'owner/repo-3'), ], error: null, }; diff --git a/src/renderer/utils/notifications/notifications.ts b/src/renderer/utils/notifications/notifications.ts index 86d7f256c..e8a498d04 100644 --- a/src/renderer/utils/notifications/notifications.ts +++ b/src/renderer/utils/notifications/notifications.ts @@ -150,7 +150,7 @@ export async function enrichNotification( try { const handler = createNotificationHandler(notification); - additionalSubjectDetails = await handler.enrich(notification, settings); + additionalSubjectDetails = await handler.enrich(settings); } catch (err) { rendererLogError( 'enrichNotification', diff --git a/src/renderer/utils/notifications/utils.test.ts b/src/renderer/utils/notifications/utils.test.ts index c16b6c3e8..44446ef1d 100644 --- a/src/renderer/utils/notifications/utils.test.ts +++ b/src/renderer/utils/notifications/utils.test.ts @@ -1,4 +1,4 @@ -import { createMockNotificationForRepoName } from '../../__mocks__/notifications-mocks'; +import { mockNotificationWithRepoName } from '../../__mocks__/notifications-mocks'; import { mockGitHubCloudAccount, mockGitHubEnterpriseServerAccount, @@ -13,9 +13,9 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('1', 'some/repo'), - createMockNotificationForRepoName('2', 'some/repo'), - createMockNotificationForRepoName('3', 'some/repo'), + mockNotificationWithRepoName('1', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), + mockNotificationWithRepoName('3', 'some/repo'), ], error: null, }, @@ -31,7 +31,7 @@ describe('renderer/utils/notifications/utils.ts', () => { const previousNotifications: AccountNotifications[] = [ { account: mockGitHubCloudAccount, - notifications: [createMockNotificationForRepoName('1', 'some/repo')], + notifications: [mockNotificationWithRepoName('1', 'some/repo')], error: null, }, ]; @@ -52,8 +52,8 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('1', 'some/repo'), - createMockNotificationForRepoName('2', 'some/repo'), + mockNotificationWithRepoName('1', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), ], error: null, }, @@ -63,9 +63,9 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('2', 'some/repo'), - createMockNotificationForRepoName('3', 'some/repo'), - createMockNotificationForRepoName('4', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), + mockNotificationWithRepoName('3', 'some/repo'), + mockNotificationWithRepoName('4', 'some/repo'), ], error: null, }, @@ -85,9 +85,9 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('1', 'some/repo'), - createMockNotificationForRepoName('2', 'some/repo'), - createMockNotificationForRepoName('3', 'some/repo'), + mockNotificationWithRepoName('1', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), + mockNotificationWithRepoName('3', 'some/repo'), ], error: null, }, @@ -97,9 +97,9 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('1', 'some/repo'), - createMockNotificationForRepoName('2', 'some/repo'), - createMockNotificationForRepoName('3', 'some/repo'), + mockNotificationWithRepoName('1', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), + mockNotificationWithRepoName('3', 'some/repo'), ], error: null, }, @@ -117,12 +117,12 @@ describe('renderer/utils/notifications/utils.ts', () => { const previousNotifications: AccountNotifications[] = [ { account: mockGitHubCloudAccount, - notifications: [createMockNotificationForRepoName('1', 'some/repo')], + notifications: [mockNotificationWithRepoName('1', 'some/repo')], error: null, }, { account: mockGitHubEnterpriseServerAccount, - notifications: [createMockNotificationForRepoName('10', 'some/repo')], + notifications: [mockNotificationWithRepoName('10', 'some/repo')], error: null, }, ]; @@ -131,16 +131,16 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('1', 'some/repo'), - createMockNotificationForRepoName('2', 'some/repo'), + mockNotificationWithRepoName('1', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), ], error: null, }, { account: mockGitHubEnterpriseServerAccount, notifications: [ - createMockNotificationForRepoName('10', 'some/repo'), - createMockNotificationForRepoName('11', 'some/repo'), + mockNotificationWithRepoName('10', 'some/repo'), + mockNotificationWithRepoName('11', 'some/repo'), ], error: null, }, @@ -159,7 +159,7 @@ describe('renderer/utils/notifications/utils.ts', () => { const previousNotifications: AccountNotifications[] = [ { account: mockGitHubCloudAccount, - notifications: [createMockNotificationForRepoName('1', 'some/repo')], + notifications: [mockNotificationWithRepoName('1', 'some/repo')], error: null, }, ]; @@ -167,14 +167,14 @@ describe('renderer/utils/notifications/utils.ts', () => { const newNotifications: AccountNotifications[] = [ { account: mockGitHubCloudAccount, - notifications: [createMockNotificationForRepoName('1', 'some/repo')], + notifications: [mockNotificationWithRepoName('1', 'some/repo')], error: null, }, { account: mockGitHubEnterpriseServerAccount, notifications: [ - createMockNotificationForRepoName('10', 'some/repo'), - createMockNotificationForRepoName('11', 'some/repo'), + mockNotificationWithRepoName('10', 'some/repo'), + mockNotificationWithRepoName('11', 'some/repo'), ], error: null, }, @@ -193,7 +193,7 @@ describe('renderer/utils/notifications/utils.ts', () => { const previousNotifications: AccountNotifications[] = [ { account: mockGitHubCloudAccount, - notifications: [createMockNotificationForRepoName('1', 'some/repo')], + notifications: [mockNotificationWithRepoName('1', 'some/repo')], error: null, }, ]; @@ -218,7 +218,7 @@ describe('renderer/utils/notifications/utils.ts', () => { const previousNotifications: AccountNotifications[] = [ { account: mockGitHubCloudAccount, - notifications: [createMockNotificationForRepoName('1', 'some/repo')], + notifications: [mockNotificationWithRepoName('1', 'some/repo')], error: null, }, ]; @@ -227,9 +227,9 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('5', 'some/repo'), - createMockNotificationForRepoName('3', 'some/repo'), - createMockNotificationForRepoName('4', 'some/repo'), + mockNotificationWithRepoName('5', 'some/repo'), + mockNotificationWithRepoName('3', 'some/repo'), + mockNotificationWithRepoName('4', 'some/repo'), ], error: null, }, @@ -248,12 +248,12 @@ describe('renderer/utils/notifications/utils.ts', () => { const previousNotifications: AccountNotifications[] = [ { account: mockGitHubCloudAccount, - notifications: [createMockNotificationForRepoName('1', 'some/repo')], + notifications: [mockNotificationWithRepoName('1', 'some/repo')], error: null, }, { account: mockGitHubEnterpriseServerAccount, - notifications: [createMockNotificationForRepoName('10', 'some/repo')], + notifications: [mockNotificationWithRepoName('10', 'some/repo')], error: null, }, ]; @@ -262,8 +262,8 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('1', 'some/repo'), - createMockNotificationForRepoName('2', 'some/repo'), + mockNotificationWithRepoName('1', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), ], error: null, }, @@ -286,16 +286,16 @@ describe('renderer/utils/notifications/utils.ts', () => { { account: mockGitHubCloudAccount, notifications: [ - createMockNotificationForRepoName('1', 'some/repo'), - createMockNotificationForRepoName('2', 'some/repo'), + mockNotificationWithRepoName('1', 'some/repo'), + mockNotificationWithRepoName('2', 'some/repo'), ], error: null, }, { account: mockGitHubEnterpriseServerAccount, notifications: [ - createMockNotificationForRepoName('10', 'some/repo'), - createMockNotificationForRepoName('11', 'some/repo'), + mockNotificationWithRepoName('10', 'some/repo'), + mockNotificationWithRepoName('11', 'some/repo'), ], error: null, },