From 4ee4ff10ddb3dc0a6745d0fb770d5b99a25f9020 Mon Sep 17 00:00:00 2001 From: Miguel Alatzar Date: Fri, 26 Jul 2019 03:21:11 -0700 Subject: [PATCH] [MM-14926] Clear foreground notifications from AsyncStorage on logout and server upgrade (#3033) * Clear foreground notifications from AsyncStorage * Remove unnecessary call to clearNotifications --- app/init/global_event_handler.js | 5 +--- app/init/global_event_handler.test.js | 28 +++++++++++++++++++ .../push_notifications.android.js | 10 +++++++ .../push_notifications.ios.js | 10 +++++++ .../push_notifications.ios.test.js | 14 ++++++++++ 5 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 app/init/global_event_handler.test.js diff --git a/app/init/global_event_handler.js b/app/init/global_event_handler.js index 4eb258b93..c0a013946 100644 --- a/app/init/global_event_handler.js +++ b/app/init/global_event_handler.js @@ -143,8 +143,7 @@ class GlobalEventHandler { deleteFileCache(); removeAppCredentials(); - PushNotifications.setApplicationIconBadgeNumber(0); - PushNotifications.cancelAllLocalNotifications(); // TODO: Only cancel the notification that belongs to this server + PushNotifications.clearNotifications(); if (this.launchApp) { this.launchApp(); @@ -225,8 +224,6 @@ class GlobalEventHandler { dispatch(setServerVersion('')); Client4.serverVersion = ''; - PushNotifications.setApplicationIconBadgeNumber(0); - PushNotifications.cancelAllLocalNotifications(); // TODO: Only cancel the notification that belongs to this server const credentials = await getAppCredentials(); diff --git a/app/init/global_event_handler.test.js b/app/init/global_event_handler.test.js new file mode 100644 index 000000000..a3abef9f5 --- /dev/null +++ b/app/init/global_event_handler.test.js @@ -0,0 +1,28 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; + +import PushNotification from 'app/push_notifications'; + +import GlobalEventHandler from './global_event_handler'; + +jest.mock('app/init/credentials', () => ({ + getAppCredentials: jest.fn(), + removeAppCredentials: jest.fn(), +})); + +const mockStore = configureMockStore([thunk]); +const store = mockStore({}); +GlobalEventHandler.store = store; + +// TODO: Add Android test as part of https://mattermost.atlassian.net/browse/MM-17110 +describe('GlobalEventHandler', () => { + it('should clear notifications on logout', () => { + const clearNotifications = jest.spyOn(PushNotification, 'clearNotifications'); + + GlobalEventHandler.onLogout(); + expect(clearNotifications).toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/app/push_notifications/push_notifications.android.js b/app/push_notifications/push_notifications.android.js index cacbb9aef..9b15f6116 100644 --- a/app/push_notifications/push_notifications.android.js +++ b/app/push_notifications/push_notifications.android.js @@ -113,6 +113,16 @@ class PushNotification { NotificationPreferences.removeDeliveredNotifications(notificationForChannel.identifier, channelId); } } + + clearForegroundNotifications = () => { + // TODO: Implement as part of https://mattermost.atlassian.net/browse/MM-17110 + }; + + clearNotifications = () => { + this.setApplicationIconBadgeNumber(0); + this.cancelAllLocalNotifications(); // TODO: Only cancel the local notifications that belong to this server + this.clearForegroundNotifications(); // TODO: Only clear the foreground notifications that belong to this server + } } export default new PushNotification(); diff --git a/app/push_notifications/push_notifications.ios.js b/app/push_notifications/push_notifications.ios.js index 5ec54d4ca..1040e3ca0 100644 --- a/app/push_notifications/push_notifications.ios.js +++ b/app/push_notifications/push_notifications.ios.js @@ -210,6 +210,16 @@ class PushNotification { foregroundNotifications[channelId] += 1; await AsyncStorage.setItem(FOREGROUND_NOTIFICATIONS_KEY, JSON.stringify(foregroundNotifications)); } + + clearForegroundNotifications = () => { + AsyncStorage.removeItem(FOREGROUND_NOTIFICATIONS_KEY); + }; + + clearNotifications = () => { + this.setApplicationIconBadgeNumber(0); + this.cancelAllLocalNotifications(); // TODO: Only cancel the local notifications that belong to this server + this.clearForegroundNotifications(); // TODO: Only clear the foreground notifications that belong to this server + } } export default new PushNotification(); diff --git a/app/push_notifications/push_notifications.ios.test.js b/app/push_notifications/push_notifications.ios.test.js index 4afa5b9ba..2e4b6cab9 100644 --- a/app/push_notifications/push_notifications.ios.test.js +++ b/app/push_notifications/push_notifications.ios.test.js @@ -24,6 +24,7 @@ jest.mock('react-native-notifications', () => { removeDeliveredNotifications: jest.fn((ids) => { deliveredNotifications = deliveredNotifications.filter((n) => !ids.includes(n.identifier)); }), + cancelAllLocalNotifications: jest.fn(), NotificationAction: jest.fn(), NotificationCategory: jest.fn(), }; @@ -133,4 +134,17 @@ describe('PushNotification', () => { expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(badgeNumber); }); }); + + it('should clear all notifications', () => { + const setApplicationIconBadgeNumber = jest.spyOn(PushNotification, 'setApplicationIconBadgeNumber'); + const cancelAllLocalNotifications = jest.spyOn(PushNotification, 'cancelAllLocalNotifications'); + const clearForegroundNotifications = jest.spyOn(PushNotification, 'clearForegroundNotifications'); + + PushNotification.clearNotifications(); + expect(setApplicationIconBadgeNumber).toHaveBeenCalledWith(0); + expect(NotificationsIOS.setBadgesCount).toHaveBeenCalledWith(0); + expect(cancelAllLocalNotifications).toHaveBeenCalled(); + expect(NotificationsIOS.cancelAllLocalNotifications).toHaveBeenCalled(); + expect(clearForegroundNotifications).toHaveBeenCalled(); + }); }); \ No newline at end of file