Skip to content

Commit

Permalink
MM-59423 Add tests to actions/remote/notifications (#8302)
Browse files Browse the repository at this point in the history
* Add tests to actions/remote/notifications

* Fix typing error in test
  • Loading branch information
jwilander authored Nov 4, 2024
1 parent cd2725e commit a3582c4
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 3 deletions.
189 changes: 189 additions & 0 deletions app/actions/remote/notifications.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

/* eslint-disable max-lines */

import {Platform} from 'react-native';

import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import NetworkManager from '@managers/network_manager';
import TestHelper from '@test/test_helper';

import {
fetchNotificationData,
backgroundNotification,
openNotification,
} from './notifications';

import type ServerDataOperator from '@database/operator/server_data_operator';

const serverUrl = 'baseHandler.test.com';
let operator: ServerDataOperator;

const teamId = 'teamid1';
const team: Team = {
id: teamId,
name: 'team1',
} as Team;

const channelId = 'channelid1';
const channel: Channel = {
id: channelId,
display_name: 'channelname',
team_id: '',
total_msg_count: 0,
delete_at: 0,
} as Channel;

const user1 = {id: 'userid1', username: 'user1', email: 'user1@mattermost.com', roles: ''} as UserProfile;

const post1 = {...TestHelper.fakePost(channelId), id: 'postid1'};

const notificationExtraData = {
channel,
myChannel: {channel_id: channelId, user_id: user1.id, roles: ''} as ChannelMembership,
team,
myTeam: {team_id: teamId, user_id: user1.id, roles: ''} as TeamMembership,
posts: {posts: {[post1.id]: post1}, order: [post1.id], next: 0, prev: 0},
categoryChannels: [{channel_id: channelId, category_id: 'categoryid1', sort_order: 0} as CategoryChannel],
categories: {categories: [{id: 'categoryid1', team_id: teamId, display_name: 'category1', sort_order: 0, sorting: 'alpha', type: 'custom', muted: false, collapsed: false, channel_ids: [channelId]}], order: ['categoryid1']},
} as NotificationExtraData;

const notificationData = {
channel_id: channelId,
team_id: teamId,
post_id: post1.id,
type: 'type',
version: 'version',
isCRTEnabled: false,
data: notificationExtraData,
} as NotificationData;

const notificationWithData = {
payload: notificationData,
} as NotificationWithData;

const throwFunc = (e?: string) => {
throw Error(e == null ? 'error' : e);
};

let mockEmitNotificationError: jest.Mock;
jest.mock('@utils/notification', () => {
const original = jest.requireActual('@utils/notification');
mockEmitNotificationError = jest.fn();
return {
...original,
emitNotificationError: mockEmitNotificationError,
};
});

const mockClient = {
getTeam: jest.fn((id: string) => ({id, name: 'team1'})),
getTeamMember: jest.fn((id: string, userId: string) => ({id: userId + '-' + id, user_id: userId === 'me' ? user1.id : userId, team_id: id, roles: ''})),
getChannel: jest.fn((_channelId: string) => ({...channel, id: _channelId})),
getChannelMember: jest.fn((_channelId: string, userId: string) => ({id: userId + '-' + _channelId, user_id: userId === 'me' ? user1.id : userId, channel_id: _channelId, roles: ''})),
};

beforeAll(() => {
// eslint-disable-next-line
// @ts-ignore
NetworkManager.getClient = () => mockClient;
});

beforeEach(async () => {
await DatabaseManager.init([serverUrl]);
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
});

afterEach(async () => {
await DatabaseManager.destroyServerDatabase(serverUrl);
});

describe('notifications', () => {
it('fetchNotificationData - handle no channel id', async () => {
const result = await fetchNotificationData(serverUrl, {} as NotificationWithData);
expect(result).toBeDefined();
expect(result.error).toBe('No channel Id was specified');
});

it('fetchNotificationData - handle not found database', async () => {
const result = await fetchNotificationData('foo', {payload: {channel_id: channelId}} as NotificationWithData);
expect(result).toBeDefined();
expect(result.error).toBeDefined();
});

it('fetchNotificationData - no team', async () => {
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
mockClient.getTeam.mockImplementationOnce(jest.fn(throwFunc));

const result = await fetchNotificationData(serverUrl, notificationWithData);
expect(result).toBeDefined();
expect(result.error).toBeDefined();
});

it('fetchNotificationData - no channel', async () => {
const myTeams = [
{
id: team.id,
roles: '',
},
];

await operator.handleMyTeam({
myTeams,
prepareRecordsOnly: false,
});
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
mockClient.getChannel.mockImplementationOnce(jest.fn(() => ({...channel, delete_at: 1})));

const result = await fetchNotificationData(serverUrl, notificationWithData);
expect(result).toBeDefined();
expect(result.error).toBe('Channel');
});

it('fetchNotificationData - base case', async () => {
Platform.OS = 'android';
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}, {id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false});

const result = await fetchNotificationData(serverUrl, {payload: {...notificationData, team_id: ''}} as NotificationWithData);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
});

it('backgroundNotification - handle not found database', async () => {
const result = await backgroundNotification('foo', {payload: {channel_id: channelId}} as NotificationWithData);
expect(result).toBeDefined();
expect(result.error).toBeDefined();
});

it('backgroundNotification - handle no channel id', async () => {
const result = await backgroundNotification(serverUrl, {} as NotificationWithData);
expect(result).toBeDefined();
expect(result.error).toMatchObject(new Error('No channel Id was specified'));
});

it('backgroundNotification - base case', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}, {id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false});

const result = await backgroundNotification(serverUrl, {payload: {...notificationData, team_id: ''}} as NotificationWithData);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.models).toBeDefined();
expect(result.models?.length).toBe(1); // team model
});

it('openNotification - handle not found database', async () => {
const result = await openNotification('foo', {payload: {channel_id: channelId}} as NotificationWithData) as {error: unknown};
expect(result).toBeDefined();
expect(result.error).toBeDefined();
});

it('openNotification - base case', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}, {id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}], prepareRecordsOnly: false});

const result = await openNotification(serverUrl, {payload: {...notificationData, team_id: ''}} as NotificationWithData) as {error?: unknown};
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
});
});
9 changes: 6 additions & 3 deletions app/actions/remote/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ import {processPostsFetched} from '@utils/post';

import type {Model} from '@nozbe/watermelondb';

const fetchNotificationData = async (serverUrl: string, notification: NotificationWithData, skipEvents = false) => {
export const fetchNotificationData = async (serverUrl: string, notification: NotificationWithData, skipEvents = false) => {
const channelId = notification.payload?.channel_id;

if (!channelId) {
return {error: 'No chanel Id was specified'};
return {error: 'No channel Id was specified'};
}

try {
Expand Down Expand Up @@ -103,7 +103,7 @@ export const backgroundNotification = async (serverUrl: string, notification: No
const channelId = notification.payload?.channel_id;
let teamId = notification.payload?.team_id;
if (!channelId) {
throw new Error('No chanel Id was specified');
throw new Error('No channel Id was specified');
}

if (!teamId) {
Expand Down Expand Up @@ -173,9 +173,12 @@ export const backgroundNotification = async (serverUrl: string, notification: No
if (models.length) {
await operator.batchRecords(models, 'backgroundNotification');
}
return {models};
}
return {models: []};
} catch (error) {
logWarning('backgroundNotification', error);
return {error};
}
};

Expand Down

0 comments on commit a3582c4

Please sign in to comment.