diff --git a/src/main/notifications/index.test.js b/src/main/notifications/index.test.js new file mode 100644 index 00000000..3635dd06 --- /dev/null +++ b/src/main/notifications/index.test.js @@ -0,0 +1,170 @@ +// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +'use strict'; + +import {Notification, shell} from 'electron'; + +import {PLAY_SOUND} from 'common/communication'; +import {TAB_MESSAGING} from 'common/tabs/TabView'; + +import * as WindowManager from '../windows/windowManager'; + +import {displayMention, displayDownloadCompleted, currentNotifications} from './index'; + +const mentions = []; + +jest.mock('electron', () => { + class NotificationMock { + static isSupported = jest.fn(); + static didConstruct = jest.fn(); + + constructor(options) { + NotificationMock.didConstruct(); + this.callbackMap = new Map(); + mentions.push({body: options.body, value: this}); + } + + on = (event, callback) => { + this.callbackMap.set(event, callback); + } + + show = jest.fn().mockImplementation(() => { + this.callbackMap.get('show')(); + }); + + click = jest.fn().mockImplementation(() => { + this.callbackMap.get('click')(); + }); + + close = jest.fn(); + } + + return { + app: { + getAppPath: () => '/path/to/app', + }, + Notification: NotificationMock, + shell: { + showItemInFolder: jest.fn(), + }, + }; +}); + +jest.mock('electron-log', () => ({ + info: jest.fn(), + error: jest.fn(), +})); + +jest.mock('../windows/windowManager', () => ({ + getServerNameByWebContentsId: () => 'server_name', + sendToRenderer: jest.fn(), + flashFrame: jest.fn(), + switchTab: jest.fn(), +})); + +describe('main/notifications', () => { + describe('displayMention', () => { + beforeEach(() => { + Notification.isSupported.mockImplementation(() => true); + }); + + it('should do nothing when Notification is not supported', () => { + Notification.isSupported.mockImplementation(() => false); + displayMention( + 'test', + 'test body', + {id: 'channel_id'}, + 'team_id', + 'http://server-1.com/team_id/channel_id', + false, + {id: 1}, + {}, + ); + expect(Notification.didConstruct).not.toBeCalled(); + }); + + it('should play notification sound when custom sound is provided', () => { + displayMention( + 'test', + 'test body', + {id: 'channel_id'}, + 'team_id', + 'http://server-1.com/team_id/channel_id', + false, + {id: 1}, + {soundName: 'test_sound'}, + ); + expect(WindowManager.sendToRenderer).toHaveBeenCalledWith(PLAY_SOUND, 'test_sound'); + }); + + it('should remove existing notification from the same channel/team on windows', () => { + const originalPlatform = process.platform; + Object.defineProperty(process, 'platform', { + value: 'win32', + }); + + displayMention( + 'test', + 'test body', + {id: 'channel_id'}, + 'team_id', + 'http://server-1.com/team_id/channel_id', + false, + {id: 1}, + {}, + ); + + expect(currentNotifications.has('team_id:channel_id')).toBe(true); + + const existingMention = currentNotifications.get('team_id:channel_id'); + currentNotifications.delete = jest.fn(); + displayMention( + 'test', + 'test body 2', + {id: 'channel_id'}, + 'team_id', + 'http://server-1.com/team_id/channel_id', + false, + {id: 1}, + {}, + ); + + expect(currentNotifications.delete).toHaveBeenCalled(); + expect(existingMention.close).toHaveBeenCalled(); + + Object.defineProperty(process, 'platform', { + value: originalPlatform, + }); + }); + + it('should switch tab when clicking on notification', () => { + displayMention( + 'click_test', + 'mention_click_body', + {id: 'channel_id'}, + 'team_id', + 'http://server-1.com/team_id/channel_id', + false, + {id: 1, send: jest.fn()}, + {}, + ); + const mention = mentions.find((m) => m.body === 'mention_click_body'); + mention.value.click(); + expect(WindowManager.switchTab).toHaveBeenCalledWith('server_name', TAB_MESSAGING); + }); + }); + + describe('displayDownloadCompleted', () => { + it('should open file when clicked', () => { + displayDownloadCompleted( + 'test_filename', + '/path/to/file', + 'server_name', + ); + const mention = mentions.find((m) => m.body.includes('test_filename')); + mention.value.click(); + expect(shell.showItemInFolder).toHaveBeenCalledWith('/path/to/file'); + }); + }); +}); diff --git a/src/main/notifications/index.ts b/src/main/notifications/index.ts index 5a493a2e..4bea76fa 100644 --- a/src/main/notifications/index.ts +++ b/src/main/notifications/index.ts @@ -14,7 +14,7 @@ import * as windowManager from '../windows/windowManager'; import {Mention} from './Mention'; import {DownloadNotification} from './Download'; -const currentNotifications = new Map(); +export const currentNotifications = new Map(); export function displayMention(title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, webcontents: Electron.WebContents, data: MentionData) { if (!Notification.isSupported()) {