Skip to content

Commit 5e05265

Browse files
authored
refactor(handlers): move icon color into each handler (#2469)
Signed-off-by: Adam Setch <adam.setch@outlook.com>
1 parent 2818607 commit 5e05265

File tree

10 files changed

+208
-45
lines changed

10 files changed

+208
-45
lines changed

src/renderer/utils/notifications/handlers/checkSuite.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
createPartialMockNotification,
44
} from '../../../__mocks__/notifications-mocks';
55
import { mockSettings } from '../../../__mocks__/state-mocks';
6+
import { IconColor } from '../../../types';
67
import { checkSuiteHandler, getCheckSuiteAttributes } from './checkSuite';
78

89
describe('renderer/utils/notifications/handlers/checkSuite.ts', () => {
@@ -182,6 +183,38 @@ describe('renderer/utils/notifications/handlers/checkSuite.ts', () => {
182183
).toBe('CheckIcon');
183184
});
184185

186+
it('iconColor', () => {
187+
expect(
188+
checkSuiteHandler.iconColor(
189+
createMockSubject({ type: 'CheckSuite', state: 'success' }),
190+
),
191+
).toBe(IconColor.GREEN);
192+
193+
expect(
194+
checkSuiteHandler.iconColor(
195+
createMockSubject({ type: 'CheckSuite', state: 'failure' }),
196+
),
197+
).toBe(IconColor.RED);
198+
199+
expect(
200+
checkSuiteHandler.iconColor(
201+
createMockSubject({ type: 'CheckSuite', state: 'cancelled' }),
202+
),
203+
).toBe(IconColor.GRAY);
204+
205+
expect(
206+
checkSuiteHandler.iconColor(
207+
createMockSubject({ type: 'CheckSuite', state: 'skipped' }),
208+
),
209+
).toBe(IconColor.GRAY);
210+
211+
expect(
212+
checkSuiteHandler.iconColor(
213+
createMockSubject({ type: 'CheckSuite', state: null }),
214+
),
215+
).toBe(IconColor.GRAY);
216+
});
217+
185218
describe('getCheckSuiteState', () => {
186219
it('cancelled check suite state', async () => {
187220
const mockNotification = createPartialMockNotification({

src/renderer/utils/notifications/handlers/checkSuite.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import {
1010
} from '@primer/octicons-react';
1111

1212
import type { SettingsState } from '../../../types';
13+
import { IconColor } from '../../../types';
1314
import type {
1415
CheckSuiteAttributes,
1516
CheckSuiteStatus,
1617
GitifySubject,
1718
Notification,
1819
Subject,
1920
} from '../../../typesGitHub';
20-
import { DefaultHandler } from './default';
21+
import { DefaultHandler, defaultHandler } from './default';
2122

2223
class CheckSuiteHandler extends DefaultHandler {
2324
readonly type = 'CheckSuite';
@@ -52,6 +53,17 @@ class CheckSuiteHandler extends DefaultHandler {
5253
return RocketIcon;
5354
}
5455
}
56+
57+
iconColor(subject: Subject): IconColor {
58+
switch (subject.state) {
59+
case 'success':
60+
return IconColor.GREEN;
61+
case 'failure':
62+
return IconColor.RED;
63+
default:
64+
return defaultHandler.iconColor(subject);
65+
}
66+
}
5567
}
5668

5769
export const checkSuiteHandler = new CheckSuiteHandler();

src/renderer/utils/notifications/handlers/default.test.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,17 @@ describe('renderer/utils/notifications/handlers/default.ts', () => {
3232
});
3333

3434
describe('iconColor', () => {
35-
const cases: Array<[StateType | null, IconColor]> = [
36-
['open' as StateType, IconColor.GREEN],
37-
['reopened' as StateType, IconColor.GREEN],
38-
['ANSWERED' as StateType, IconColor.GREEN],
39-
['success' as StateType, IconColor.GREEN],
40-
['closed' as StateType, IconColor.RED],
41-
['failure' as StateType, IconColor.RED],
42-
['completed' as StateType, IconColor.PURPLE],
43-
['RESOLVED' as StateType, IconColor.PURPLE],
44-
['merged' as StateType, IconColor.PURPLE],
45-
['not_planned' as StateType, IconColor.GRAY],
46-
['draft' as StateType, IconColor.GRAY],
47-
['skipped' as StateType, IconColor.GRAY],
48-
['cancelled' as StateType, IconColor.GRAY],
49-
['unknown' as StateType, IconColor.GRAY],
50-
[null, IconColor.GRAY],
51-
[undefined, IconColor.GRAY],
52-
];
35+
it('returns GRAY for any state (fallback behavior)', () => {
36+
const states: Array<StateType | null | undefined> = [
37+
'unknown' as StateType,
38+
null,
39+
undefined,
40+
];
5341

54-
it.each(cases)('returns correct color for state %s', (state, expected) => {
55-
const subject = createMockSubject({ state });
56-
expect(defaultHandler.iconColor(subject)).toBe(expected);
42+
states.forEach((state) => {
43+
const subject = createMockSubject({ state });
44+
expect(defaultHandler.iconColor(subject)).toBe(IconColor.GRAY);
45+
});
5746
});
5847
});
5948

src/renderer/utils/notifications/handlers/default.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,8 @@ export class DefaultHandler implements NotificationTypeHandler {
2828
return QuestionIcon;
2929
}
3030

31-
iconColor(subject: Subject): IconColor {
32-
switch (subject.state) {
33-
case 'open':
34-
case 'reopened':
35-
case 'ANSWERED':
36-
case 'success':
37-
return IconColor.GREEN;
38-
case 'closed':
39-
case 'failure':
40-
return IconColor.RED;
41-
case 'completed':
42-
case 'RESOLVED':
43-
case 'merged':
44-
return IconColor.PURPLE;
45-
default:
46-
return IconColor.GRAY;
47-
}
31+
iconColor(_subject: Subject): IconColor {
32+
return IconColor.GRAY;
4833
}
4934

5035
formattedNotificationType(notification: Notification): string {

src/renderer/utils/notifications/handlers/discussion.test.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
createPartialMockNotification,
77
} from '../../../__mocks__/notifications-mocks';
88
import { mockSettings } from '../../../__mocks__/state-mocks';
9-
import type { Link } from '../../../types';
9+
import { IconColor, type Link } from '../../../types';
1010
import type { Owner, Repository } from '../../../typesGitHub';
1111
import {
1212
type AuthorFieldsFragment,
@@ -325,6 +325,38 @@ describe('renderer/utils/notifications/handlers/discussion.ts', () => {
325325
).displayName,
326326
).toBe('DiscussionClosedIcon');
327327
});
328+
329+
it('iconColor', () => {
330+
expect(
331+
discussionHandler.iconColor(
332+
createMockSubject({ type: 'Discussion', state: 'ANSWERED' }),
333+
),
334+
).toBe(IconColor.GREEN);
335+
336+
expect(
337+
discussionHandler.iconColor(
338+
createMockSubject({ type: 'Discussion', state: 'RESOLVED' }),
339+
),
340+
).toBe(IconColor.PURPLE);
341+
342+
expect(
343+
discussionHandler.iconColor(
344+
createMockSubject({ type: 'Discussion', state: 'DUPLICATE' }),
345+
),
346+
).toBe(IconColor.GRAY);
347+
348+
expect(
349+
discussionHandler.iconColor(
350+
createMockSubject({ type: 'Discussion', state: 'OUTDATED' }),
351+
),
352+
).toBe(IconColor.GRAY);
353+
354+
expect(
355+
discussionHandler.iconColor(
356+
createMockSubject({ type: 'Discussion', state: 'OPEN' }),
357+
),
358+
).toBe(IconColor.GRAY);
359+
});
328360
});
329361

330362
function mockDiscussionNode(

src/renderer/utils/notifications/handlers/discussion.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
import { differenceInMilliseconds } from 'date-fns';
1212

1313
import type { SettingsState } from '../../../types';
14+
import { IconColor } from '../../../types';
1415
import type {
1516
DiscussionStateType,
1617
GitifySubject,
@@ -24,7 +25,7 @@ import type {
2425
FetchDiscussionByNumberQuery,
2526
} from '../../api/graphql/generated/graphql';
2627
import { isStateFilteredOut } from '../filters/filter';
27-
import { DefaultHandler } from './default';
28+
import { DefaultHandler, defaultHandler } from './default';
2829

2930
type DiscussionComment = NonNullable<
3031
NonNullable<
@@ -110,6 +111,17 @@ class DiscussionHandler extends DefaultHandler {
110111
return CommentDiscussionIcon;
111112
}
112113
}
114+
115+
iconColor(subject: Subject): IconColor {
116+
switch (subject.state) {
117+
case 'ANSWERED':
118+
return IconColor.GREEN;
119+
case 'RESOLVED':
120+
return IconColor.PURPLE;
121+
default:
122+
return defaultHandler.iconColor(subject);
123+
}
124+
}
113125
}
114126

115127
export const discussionHandler = new DiscussionHandler();

src/renderer/utils/notifications/handlers/issue.test.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '../../../__mocks__/notifications-mocks';
88
import { mockSettings } from '../../../__mocks__/state-mocks';
99
import { createPartialMockUser } from '../../../__mocks__/user-mocks';
10-
import type { Link } from '../../../types';
10+
import { IconColor, type Link } from '../../../types';
1111
import type { Notification } from '../../../typesGitHub';
1212
import { issueHandler } from './issue';
1313

@@ -341,4 +341,42 @@ describe('renderer/utils/notifications/handlers/issue.ts', () => {
341341
).displayName,
342342
).toBe('IssueReopenedIcon');
343343
});
344+
345+
it('iconColor', () => {
346+
expect(
347+
issueHandler.iconColor(
348+
createMockSubject({ type: 'Issue', state: 'open' }),
349+
),
350+
).toBe(IconColor.GREEN);
351+
352+
expect(
353+
issueHandler.iconColor(
354+
createMockSubject({ type: 'Issue', state: 'reopened' }),
355+
),
356+
).toBe(IconColor.GREEN);
357+
358+
expect(
359+
issueHandler.iconColor(
360+
createMockSubject({ type: 'Issue', state: 'closed' }),
361+
),
362+
).toBe(IconColor.RED);
363+
364+
expect(
365+
issueHandler.iconColor(
366+
createMockSubject({ type: 'Issue', state: 'completed' }),
367+
),
368+
).toBe(IconColor.PURPLE);
369+
370+
expect(
371+
issueHandler.iconColor(
372+
createMockSubject({ type: 'Issue', state: 'draft' }),
373+
),
374+
).toBe(IconColor.GRAY);
375+
376+
expect(
377+
issueHandler.iconColor(
378+
createMockSubject({ type: 'Issue', state: 'not_planned' }),
379+
),
380+
).toBe(IconColor.GRAY);
381+
});
344382
});

src/renderer/utils/notifications/handlers/issue.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from '@primer/octicons-react';
1111

1212
import type { SettingsState } from '../../../types';
13+
import { IconColor } from '../../../types';
1314
import type {
1415
GitifySubject,
1516
Notification,
@@ -18,7 +19,7 @@ import type {
1819
} from '../../../typesGitHub';
1920
import { getIssue, getIssueOrPullRequestComment } from '../../api/client';
2021
import { isStateFilteredOut } from '../filters/filter';
21-
import { DefaultHandler } from './default';
22+
import { DefaultHandler, defaultHandler } from './default';
2223
import { getSubjectUser } from './utils';
2324

2425
class IssueHandler extends DefaultHandler {
@@ -76,6 +77,20 @@ class IssueHandler extends DefaultHandler {
7677
return IssueOpenedIcon;
7778
}
7879
}
80+
81+
iconColor(subject: Subject): IconColor {
82+
switch (subject.state) {
83+
case 'open':
84+
case 'reopened':
85+
return IconColor.GREEN;
86+
case 'closed':
87+
return IconColor.RED;
88+
case 'completed':
89+
return IconColor.PURPLE;
90+
default:
91+
return defaultHandler.iconColor(subject);
92+
}
93+
}
7994
}
8095

8196
export const issueHandler = new IssueHandler();

src/renderer/utils/notifications/handlers/pullRequest.test.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '../../../__mocks__/notifications-mocks';
88
import { mockSettings } from '../../../__mocks__/state-mocks';
99
import { createPartialMockUser } from '../../../__mocks__/user-mocks';
10-
import type { Link } from '../../../types';
10+
import { IconColor, type Link } from '../../../types';
1111
import type { Notification, PullRequest } from '../../../typesGitHub';
1212
import {
1313
getLatestReviewForReviewers,
@@ -472,6 +472,38 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => {
472472
).toBe('GitMergeIcon');
473473
});
474474

475+
it('iconColor', () => {
476+
expect(
477+
pullRequestHandler.iconColor(
478+
createMockSubject({ type: 'PullRequest', state: 'open' }),
479+
),
480+
).toBe(IconColor.GREEN);
481+
482+
expect(
483+
pullRequestHandler.iconColor(
484+
createMockSubject({ type: 'PullRequest', state: 'reopened' }),
485+
),
486+
).toBe(IconColor.GREEN);
487+
488+
expect(
489+
pullRequestHandler.iconColor(
490+
createMockSubject({ type: 'PullRequest', state: 'closed' }),
491+
),
492+
).toBe(IconColor.RED);
493+
494+
expect(
495+
pullRequestHandler.iconColor(
496+
createMockSubject({ type: 'PullRequest', state: 'merged' }),
497+
),
498+
).toBe(IconColor.PURPLE);
499+
500+
expect(
501+
pullRequestHandler.iconColor(
502+
createMockSubject({ type: 'PullRequest', state: 'draft' }),
503+
),
504+
).toBe(IconColor.GRAY);
505+
});
506+
475507
describe('Pull Request Reviews - Latest Reviews By Reviewer', () => {
476508
it('returns latest review state per reviewer', async () => {
477509
nock('https://api.github.com')

0 commit comments

Comments
 (0)