1343 lines
56 KiB
TypeScript
1343 lines
56 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
/* eslint-disable max-lines */
|
|
|
|
import {DeviceEventEmitter} from 'react-native';
|
|
|
|
import {ActionType, Events, Navigation} from '@constants';
|
|
import {SYSTEM_IDENTIFIERS} from '@constants/database';
|
|
import DatabaseManager from '@database/manager';
|
|
import {getMyChannel} from '@queries/servers/channel';
|
|
import {getPostById} from '@queries/servers/post';
|
|
import {getCommonSystemValues, getTeamHistory} from '@queries/servers/system';
|
|
import {getTeamChannelHistory} from '@queries/servers/team';
|
|
import {dismissAllModalsAndPopToRoot, dismissAllModalsAndPopToScreen} from '@screens/navigation';
|
|
import TestHelper from '@test/test_helper';
|
|
|
|
import {
|
|
switchToChannel,
|
|
removeCurrentUserFromChannel,
|
|
setChannelDeleteAt,
|
|
selectAllMyChannelIds,
|
|
markChannelAsUnread,
|
|
resetMessageCount,
|
|
storeMyChannelsForTeam,
|
|
updateMyChannelFromWebsocket,
|
|
updateChannelInfoFromChannel,
|
|
updateLastPostAt,
|
|
updateChannelsDisplayName,
|
|
showUnreadChannelsOnly,
|
|
updateDmGmDisplayName,
|
|
deletePostsForChannelsWithAutotranslation,
|
|
deletePostsForChannel,
|
|
} from './channel';
|
|
|
|
import type {ChannelModel, MyChannelModel, SystemModel} from '@database/models/server';
|
|
import type ServerDataOperator from '@database/operator/server_data_operator';
|
|
import type {Database} from '@nozbe/watermelondb';
|
|
|
|
let mockIsTablet: jest.Mock;
|
|
const now = new Date('2020-01-01').getTime();
|
|
|
|
jest.mock('@screens/navigation', () => {
|
|
const original = jest.requireActual('@screens/navigation');
|
|
return {
|
|
...original,
|
|
dismissAllModalsAndPopToScreen: jest.fn(),
|
|
dismissAllModalsAndPopToRoot: jest.fn(),
|
|
};
|
|
});
|
|
|
|
jest.mock('@utils/helpers', () => {
|
|
const original = jest.requireActual('@utils/helpers');
|
|
mockIsTablet = jest.fn(() => false);
|
|
return {
|
|
...original,
|
|
isTablet: mockIsTablet,
|
|
};
|
|
});
|
|
|
|
const queryDatabaseValues = async (database: Database, teamId: string, channelId: string) => ({
|
|
systemValues: await getCommonSystemValues(database),
|
|
teamHistory: await getTeamHistory(database),
|
|
channelHistory: await getTeamChannelHistory(database, teamId),
|
|
member: await getMyChannel(database, channelId),
|
|
});
|
|
|
|
describe('switchToChannel', () => {
|
|
let operator: ServerDataOperator;
|
|
let spyNow: jest.SpyInstance;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const team: Team = {
|
|
id: teamId,
|
|
} as Team;
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
} as ChannelMembership;
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
spyNow = jest.spyOn(Date, 'now').mockImplementation(() => now);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
spyNow.mockRestore();
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {error} = await switchToChannel('foo', 'channelId');
|
|
listener.remove();
|
|
|
|
expect(error).toBeTruthy();
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(0);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('handle no member', async () => {
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, 'channelId');
|
|
listener.remove();
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(0);
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(systemValues.currentTeamId).toBe('');
|
|
expect(systemValues.currentChannelId).toBe('');
|
|
expect(teamHistory.length).toBe(0);
|
|
expect(channelHistory.length).toBe(0);
|
|
expect(member?.lastViewedAt).toBe(undefined);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(0);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to current channel', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: channelId}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(2); // Viewed at, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(0);
|
|
expect(channelHistory.length).toBe(0);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to different channel in same team', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(4); // Viewed at, channel history and currentChannelId
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(0);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to different channel in different team', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'currentTeamId'}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId, teamId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(6); // Viewed at, channel history, team history, currentTeamId and currentChannelId
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(1);
|
|
expect(teamHistory[0]).toBe(teamId);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to same channel in different team', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
const tChannel = {...channel, team_id: ''};
|
|
await operator.handleChannel({channels: [tChannel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [tChannel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'currentTeamId'}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: channelId}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId, teamId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(5); // Viewed at, channel history, team history and currentTeamId, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(1);
|
|
expect(teamHistory[0]).toBe(teamId);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to dm channel in different team', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
const tChannel = {...channel, team_id: ''};
|
|
await operator.handleChannel({channels: [tChannel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [tChannel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'currentTeamId'}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId, teamId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(6); // Viewed at, channel history, team history, currentTeamId and currentChannelId, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(1);
|
|
expect(teamHistory[0]).toBe(teamId);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to a channel from different team without passing the teamId', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'currentTeamId'}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(6); // Viewed at, channel history, team history, currentTeamId and currentChannelId, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(1);
|
|
expect(teamHistory[0]).toBe(teamId);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to a channel from the same team without passing a teamId', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(4); // Viewed at, channel history and currentChannelId, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(0);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to a DM without passing the teamId', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
const tChannel = {...channel, team_id: ''};
|
|
await operator.handleChannel({channels: [tChannel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [tChannel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(4); // Viewed at, channel history and currentChannelId, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(0);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to a channel passing a wrong teamId', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'currentTeamId'}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId, 'someTeamId');
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(6); // Viewed at, channel history, team history, currentTeamId and currentChannelId, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(1);
|
|
expect(teamHistory[0]).toBe(teamId);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('switch to a DM passing a non-existing teamId', async () => {
|
|
const currentTeamId = 'ctid';
|
|
const currentChannelId = 'ccid';
|
|
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
const tChannel = {...channel, team_id: ''};
|
|
await operator.handleChannel({channels: [tChannel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [tChannel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: currentTeamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: currentChannelId}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {error} = await switchToChannel(serverUrl, channelId, 'someTeamId');
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeTruthy();
|
|
expect(systemValues.currentTeamId).toBe(currentTeamId);
|
|
expect(systemValues.currentChannelId).toBe(currentChannelId);
|
|
expect(teamHistory.length).toBe(0);
|
|
expect(channelHistory.length).toBe(0);
|
|
expect(member?.lastViewedAt).toBe(0);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(0);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('prepare records only does not change the database', async () => {
|
|
const currentTeamId = 'ctid';
|
|
const currentChannelId = 'ccid';
|
|
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: currentTeamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: currentChannelId}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId, teamId, false, true);
|
|
for (const model of models!) {
|
|
model.cancelPrepareUpdate();
|
|
}
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(6); // Viewed at, channel history, team history, currentTeamId and currentChannelId, lastunread
|
|
expect(systemValues.currentTeamId).toBe(currentTeamId);
|
|
expect(systemValues.currentChannelId).toBe(currentChannelId);
|
|
expect(teamHistory.length).toBe(0);
|
|
expect(channelHistory.length).toBe(0);
|
|
expect(member?.lastViewedAt).toBe(0);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(1);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(0);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
it('test behaviour when it is a tablet', async () => {
|
|
mockIsTablet.mockImplementationOnce(() => true);
|
|
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: 'currentTeamId'}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: 'currentChannelId'}], prepareRecordsOnly: false});
|
|
|
|
const listenerCallback = jest.fn();
|
|
const listener = DeviceEventEmitter.addListener(Navigation.NAVIGATION_HOME, listenerCallback);
|
|
const {models, error} = await switchToChannel(serverUrl, channelId, teamId);
|
|
listener.remove();
|
|
|
|
const {systemValues, teamHistory, channelHistory, member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(6); // Viewed at, channel history, team history, currentTeamId and currentChannelId, lastUnread
|
|
expect(systemValues.currentTeamId).toBe(teamId);
|
|
expect(systemValues.currentChannelId).toBe(channelId);
|
|
expect(teamHistory.length).toBe(1);
|
|
expect(teamHistory[0]).toBe(teamId);
|
|
expect(channelHistory.length).toBe(1);
|
|
expect(channelHistory[0]).toBe(channelId);
|
|
expect(member?.lastViewedAt).toBe(now);
|
|
expect(dismissAllModalsAndPopToScreen).toHaveBeenCalledTimes(0);
|
|
expect(dismissAllModalsAndPopToRoot).toHaveBeenCalledTimes(1);
|
|
expect(listenerCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
|
|
describe('removeCurrentUserFromChannel', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const team: Team = {
|
|
id: teamId,
|
|
} as Team;
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
} as ChannelMembership;
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {error} = await removeCurrentUserFromChannel('foo', 'channelId');
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no member', async () => {
|
|
const {models, error} = await removeCurrentUserFromChannel(serverUrl, 'channelId');
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(0);
|
|
});
|
|
|
|
it('handle no channel', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: channelId}], prepareRecordsOnly: false});
|
|
|
|
const {models, error} = await removeCurrentUserFromChannel(serverUrl, channelId);
|
|
expect(error).toBeTruthy();
|
|
expect(models).toBeUndefined();
|
|
});
|
|
|
|
it('remove user from current channel', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: teamId}, {id: SYSTEM_IDENTIFIERS.CURRENT_CHANNEL_ID, value: channelId}], prepareRecordsOnly: false});
|
|
|
|
const {models, error} = await removeCurrentUserFromChannel(serverUrl, channelId);
|
|
|
|
const {member} = await queryDatabaseValues(operator.database, teamId, channelId);
|
|
|
|
expect(error).toBeUndefined();
|
|
expect(member).toBeUndefined();
|
|
expect(models?.length).toBe(2); // Deleted my channel and channel
|
|
});
|
|
});
|
|
|
|
describe('setChannelDeleteAt', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {error} = await setChannelDeleteAt('foo', channelId, 0);
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no channel', async () => {
|
|
const {models, error} = await setChannelDeleteAt(serverUrl, channelId, 0);
|
|
expect(error).toBeDefined();
|
|
expect(error).toBe(`channel with id ${channelId} not found`);
|
|
expect(models).toBeUndefined();
|
|
});
|
|
|
|
it('set channel delete at', async () => {
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
|
|
const {models, error} = await setChannelDeleteAt(serverUrl, channelId, 123);
|
|
expect(error).toBeUndefined();
|
|
expect(models?.length).toBe(1); // Deleted channel
|
|
expect(models![0].deleteAt).toBe(123);
|
|
});
|
|
});
|
|
|
|
describe('selectAllMyChannelIds', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
} as ChannelMembership;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const result = await selectAllMyChannelIds('foo');
|
|
expect(result.length).toBe(0);
|
|
});
|
|
|
|
it('handle no my channels', async () => {
|
|
const result = await selectAllMyChannelIds(serverUrl);
|
|
expect(result.length).toBe(0);
|
|
});
|
|
|
|
it('select my channels', async () => {
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
|
|
const result = await selectAllMyChannelIds(serverUrl);
|
|
expect(result.length).toBe(1); // My channel
|
|
expect(result[0]).toBe(channelId);
|
|
});
|
|
});
|
|
|
|
describe('markChannelAsUnread', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
} as ChannelMembership;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {member, error} = await markChannelAsUnread('foo', channelId, 10, 1, 123, false);
|
|
expect(error).toBeTruthy();
|
|
expect(member).toBeUndefined();
|
|
});
|
|
|
|
it('handle no member', async () => {
|
|
const {member, error} = await markChannelAsUnread(serverUrl, channelId, 10, 1, 123, false);
|
|
expect(error).toBe('not a member');
|
|
expect(member).toBeUndefined();
|
|
});
|
|
|
|
it('mark channel as unread', async () => {
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
|
|
const {member, error} = await markChannelAsUnread(serverUrl, channelId, 10, 1, 123, false);
|
|
expect(error).toBeUndefined();
|
|
expect(member).toBeDefined();
|
|
expect(member?.viewedAt).toBe(122);
|
|
expect(member?.lastViewedAt).toBe(122);
|
|
expect(member?.messageCount).toBe(10);
|
|
expect(member?.mentionsCount).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('resetMessageCount', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 10,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 10,
|
|
} as ChannelMembership;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const result = await resetMessageCount('foo', channelId);
|
|
expect((result as { error: unknown }).error).toBeDefined();
|
|
});
|
|
|
|
it('handle no member', async () => {
|
|
const result = await resetMessageCount(serverUrl, channelId);
|
|
expect((result as { error: unknown }).error).toBe('not a member');
|
|
});
|
|
|
|
it('reset message count', async () => {
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
|
|
const member = await resetMessageCount(serverUrl, channelId);
|
|
expect((member as { error: unknown }).error).toBeUndefined();
|
|
expect(member).toBeDefined();
|
|
expect((member as MyChannelModel).messageCount).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('storeMyChannelsForTeam', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const team: Team = {
|
|
id: teamId,
|
|
} as Team;
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
} as ChannelMembership;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {models, error} = await storeMyChannelsForTeam('foo', teamId, [channel], [channelMember], false, false);
|
|
expect(models).toBeUndefined();
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no member', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: 'userid'}], prepareRecordsOnly: false});
|
|
|
|
const {models, error} = await storeMyChannelsForTeam(serverUrl, teamId, [], [], false, false);
|
|
expect(error).toBeUndefined();
|
|
expect(models).toBeDefined();
|
|
expect(models!.length).toBe(0);
|
|
});
|
|
|
|
it('store my channels for team', async () => {
|
|
await operator.handleTeam({teams: [team], prepareRecordsOnly: false});
|
|
|
|
const {models: prepModels, error: prepError} = await storeMyChannelsForTeam(serverUrl, teamId, [channel], [channelMember], true, false);
|
|
expect(prepError).toBeUndefined();
|
|
expect(prepModels).toBeDefined();
|
|
expect(prepModels!.length).toBe(5); // Channel, channel info, member, settings and my channel
|
|
|
|
const {models, error} = await storeMyChannelsForTeam(serverUrl, teamId, [channel], [channelMember], false, false);
|
|
expect(error).toBeUndefined();
|
|
expect(models).toBeDefined();
|
|
expect(models!.length).toBe(5);
|
|
});
|
|
});
|
|
|
|
describe('updateMyChannelFromWebsocket', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = TestHelper.fakeChannel({
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
});
|
|
const channelMember: ChannelMembership = TestHelper.fakeChannelMember({
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
roles: '',
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {model, error} = await updateMyChannelFromWebsocket('foo', channelMember, false);
|
|
expect(model).toBeUndefined();
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('update my channel from websocket', async () => {
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
|
|
const {model, error} = await updateMyChannelFromWebsocket(serverUrl, {...channelMember, roles: 'channel_user'}, false);
|
|
expect(error).toBeUndefined();
|
|
expect(model).toBeDefined();
|
|
expect(model?.roles).toBe('channel_user');
|
|
});
|
|
|
|
it('calls deletePostsForChannel when autotranslation changes', async () => {
|
|
const post = TestHelper.fakePost({id: 'postid1', channel_id: channelId, root_id: ''});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handlePosts({actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL, order: [post.id], posts: [post], prepareRecordsOnly: false});
|
|
|
|
await updateMyChannelFromWebsocket(serverUrl, {...channelMember, autotranslation_disabled: true}, false);
|
|
|
|
expect(DeviceEventEmitter.emit).toHaveBeenCalledWith(Events.POST_DELETED_FOR_CHANNEL, {serverUrl, channelId, teamId: channel.team_id});
|
|
});
|
|
|
|
it('updates member autotranslation from channelMember', async () => {
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
|
|
await updateMyChannelFromWebsocket(serverUrl, {...channelMember, autotranslation_disabled: true}, false);
|
|
|
|
const member = await getMyChannel(operator.database, channelId);
|
|
expect(member?.autotranslationDisabled).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('updateChannelInfoFromChannel', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {model, error} = await updateChannelInfoFromChannel('foo', channel, false);
|
|
expect(model).toBeUndefined();
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('update channel info from channel', async () => {
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
|
|
const {model, error} = await updateChannelInfoFromChannel(serverUrl, {...channel, header: 'newheader'}, false);
|
|
expect(error).toBeUndefined();
|
|
expect(model).toBeDefined();
|
|
expect(model?.length).toBe(1);
|
|
expect(model![0].header).toBe('newheader');
|
|
});
|
|
});
|
|
|
|
describe('updateLastPostAt', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
roles: '',
|
|
} as ChannelMembership;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {member, error} = await updateLastPostAt('foo', channelId, 123, false);
|
|
expect(member).toBeUndefined();
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no member', async () => {
|
|
const {member, error} = await updateLastPostAt(serverUrl, channelId, 123, false);
|
|
expect(error).toBeDefined();
|
|
expect(error).toBe('not a member');
|
|
expect(member).toBeUndefined();
|
|
});
|
|
|
|
it('update last post at', async () => {
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
|
|
const {member, error} = await updateLastPostAt(serverUrl, channelId, 123, false);
|
|
expect(error).toBeUndefined();
|
|
expect(member).toBeDefined();
|
|
expect(member?.lastPostAt).toBe(123);
|
|
});
|
|
});
|
|
|
|
describe('updateChannelsDisplayName', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const dmChannel: Channel = {
|
|
id: channelId,
|
|
name: 'userid__userid2',
|
|
display_name: '',
|
|
team_id: '',
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
type: 'D',
|
|
} as Channel;
|
|
const dmChannelMember: ChannelMembership = {
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: dmChannel.id,
|
|
msg_count: 0,
|
|
roles: '',
|
|
} as ChannelMembership;
|
|
const gmChannel: Channel = {
|
|
id: 'id2',
|
|
name: 'name',
|
|
display_name: '',
|
|
team_id: '',
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
type: 'G',
|
|
} as Channel;
|
|
const gmChannelMember: ChannelMembership = {
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: gmChannel.id,
|
|
msg_count: 0,
|
|
roles: '',
|
|
} as ChannelMembership;
|
|
const user: UserProfile = {
|
|
id: 'userid',
|
|
username: 'username',
|
|
roles: '',
|
|
} as UserProfile;
|
|
const user2: UserProfile = {
|
|
id: 'userid2',
|
|
username: 'username2',
|
|
first_name: 'first',
|
|
last_name: 'last',
|
|
roles: '',
|
|
} as UserProfile;
|
|
const user3: UserProfile = {
|
|
id: 'userid3',
|
|
username: 'username3',
|
|
first_name: 'first',
|
|
last_name: 'last',
|
|
roles: '',
|
|
} as UserProfile;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {models, error} = await updateChannelsDisplayName('foo', [], [], false);
|
|
expect(models).toBeUndefined();
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no currnet user', async () => {
|
|
const {models, error} = await updateChannelsDisplayName(serverUrl, [], [], false);
|
|
expect(models).toBeUndefined();
|
|
expect(error).toBeUndefined();
|
|
});
|
|
|
|
it('update channels display name', async () => {
|
|
const channelModels = await operator.handleChannel({channels: [dmChannel, gmChannel], prepareRecordsOnly: false});
|
|
await operator.handleUsers({users: [user, user2, user3], prepareRecordsOnly: false});
|
|
await operator.handleChannelMembership({channelMemberships: [{...gmChannelMember, user_id: user2.id}, {...gmChannelMember, user_id: user3.id}], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [dmChannel, gmChannel], myChannels: [dmChannelMember, gmChannelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user.id}], prepareRecordsOnly: false});
|
|
|
|
const {models, error} = await updateChannelsDisplayName(serverUrl, channelModels, [user, user2], false);
|
|
expect(error).toBeUndefined();
|
|
expect(models).toBeDefined();
|
|
expect(models?.length).toBe(2);
|
|
expect((models![0] as ChannelModel).displayName).toBe(user2.username);
|
|
expect((models![1] as ChannelModel).displayName).toBe(`${user2.username}, ${user3.username}`);
|
|
});
|
|
});
|
|
|
|
describe('showUnreadChannelsOnly', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
} as Channel;
|
|
const channelMember: ChannelMembership = {
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
roles: '',
|
|
} as ChannelMembership;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const result = await showUnreadChannelsOnly('foo', true);
|
|
expect((result as { error: unknown}).error).toBeTruthy();
|
|
});
|
|
|
|
it('show unread channels only', async () => {
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
|
|
const result = await showUnreadChannelsOnly(serverUrl, true);
|
|
expect((result as { error: unknown}).error).toBeUndefined();
|
|
const models = (result as SystemModel[]);
|
|
expect(models).toBeDefined();
|
|
expect(models?.length).toBe(1);
|
|
expect(models![0].id).toBe(SYSTEM_IDENTIFIERS.ONLY_UNREADS);
|
|
expect(models![0].value).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('updateDmGmDisplayName', () => {
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const dmChannel: Channel = {
|
|
id: channelId,
|
|
name: 'userid__userid2',
|
|
display_name: '',
|
|
team_id: '',
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
type: 'D',
|
|
} as Channel;
|
|
const dmChannelMember: ChannelMembership = {
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: dmChannel.id,
|
|
msg_count: 0,
|
|
roles: '',
|
|
} as ChannelMembership;
|
|
const gmChannel: Channel = {
|
|
id: 'id2',
|
|
name: 'name',
|
|
display_name: '',
|
|
team_id: '',
|
|
total_msg_count: 0,
|
|
delete_at: 0,
|
|
type: 'G',
|
|
} as Channel;
|
|
const gmChannelMember: ChannelMembership = {
|
|
id: 'id',
|
|
user_id: 'userid',
|
|
channel_id: gmChannel.id,
|
|
msg_count: 0,
|
|
roles: '',
|
|
} as ChannelMembership;
|
|
const user: UserProfile = {
|
|
id: 'userid',
|
|
username: 'username',
|
|
roles: '',
|
|
} as UserProfile;
|
|
const user2: UserProfile = {
|
|
id: 'userid2',
|
|
username: 'username2',
|
|
first_name: 'first',
|
|
last_name: 'last',
|
|
roles: '',
|
|
} as UserProfile;
|
|
const user3: UserProfile = {
|
|
id: 'userid3',
|
|
username: 'username3',
|
|
first_name: 'first',
|
|
last_name: 'last',
|
|
roles: '',
|
|
} as UserProfile;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {channels, error} = await updateDmGmDisplayName('foo');
|
|
expect(channels).toBeUndefined();
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no currnet user', async () => {
|
|
const {channels, error} = await updateDmGmDisplayName(serverUrl);
|
|
expect(channels).toBeUndefined();
|
|
expect(error).toBeDefined();
|
|
expect(error).toBe('The current user id could not be retrieved from the database');
|
|
});
|
|
|
|
it('update dm gm display name', async () => {
|
|
await operator.handleChannel({channels: [dmChannel, gmChannel], prepareRecordsOnly: false});
|
|
await operator.handleUsers({users: [user, user2, user3], prepareRecordsOnly: false});
|
|
await operator.handleChannelMembership({channelMemberships: [gmChannelMember, dmChannelMember, {...gmChannelMember, user_id: user2.id}, {...gmChannelMember, user_id: user3.id}], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [dmChannel, gmChannel], myChannels: [dmChannelMember, gmChannelMember], prepareRecordsOnly: false});
|
|
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user.id}], prepareRecordsOnly: false});
|
|
|
|
const {channels, error} = await updateDmGmDisplayName(serverUrl);
|
|
expect(error).toBeUndefined();
|
|
expect(channels).toBeDefined();
|
|
expect(channels?.length).toBe(2);
|
|
expect((channels![0] as ChannelModel).displayName).toBe(user2.username);
|
|
expect((channels![1] as ChannelModel).displayName).toBe(`${user2.username}, ${user3.username}`);
|
|
});
|
|
});
|
|
|
|
describe('deletePostsForChannel', () => {
|
|
const serverUrl = 'baseHandler.test.com';
|
|
let operator: ServerDataOperator;
|
|
|
|
const channelId = 'channelid1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = TestHelper.fakeChannel({
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
});
|
|
const channelMember: ChannelMembership = TestHelper.fakeChannelMember({
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('handle not found database', async () => {
|
|
const {models, error} = await deletePostsForChannel('foo', channelId);
|
|
expect(models).toEqual([]);
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('channel not found', async () => {
|
|
const {models, error} = await deletePostsForChannel(serverUrl, 'nonexistent');
|
|
expect(models).toEqual([]);
|
|
expect(error).toBeFalsy();
|
|
});
|
|
|
|
it('channel with no posts', async () => {
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
|
|
const {models, error} = await deletePostsForChannel(serverUrl, channelId);
|
|
expect(models).toEqual([]);
|
|
expect(error).toBeFalsy();
|
|
});
|
|
|
|
it('channel with posts - batch written and event emitted', async () => {
|
|
const post = TestHelper.fakePost({id: 'postid1', channel_id: channelId, root_id: ''});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handlePosts({
|
|
actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL,
|
|
order: [post.id],
|
|
posts: [post],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const listener = jest.fn();
|
|
const subscription = DeviceEventEmitter.addListener(Events.POST_DELETED_FOR_CHANNEL, listener);
|
|
|
|
const {models, error} = await deletePostsForChannel(serverUrl, channelId);
|
|
subscription.remove();
|
|
|
|
expect(error).toBeFalsy();
|
|
expect(models.length).toBeGreaterThan(0);
|
|
expect(listener).toHaveBeenCalledTimes(1);
|
|
expect(listener).toHaveBeenCalledWith({serverUrl, channelId, teamId: channel.team_id});
|
|
|
|
const myChannel = await getMyChannel(operator.database, channelId);
|
|
expect(myChannel?.lastFetchedAt).toBe(0);
|
|
});
|
|
|
|
it('prepareRecordsOnly true - no write and no emit', async () => {
|
|
const post = TestHelper.fakePost({id: 'postid2', channel_id: channelId, root_id: ''});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handlePosts({
|
|
actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL,
|
|
order: [post.id],
|
|
posts: [post],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const listener = jest.fn();
|
|
const subscription = DeviceEventEmitter.addListener(Events.POST_DELETED_FOR_CHANNEL, listener);
|
|
|
|
const {models, error} = await deletePostsForChannel(serverUrl, channelId, true);
|
|
subscription.remove();
|
|
|
|
expect(error).toBeFalsy();
|
|
expect(models.length).toBeGreaterThan(0);
|
|
expect(listener).not.toHaveBeenCalled();
|
|
|
|
const myChannel = await getMyChannel(operator.database, channelId);
|
|
expect(myChannel?._preparedState).toBe('update');
|
|
|
|
// Batch the records to avoid the invariant error
|
|
await operator.batchRecords([...models], 'test');
|
|
});
|
|
});
|
|
|
|
describe('deletePostsForChannelsWithAutotranslation', () => {
|
|
const serverUrl = 'baseHandler.test.com';
|
|
let operator: ServerDataOperator;
|
|
|
|
const channelId = 'channelid1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = TestHelper.fakeChannel({
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
autotranslation: true,
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
it('no myChannels with autotranslation - no deletes', async () => {
|
|
const channelMember: ChannelMembership = TestHelper.fakeChannelMember({
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
autotranslation_disabled: true,
|
|
});
|
|
const post = TestHelper.fakePost({id: 'postid1', channel_id: channelId, root_id: ''});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handlePosts({
|
|
actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL,
|
|
order: [post.id],
|
|
posts: [post],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const {models, error} = await deletePostsForChannelsWithAutotranslation(serverUrl);
|
|
expect(error).toBeUndefined();
|
|
expect(models).toEqual([]);
|
|
|
|
const databasePost = await getPostById(operator.database, post.id);
|
|
expect(databasePost).toBeDefined();
|
|
});
|
|
|
|
it('myChannels with autotranslation - delete posts', async () => {
|
|
const channelMember: ChannelMembership = TestHelper.fakeChannelMember({
|
|
id: 'id',
|
|
channel_id: channelId,
|
|
msg_count: 0,
|
|
autotranslation_disabled: false,
|
|
});
|
|
const post = TestHelper.fakePost({id: 'postid1', channel_id: channelId, root_id: ''});
|
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
|
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
|
await operator.handlePosts({
|
|
actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL,
|
|
order: [post.id],
|
|
posts: [post],
|
|
prepareRecordsOnly: false,
|
|
});
|
|
|
|
const {models, error} = await deletePostsForChannelsWithAutotranslation(serverUrl);
|
|
expect(error).toBeUndefined();
|
|
expect(models.length).toBeGreaterThan(0);
|
|
const databasePost = await getPostById(operator.database, post.id);
|
|
expect(databasePost).toBeUndefined();
|
|
});
|
|
|
|
it('handle error', async () => {
|
|
jest.spyOn(DatabaseManager, 'getServerDatabaseAndOperator').mockImplementationOnce(() => {
|
|
throw new Error('DB error');
|
|
});
|
|
const {models, error} = await deletePostsForChannelsWithAutotranslation(serverUrl);
|
|
expect(models).toEqual([]);
|
|
expect(error).toBeTruthy();
|
|
});
|
|
});
|