Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
266 changes: 212 additions & 54 deletions src/utils/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,62 +230,220 @@ describe('utils/helpers.ts', () => {
expect(result).toBe(`${mockedHtmlUrl}?${mockedNotificationReferrer}`);
});

it('Discussions: when no subject urls and no discussions found via query, default to linking to repository discussions', async () => {
const subject = {
title: 'generate github web url unit tests',
url: null,
latest_comment_url: null,
type: 'Discussion' as SubjectType,
};

const requestPromise = new Promise((resolve) =>
resolve({
data: {},
} as AxiosResponse),
) as AxiosPromise;

apiRequestAuthMock.mockResolvedValue(requestPromise);

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(1);
expect(result).toBe(
`${mockedSingleNotification.repository.html_url}/discussions?${mockedNotificationReferrer}`,
);
describe('Check Suite URLs', () => {
it('successful workflow', async () => {
const subject = {
title: 'Demo workflow run succeeded for main branch',
url: null,
latest_comment_url: null,
type: 'CheckSuite' as SubjectType,
};

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
expect(result).toBe(
`https://github.com/manosim/notifications-test/actions?query=workflow%3A%22Demo%22+is%3Asuccess+branch%3Amain&${mockedNotificationReferrer}`,
);
});

it('failed workflow', async () => {
const subject = {
title: 'Demo workflow run failed for main branch',
url: null,
latest_comment_url: null,
type: 'CheckSuite' as SubjectType,
};

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
expect(result).toBe(
`https://github.com/manosim/notifications-test/actions?query=workflow%3A%22Demo%22+is%3Afailure+branch%3Amain&${mockedNotificationReferrer}`,
);
});

it('failed workflow multiple attempts', async () => {
const subject = {
title: 'Demo workflow run, Attempt #3 failed for main branch',
url: null,
latest_comment_url: null,
type: 'CheckSuite' as SubjectType,
};

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
expect(result).toBe(
`https://github.com/manosim/notifications-test/actions?query=workflow%3A%22Demo%22+is%3Afailure+branch%3Amain&${mockedNotificationReferrer}`,
);
});

it('skipped workflow', async () => {
const subject = {
title: 'Demo workflow run skipped for main branch',
url: null,
latest_comment_url: null,
type: 'CheckSuite' as SubjectType,
};

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
expect(result).toBe(
`https://github.com/manosim/notifications-test/actions?query=workflow%3A%22Demo%22+is%3Askipped+branch%3Amain&${mockedNotificationReferrer}`,
);
});

it('unhandled workflow scenario', async () => {
const subject = {
title: 'unhandled workflow scenario',
url: null,
latest_comment_url: null,
type: 'CheckSuite' as SubjectType,
};

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
expect(result).toBe(
`https://github.com/manosim/notifications-test/actions?${mockedNotificationReferrer}`,
);
});

it('unhandled status scenario', async () => {
const subject = {
title: 'Demo workflow run unhandled-status for main branch',
url: null,
latest_comment_url: null,
type: 'CheckSuite' as SubjectType,
};

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
expect(result).toBe(
`https://github.com/manosim/notifications-test/actions?query=workflow%3A%22Demo%22+branch%3Amain&${mockedNotificationReferrer}`,
);
});

it('unhandled check suite scenario', async () => {
const subject = {
title: 'Unhandled scenario',
url: null,
latest_comment_url: null,
type: 'CheckSuite' as SubjectType,
};

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
expect(result).toBe(
`https://github.com/manosim/notifications-test/actions?${mockedNotificationReferrer}`,
);
});
});

it('Discussions: when no subject urls and no discussions found via query, default to linking to repository discussions', async () => {
const subject = {
title: '1.16.0',
url: null,
latest_comment_url: null,
type: 'Discussion' as SubjectType,
};

const requestPromise = new Promise((resolve) =>
resolve(mockedGraphQLResponse as AxiosResponse),
) as AxiosPromise;

apiRequestAuthMock.mockResolvedValue(requestPromise);

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(1);
expect(result).toBe(
`https://github.com/manosim/notifications-test/discussions/612?${mockedNotificationReferrer}#discussioncomment-2300902`,
);
describe('Discussions URLs', () => {
it('when no subject urls and no discussions found via query, default to linking to repository discussions', async () => {
const subject = {
title: 'generate github web url unit tests',
url: null,
latest_comment_url: null,
type: 'Discussion' as SubjectType,
};

const requestPromise = new Promise((resolve) =>
resolve({
data: {},
} as AxiosResponse),
) as AxiosPromise;

apiRequestAuthMock.mockResolvedValue(requestPromise);

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(1);
expect(result).toBe(
`${mockedSingleNotification.repository.html_url}/discussions?${mockedNotificationReferrer}`,
);
});

it('when no subject urls and no discussions found via query, default to linking to repository discussions', async () => {
const subject = {
title: '1.16.0',
url: null,
latest_comment_url: null,
type: 'Discussion' as SubjectType,
};

const requestPromise = new Promise((resolve) =>
resolve(mockedGraphQLResponse as AxiosResponse),
) as AxiosPromise;

apiRequestAuthMock.mockResolvedValue(requestPromise);

const result = await generateGitHubWebUrl(
{
...mockedSingleNotification,
subject: subject,
},
mockAccounts,
);

expect(apiRequestAuthMock).toHaveBeenCalledTimes(1);
expect(result).toBe(
`https://github.com/manosim/notifications-test/discussions/612?${mockedNotificationReferrer}#discussioncomment-2300902`,
);
});
});

it('Repository Invitation url', async () => {
Expand Down
31 changes: 31 additions & 0 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { apiRequestAuth } from '../utils/api-requests';
import { openExternalLink } from '../utils/comms';
import { Constants } from './constants';
import { getCheckSuiteAttributes } from './state';

export function getEnterpriseAccountToken(
hostname: string,
Expand Down Expand Up @@ -70,6 +71,33 @@ export async function getHtmlUrl(url: string, token: string): Promise<string> {
return response.data.html_url;
}

export function getCheckSuiteUrl(notification: Notification) {
let url = `${notification.repository.html_url}/actions`;
let filters = [];

const checkSuiteAttributes = getCheckSuiteAttributes(notification);

if (checkSuiteAttributes?.workflowName) {
filters.push(
`workflow:"${checkSuiteAttributes.workflowName.replaceAll(' ', '+')}"`,
);
}

if (checkSuiteAttributes?.status) {
filters.push(`is:${checkSuiteAttributes.status}`);
}

if (checkSuiteAttributes?.branchName) {
filters.push(`branch:${checkSuiteAttributes.branchName}`);
}

if (filters.length > 0) {
url += `?query=${filters.join('+')}`;
}

return url;
}

async function getDiscussionUrl(
notification: Notification,
token: string,
Expand Down Expand Up @@ -161,6 +189,9 @@ export async function generateGitHubWebUrl(
} else {
// Perform any specific notification type handling (only required for a few special notification scenarios)
switch (notification.subject.type) {
case 'CheckSuite':
url = getCheckSuiteUrl(notification);
break;
case 'Discussion':
url = await getDiscussionUrl(notification, accounts.token);
break;
Expand Down