Repository: gitify-app/gitify (ts)
Issue: Invitation notifications link to no where
I have received a notification of an invite.  It shows up in Gitify, but clicking it does nothing.  The notification list in GitHub's web interface does link to the proper place.  Here is the notification url that should have been used:

https://github.com/layershifter/babel-plugin-transform-react-handled-props/invitations
Pull request description: feat: support repository invitation links
Closes #242

Patch:
diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts
index a90e4b21..48cd1347 100644
--- a/src/utils/helpers.ts
+++ b/src/utils/helpers.ts
@@ -63,7 +63,7 @@ export function formatSearchQueryString(
   return `${title} in:title repo:${repo} updated:>${addHours(lastUpdated, -2)}`;
 }
 
-export async function getHtmlUrl(url: string, token: string) {
+export async function getHtmlUrl(url: string, token: string): Promise<string> {
   const response = await apiRequestAuth(url, 'GET', token);
 
   return response.data.html_url;
@@ -152,7 +152,7 @@ export async function generateGitHubWebUrl(
   notification: Notification,
   accounts: AuthState,
 ): Promise<string> {
-  let url;
+  let url: string;
 
   if (notification.subject.latest_comment_url) {
     url = await getHtmlUrl(
@@ -167,6 +167,9 @@ export async function generateGitHubWebUrl(
       case 'Discussion':
         url = await getDiscussionUrl(notification, accounts.token);
         break;
+      case 'RepositoryInvitation':
+        url = `${notification.repository.html_url}/invitations`;
+        break;
       default:
         url = notification.repository.html_url;
         break;


Test patch:
diff --git a/src/utils/helpers.test.ts b/src/utils/helpers.test.ts
index bb0e6645..8cef1c3c 100644
--- a/src/utils/helpers.test.ts
+++ b/src/utils/helpers.test.ts
@@ -152,7 +152,7 @@ describe('utils/helpers.ts', () => {
   describe('generateGitHubWebUrl', () => {
     const mockedHtmlUrl = 'https://github.com/gitify-app/gitify/issues/785';
     const mockedNotificationReferrer =
-      '?notification_referrer_id=MDE4Ok5vdGlmaWNhdGlvblRocmVhZDEzODY2MTA5NjoxMjM0NTY3ODk%3D';
+      'notification_referrer_id=MDE4Ok5vdGlmaWNhdGlvblRocmVhZDEzODY2MTA5NjoxMjM0NTY3ODk%3D';
     const apiRequestAuthMock = jest.spyOn(apiRequests, 'apiRequestAuth');
 
     afterEach(() => {
@@ -192,7 +192,7 @@ describe('utils/helpers.ts', () => {
         'GET',
         mockAccounts.token,
       );
-      expect(result).toBe(`${mockedHtmlUrl}${mockedNotificationReferrer}`);
+      expect(result).toBe(`${mockedHtmlUrl}?${mockedNotificationReferrer}`);
     });
 
     it('Subject Url: when no latest comment url available, fetch subject html url', async () => {
@@ -227,7 +227,7 @@ describe('utils/helpers.ts', () => {
         'GET',
         mockAccounts.token,
       );
-      expect(result).toBe(`${mockedHtmlUrl}${mockedNotificationReferrer}`);
+      expect(result).toBe(`${mockedHtmlUrl}?${mockedNotificationReferrer}`);
     });
 
     it('Discussions: when no subject urls and no discussions found via query, default to linking to repository discussions', async () => {
@@ -256,7 +256,7 @@ describe('utils/helpers.ts', () => {
 
       expect(apiRequestAuthMock).toHaveBeenCalledTimes(1);
       expect(result).toBe(
-        `${mockedSingleNotification.repository.html_url}/discussions${mockedNotificationReferrer}`,
+        `${mockedSingleNotification.repository.html_url}/discussions?${mockedNotificationReferrer}`,
       );
     });
 
@@ -268,8 +268,6 @@ describe('utils/helpers.ts', () => {
         type: 'Discussion' as SubjectType,
       };
 
-      // const latestDiscussionCommentId = 12345;
-
       const requestPromise = new Promise((resolve) =>
         resolve(mockedGraphQLResponse as AxiosResponse),
       ) as AxiosPromise;
@@ -286,7 +284,29 @@ describe('utils/helpers.ts', () => {
 
       expect(apiRequestAuthMock).toHaveBeenCalledTimes(1);
       expect(result).toBe(
-        'https://github.com/manosim/notifications-test/discussions/612?notification_referrer_id=MDE4Ok5vdGlmaWNhdGlvblRocmVhZDEzODY2MTA5NjoxMjM0NTY3ODk%3D#discussioncomment-2300902',
+        `https://github.com/manosim/notifications-test/discussions/612?${mockedNotificationReferrer}#discussioncomment-2300902`,
+      );
+    });
+
+    it('Repository Invitation url', async () => {
+      const subject = {
+        title: 'Invitation to join manosim/notifications-test from unit-tests',
+        url: null,
+        latest_comment_url: null,
+        type: 'RepositoryInvitation' as SubjectType,
+      };
+
+      const result = await generateGitHubWebUrl(
+        {
+          ...mockedSingleNotification,
+          subject: subject,
+        },
+        mockAccounts,
+      );
+
+      expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
+      expect(result).toBe(
+        `https://github.com/manosim/notifications-test/invitations?${mockedNotificationReferrer}`,
       );
     });
 
@@ -308,7 +328,7 @@ describe('utils/helpers.ts', () => {
 
       expect(apiRequestAuthMock).toHaveBeenCalledTimes(0);
       expect(result).toBe(
-        `${mockedSingleNotification.repository.html_url}${mockedNotificationReferrer}`,
+        `${mockedSingleNotification.repository.html_url}?${mockedNotificationReferrer}`,
       );
     });
   });