Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions src/renderer/__mocks__/notifications-mocks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AgentIcon,
CopilotIcon,
GitCommitIcon,
GitPullRequestIcon,
IssueOpenedIcon,
TagIcon,
Expand Down Expand Up @@ -93,7 +94,7 @@ export const mockGitHubCloudGitifyNotifications: GitifyNotification[] = [
},
repository: mockGitHubRepository,
display: {
number: '123',
identifier: '123',
title: 'I am a robot and this is a test! [#123]',
type: 'Open Issue',
icon: {
Expand Down Expand Up @@ -124,7 +125,7 @@ export const mockGitHubCloudGitifyNotifications: GitifyNotification[] = [
},
repository: mockGitHubRepository,
display: {
number: '456',
identifier: '456',
title: 'Improve the UI [#456]',
type: 'Issue',
icon: {
Expand Down Expand Up @@ -175,10 +176,11 @@ export const mockGithubEnterpriseGitifyNotifications: GitifyNotification[] = [
'https://github.gitify.io/api/v3/repos/myorg/notifications-test/releases/3' as Link,
type: 'Release',
reviewers: undefined,
tagName: '0.0.1',
},
repository: mockEnterpriseRepository,
display: {
number: '',
identifier: '0.0.1',
title: 'Release 0.0.1',
type: 'Release',
icon: {
Expand Down Expand Up @@ -209,7 +211,7 @@ export const mockGithubEnterpriseGitifyNotifications: GitifyNotification[] = [
},
repository: mockEnterpriseRepository,
display: {
number: '123',
identifier: '123',
title: 'Bump Version [#123]',
type: 'Pull Request',
icon: {
Expand All @@ -223,6 +225,44 @@ export const mockGithubEnterpriseGitifyNotifications: GitifyNotification[] = [

export const mockGitifyNotification: GitifyNotification = mockGitHubCloudGitifyNotifications[0];

/**
* Mock Gitify Notification for a GitHub commit.
*
* Subject type `Commit`, which identifies by its SHA rather than a number.
*/
export const mockCommitGitifyNotification: GitifyNotification = {
account: mockGitHubCloudAccount,
order: 0,
id: '1349837581',
unread: true,
reason: {
code: 'subscribed',
title: 'Updated',
description: "You're watching the repository.",
},
updatedAt: '2024-03-12T10:00:00Z',
subject: {
title: 'Fix the thing',
url: 'https://api.github.com/repos/gitify-app/notifications-test/commits/d2a86d80e3d24ea9510d5de6c147e53c30f313a8' as Link,
latestCommentUrl: null,
type: 'Commit',
commitSha: 'd2a86d80e3d24ea9510d5de6c147e53c30f313a8',
user: mockSubjectUser,
author: mockSubjectUser,
},
repository: mockGitHubRepository,
display: {
identifier: 'd2a86d8',
title: 'Fix the thing',
type: 'Commit',
icon: {
type: GitCommitIcon,
color: IconColor.GRAY,
},
defaultUserType: 'User',
},
};

/**
* Mock Gitify Notification for a GitHub Copilot cloud agent session.
*
Expand All @@ -248,7 +288,7 @@ export const mockAgentSessionGitifyNotification: GitifyNotification = {
},
repository: mockGitHubRepository,
display: {
number: '',
identifier: '',
title: 'Analyzing and fixing GitHub Actions job failure',
type: 'Agent Session Thread',
icon: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const NotificationHeader: FC<NotificationHeaderProps> = ({
/>
</button>
<div className={cn('text-xxs', Opacity.READ, !showNumber && 'hidden')}>
{notification.display.number}
{notification.display.identifier}
</div>
</Stack>
</div>
Expand Down
27 changes: 27 additions & 0 deletions src/renderer/components/notifications/NotificationRow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useState } from 'react';
import { renderWithProviders } from '../../__helpers__/test-utils';
import { mockGitHubEnterpriseServerAccount } from '../../__mocks__/account-mocks';
import {
mockCommitGitifyNotification,
mockGiteaGitifyNotification,
mockGitifyNotification,
} from '../../__mocks__/notifications-mocks';
Expand Down Expand Up @@ -81,6 +82,32 @@ describe('renderer/components/notifications/NotificationRow.tsx', () => {
expect(tree.container).toMatchSnapshot();
});

it('shows the release tag as the identifier', () => {
const props: NotificationRowProps = {
notification: {
...mockGitifyNotification,
subject: { ...mockGitifyNotification.subject, type: 'Release', tagName: '0.0.1' },
display: { ...mockGitifyNotification.display, identifier: '0.0.1' },
},
isRepositoryAnimatingExit: false,
};

const tree = renderWithProviders(<NotificationRow {...props} />);

expect(tree.getByText('0.0.1')).toBeInTheDocument();
});

it('shows the commit short SHA as the identifier', () => {
const props: NotificationRowProps = {
notification: mockCommitGitifyNotification,
isRepositoryAnimatingExit: false,
};

const tree = renderWithProviders(<NotificationRow {...props} />);

expect(tree.getByText('d2a86d8')).toBeInTheDocument();
});

it('should render itself & its children - notification is read', async () => {
const props: NotificationRowProps = {
notification: { ...mockGitifyNotification, unread: false },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export const NotificationRow: FC<NotificationRowProps> = ({
(isGroupByDate() || !showNumber) && 'hidden',
)}
>
{notification.display.number}
{notification.display.identifier}
</Text>
</Stack>

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 24 additions & 8 deletions src/renderer/components/settings/NotificationSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
CheckIcon,
CommentIcon,
DashIcon,
GitCommitIcon,
GitPullRequestIcon,
IssueOpenedIcon,
MilestoneIcon,
Expand Down Expand Up @@ -275,27 +276,42 @@ export const NotificationSettings: FC = () => {

<Checkbox
checked={showNumber}
label="Show GitHub number"
label="Show identifier"
name="showNumber"
onChange={() => toggleSetting('showNumber')}
tooltip={
<Stack direction="vertical" gap="condensed">
<Text>Show GitHub number for:</Text>
<Text>Show identifier for:</Text>
<div className="pl-2">
<Stack direction="vertical" gap="none">
<Stack direction="horizontal" gap="condensed">
<Stack align="center" direction="horizontal" gap="condensed">
<CommentIcon size={Size.SMALL} />
Discussion
<Text>Discussion</Text>
<Text className="text-gitify-icon-muted">#123</Text>
</Stack>

<Stack direction="horizontal" gap="condensed">
<Stack align="center" direction="horizontal" gap="condensed">
<IssueOpenedIcon size={Size.SMALL} />
Issue
<Text>Issue</Text>
<Text className="text-gitify-icon-muted">#123</Text>
</Stack>

<Stack direction="horizontal" gap="condensed">
<Stack align="center" direction="horizontal" gap="condensed">
<GitPullRequestIcon size={Size.SMALL} />
Pull Request
<Text>Pull Request</Text>
<Text className="text-gitify-icon-muted">#123</Text>
</Stack>

<Stack align="center" direction="horizontal" gap="condensed">
<GitCommitIcon size={Size.SMALL} />
<Text>Commit</Text>
<Text className="text-gitify-icon-muted">a1b2c3d</Text>
</Stack>

<Stack align="center" direction="horizontal" gap="condensed">
<TagIcon size={Size.SMALL} />
<Text>Release</Text>
<Text className="text-gitify-icon-muted">v1.2.3</Text>
</Stack>
</Stack>
</div>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/renderer/routes/__snapshots__/Settings.test.tsx.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions src/renderer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,10 @@ export interface GitifySubject {
// Enriched fields (from additional GraphQL or REST API calls)
/** Issue/PR/Discussion number */
number?: number;
/** Release tag (e.g. `v1.2.3`), when the subject is a release */
tagName?: string;
/** Commit SHA, when the subject is a commit */
commitSha?: string;
/** Parsed state */
state?: GitifyNotificationState;
/**
Expand Down Expand Up @@ -474,8 +478,8 @@ export interface GitifyNotificationDisplay {
title: string;
/** Formatted notification type */
type: string;
/** Formatted notification number */
number: string;
/** Formatted notification identifier (a `#number`, a release tag, or a short SHA) */
identifier: string;
/** Notification icon and color to display */
icon: {
type: Icon;
Expand Down
19 changes: 19 additions & 0 deletions src/renderer/utils/forges/github/handlers/commit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ describe('renderer/utils/notifications/handlers/commit.ts', () => {
});
});

it('attaches the commit SHA as its identifier', async () => {
const mockNotification = mockPartialGitifyNotification({
title: 'This is a commit',
type: 'Commit',
url: 'https://api.github.com/repos/gitify-app/notifications-test/commits/d2a86d80e3d24ea9510d5de6c147e53c30f313a8' as Link,
latestCommentUrl: null,
});

getCommitSpy.mockResolvedValue({
author: mockAuthor,
sha: 'd2a86d80e3d24ea9510d5de6c147e53c30f313a8',
} as GetCommitResponse);

const result = await commitHandler.enrich(mockNotification);

expect(result.commitSha).toBe('d2a86d80e3d24ea9510d5de6c147e53c30f313a8');
});

it('leaves roles undefined when the commit has no linked GitHub user', async () => {
const mockNotification = mockPartialGitifyNotification({
title: 'This is a commit with comments',
Expand All @@ -107,6 +125,7 @@ describe('renderer/utils/notifications/handlers/commit.ts', () => {
expect(result.user).toBeUndefined();
expect(result.author).toBeUndefined();
expect(result.commenter).toBeUndefined();
expect(result.commitSha).toBeUndefined();
});

it('return early if commit state filtered', async () => {
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/utils/forges/github/handlers/commit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,21 @@ class CommitHandler extends DefaultHandler {
// in parallel so populating both roles costs no extra latency.
let author: GitifyNotificationUser | undefined;
let commenter: GitifyNotificationUser | undefined;
let commitSha: string | undefined;

if (notification.subject.latestCommentUrl) {
const [commit, commitComment] = await Promise.all([
getCommit(notification.account, notification.subject.url!),
getCommitComment(notification.account, notification.subject.latestCommentUrl),
]);

commitSha = commit.sha;
author = toNotificationUser(commit.author);
commenter = toNotificationUser(commitComment.user);
} else {
const commit = await getCommit(notification.account, notification.subject.url!);

commitSha = commit.sha;
author = toNotificationUser(commit.author);
}

Expand All @@ -65,6 +68,7 @@ class CommitHandler extends DefaultHandler {
user: commenter ?? author,
author: author,
commenter: commenter,
commitSha,
};
}

Expand Down
12 changes: 12 additions & 0 deletions src/renderer/utils/forges/github/handlers/release.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('renderer/utils/notifications/handlers/release.ts', () => {
it('release notification', async () => {
getReleaseSpy.mockResolvedValue({
author: mockAuthor,
tag_name: 'v0.0.1',
} as GetReleaseResponse);

const result = await releaseHandler.enrich(mockNotification);
Expand All @@ -44,9 +45,20 @@ describe('renderer/utils/notifications/handlers/release.ts', () => {
avatarUrl: mockAuthor.avatar_url,
type: mockAuthor.type,
},
tagName: 'v0.0.1',
});
});

it('release without a tag', async () => {
getReleaseSpy.mockResolvedValue({
author: mockAuthor,
} as GetReleaseResponse);

const result = await releaseHandler.enrich(mockNotification);

expect(result.tagName).toBeUndefined();
});

it('return early if release state filtered', async () => {
useFiltersStore.setState({ states: ['closed'] });

Expand Down
Loading
Loading