+
diff --git a/src/context/App.test.tsx b/src/context/App.test.tsx
index d0b45e637..aea2d742c 100644
--- a/src/context/App.test.tsx
+++ b/src/context/App.test.tsx
@@ -38,6 +38,7 @@ describe('context/App.tsx', () => {
const fetchNotificationsMock = jest.fn();
const markNotificationMock = jest.fn();
+ const markNotificationDoneMock = jest.fn();
const unsubscribeNotificationMock = jest.fn();
const markRepoNotificationsMock = jest.fn();
@@ -45,6 +46,7 @@ describe('context/App.tsx', () => {
(useNotifications as jest.Mock).mockReturnValue({
fetchNotifications: fetchNotificationsMock,
markNotification: markNotificationMock,
+ markNotificationDone: markNotificationDoneMock,
unsubscribeNotification: unsubscribeNotificationMock,
markRepoNotifications: markRepoNotificationsMock,
});
@@ -121,6 +123,31 @@ describe('context/App.tsx', () => {
);
});
+ it('should call markNotificationDone', async () => {
+ const TestComponent = () => {
+ const { markNotificationDone } = useContext(AppContext);
+
+ return (
+
+ );
+ };
+
+ const { getByText } = customRender(
);
+
+ markNotificationDoneMock.mockReset();
+
+ fireEvent.click(getByText('Test Case'));
+
+ expect(markNotificationDoneMock).toHaveBeenCalledTimes(1);
+ expect(markNotificationDoneMock).toHaveBeenCalledWith(
+ { enterpriseAccounts: [], token: null, user: null },
+ '123-456',
+ 'github.com',
+ );
+ });
+
it('should call unsubscribeNotification', async () => {
const TestComponent = () => {
const { unsubscribeNotification } = useContext(AppContext);
diff --git a/src/context/App.tsx b/src/context/App.tsx
index 60197bca5..dbc788cd1 100644
--- a/src/context/App.tsx
+++ b/src/context/App.tsx
@@ -52,6 +52,7 @@ interface AppContextState {
requestFailed: boolean;
fetchNotifications: () => Promise
;
markNotification: (id: string, hostname: string) => Promise;
+ markNotificationDone: (id: string, hostname: string) => Promise;
unsubscribeNotification: (id: string, hostname: string) => Promise;
markRepoNotifications: (id: string, hostname: string) => Promise;
@@ -70,6 +71,7 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
requestFailed,
isFetching,
markNotification,
+ markNotificationDone,
unsubscribeNotification,
markRepoNotifications,
} = useNotifications(settings.colors);
@@ -176,6 +178,12 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
[accounts, notifications],
);
+ const markNotificationDoneWithAccounts = useCallback(
+ async (id: string, hostname: string) =>
+ await markNotificationDone(accounts, id, hostname),
+ [accounts, notifications],
+ );
+
const unsubscribeNotificationWithAccounts = useCallback(
async (id: string, hostname: string) =>
await unsubscribeNotification(accounts, id, hostname),
@@ -203,6 +211,7 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
requestFailed,
fetchNotifications: fetchNotificationsWithAccounts,
markNotification: markNotificationWithAccounts,
+ markNotificationDone: markNotificationDoneWithAccounts,
unsubscribeNotification: unsubscribeNotificationWithAccounts,
markRepoNotifications: markRepoNotificationsWithAccounts,
diff --git a/src/hooks/useNotifications.test.ts b/src/hooks/useNotifications.test.ts
index 66e40f26a..c6f2b753d 100644
--- a/src/hooks/useNotifications.test.ts
+++ b/src/hooks/useNotifications.test.ts
@@ -355,6 +355,92 @@ describe('hooks/useNotifications.ts', () => {
});
});
+ describe('markNotificationDone', () => {
+ const id = 'notification-123';
+
+ describe('github.com', () => {
+ const accounts = { ...mockAccounts, enterpriseAccounts: [] };
+ const hostname = 'github.com';
+
+ it('should mark a notification as done with success - github.com', async () => {
+ nock('https://api.github.com/')
+ .delete(`/notifications/threads/${id}`)
+ .reply(200);
+
+ const { result } = renderHook(() => useNotifications(false));
+
+ act(() => {
+ result.current.markNotificationDone(accounts, id, hostname);
+ });
+
+ await waitFor(() => {
+ expect(result.current.isFetching).toBe(false);
+ });
+
+ expect(result.current.notifications.length).toBe(0);
+ });
+
+ it('should mark a notification as done with failure - github.com', async () => {
+ nock('https://api.github.com/')
+ .delete(`/notifications/threads/${id}`)
+ .reply(400);
+
+ const { result } = renderHook(() => useNotifications(false));
+
+ act(() => {
+ result.current.markNotificationDone(accounts, id, hostname);
+ });
+
+ await waitFor(() => {
+ expect(result.current.isFetching).toBe(false);
+ });
+
+ expect(result.current.notifications.length).toBe(0);
+ });
+ });
+
+ describe('enterprise', () => {
+ const accounts = { ...mockAccounts, token: null };
+ const hostname = 'github.gitify.io';
+
+ it('should mark a notification as done with success - enterprise', async () => {
+ nock('https://github.gitify.io/')
+ .delete(`/notifications/threads/${id}`)
+ .reply(200);
+
+ const { result } = renderHook(() => useNotifications(false));
+
+ act(() => {
+ result.current.markNotificationDone(accounts, id, hostname);
+ });
+
+ await waitFor(() => {
+ expect(result.current.isFetching).toBe(false);
+ });
+
+ expect(result.current.notifications.length).toBe(0);
+ });
+
+ it('should mark a notification as done with failure - enterprise', async () => {
+ nock('https://github.gitify.io/')
+ .delete(`/notifications/threads/${id}`)
+ .reply(400);
+
+ const { result } = renderHook(() => useNotifications(false));
+
+ act(() => {
+ result.current.markNotificationDone(accounts, id, hostname);
+ });
+
+ await waitFor(() => {
+ expect(result.current.isFetching).toBe(false);
+ });
+
+ expect(result.current.notifications.length).toBe(0);
+ });
+ });
+ });
+
describe('unsubscribeNotification', () => {
const id = 'notification-123';
diff --git a/src/hooks/useNotifications.ts b/src/hooks/useNotifications.ts
index 50cf161b1..41875fb8b 100644
--- a/src/hooks/useNotifications.ts
+++ b/src/hooks/useNotifications.ts
@@ -28,6 +28,11 @@ interface NotificationsState {
id: string,
hostname: string,
) => Promise;
+ markNotificationDone: (
+ accounts: AuthState,
+ id: string,
+ hostname: string,
+ ) => Promise;
unsubscribeNotification: (
accounts: AuthState,
id: string,
@@ -215,6 +220,39 @@ export const useNotifications = (colors: boolean): NotificationsState => {
[notifications],
);
+ const markNotificationDone = useCallback(
+ async (accounts, id, hostname) => {
+ setIsFetching(true);
+
+ const isEnterprise = hostname !== Constants.DEFAULT_AUTH_OPTIONS.hostname;
+ const token = isEnterprise
+ ? getEnterpriseAccountToken(hostname, accounts.enterpriseAccounts)
+ : accounts.token;
+
+ try {
+ await apiRequestAuth(
+ `${generateGitHubAPIUrl(hostname)}notifications/threads/${id}`,
+ 'DELETE',
+ token,
+ {},
+ );
+
+ const updatedNotifications = removeNotification(
+ id,
+ notifications,
+ hostname,
+ );
+
+ setNotifications(updatedNotifications);
+ setTrayIconColor(updatedNotifications);
+ setIsFetching(false);
+ } catch (err) {
+ setIsFetching(false);
+ }
+ },
+ [notifications],
+ );
+
const unsubscribeNotification = useCallback(
async (accounts, id, hostname) => {
setIsFetching(true);
@@ -281,6 +319,7 @@ export const useNotifications = (colors: boolean): NotificationsState => {
fetchNotifications,
markNotification,
+ markNotificationDone,
unsubscribeNotification,
markRepoNotifications,
};