Add tests for actions/websocket/posts (#8465)
This commit is contained in:
parent
fff6788e94
commit
e6c19637b9
2 changed files with 476 additions and 2 deletions
474
app/actions/websocket/posts.test.ts
Normal file
474
app/actions/websocket/posts.test.ts
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {DeviceEventEmitter} from 'react-native';
|
||||
|
||||
import {markChannelAsViewed, markChannelAsUnread, storeMyChannelsForTeam, updateLastPostAt} from '@actions/local/channel';
|
||||
import {addPostAcknowledgement, markPostAsDeleted, removePostAcknowledgement} from '@actions/local/post';
|
||||
import {updateThread} from '@actions/local/thread';
|
||||
import {fetchChannelStats, fetchMyChannel, type MyChannelsRequest} from '@actions/remote/channel';
|
||||
import {fetchPostAuthors} from '@actions/remote/post';
|
||||
import {fetchThread} from '@actions/remote/thread';
|
||||
import {fetchMissingProfilesByIds} from '@actions/remote/user';
|
||||
import {Events, Screens} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {PostsInChannelModel} from '@database/models/server';
|
||||
import {getChannelById, getMyChannel} from '@queries/servers/channel';
|
||||
import {getPostById} from '@queries/servers/post';
|
||||
import {getCurrentUserId, getCurrentChannelId} from '@queries/servers/system';
|
||||
import {getIsCRTEnabled} from '@queries/servers/thread';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import NavigationStore from '@store/navigation_store';
|
||||
import MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import {isTablet} from '@utils/helpers';
|
||||
import {shouldIgnorePost} from '@utils/post';
|
||||
|
||||
import {handleNewPostEvent, handlePostEdited, handlePostDeleted, handlePostUnread, handlePostAcknowledgementAdded, handlePostAcknowledgementRemoved} from './posts';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
import type ThreadModel from '@typings/database/models/servers/thread';
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
jest.mock('@queries/servers/post');
|
||||
jest.mock('@queries/servers/channel');
|
||||
jest.mock('@queries/servers/system');
|
||||
jest.mock('@queries/servers/thread');
|
||||
jest.mock('@actions/local/channel');
|
||||
jest.mock('@actions/local/post');
|
||||
jest.mock('@actions/local/thread');
|
||||
jest.mock('@actions/remote/channel');
|
||||
jest.mock('@actions/remote/post');
|
||||
jest.mock('@actions/remote/thread');
|
||||
jest.mock('@actions/remote/user');
|
||||
jest.mock('@utils/helpers');
|
||||
jest.mock('@utils/post', () => ({
|
||||
...jest.requireActual('@utils/post'),
|
||||
shouldIgnorePost: jest.fn(),
|
||||
}));
|
||||
|
||||
const serverUrl = 'baseHandler.test.com';
|
||||
|
||||
describe('WebSocket Post Actions', () => {
|
||||
let operator: ServerDataOperator;
|
||||
|
||||
const post = {id: 'post1', channel_id: 'channel1', user_id: 'user1', create_at: 12345, message: 'hello'} as Post;
|
||||
const postModels = [{channelId: post.channel_id, userId: post.user_id, message: post.message} as PostModel];
|
||||
const myChannelModel = {id: 'channel1', manuallyUnread: false, messageCount: 4, mentionsCount: 0, lastViewedAt: 1} as MyChannelModel;
|
||||
|
||||
const mockedGetPostById = jest.mocked(getPostById);
|
||||
const mockedUpdateLastPostAt = jest.mocked(updateLastPostAt);
|
||||
const mockedMarkChannelAsViewed = jest.mocked(markChannelAsViewed);
|
||||
const mockedGetCurrentUserId = jest.mocked(getCurrentUserId);
|
||||
const mockedGetCurrentChannelId = jest.mocked(getCurrentChannelId);
|
||||
const mockedFetchPostAuthors = jest.mocked(fetchPostAuthors);
|
||||
const mockedIsTablet = jest.mocked(isTablet);
|
||||
const mockedGetMyChannel = jest.mocked(getMyChannel);
|
||||
const mockedGetIsCRTEnabled = jest.mocked(getIsCRTEnabled);
|
||||
const mockedShouldIgnorePost = jest.mocked(shouldIgnorePost);
|
||||
const mockedFetchMyChannel = jest.mocked(fetchMyChannel);
|
||||
const mockedStoreMyChannelsForTeam = jest.mocked(storeMyChannelsForTeam);
|
||||
const mockedFetchChannelStats = jest.mocked(fetchChannelStats);
|
||||
const mockedGetChannelById = jest.mocked(getChannelById);
|
||||
const mockedMarkPostAsDeleted = jest.mocked(markPostAsDeleted);
|
||||
const mockedUpdateThread = jest.mocked(updateThread);
|
||||
const mockedFetchThread = jest.mocked(fetchThread);
|
||||
const mockedMarkChannelAsUnread = jest.mocked(markChannelAsUnread);
|
||||
const mockedAddPostAcknowledgement = jest.mocked(addPostAcknowledgement);
|
||||
const mockedFetchMissingProfilesByIds = jest.mocked(fetchMissingProfilesByIds);
|
||||
const mockedRemovePostAcknowledgement = jest.mocked(removePostAcknowledgement);
|
||||
|
||||
beforeEach(async () => {
|
||||
await DatabaseManager.init([serverUrl]);
|
||||
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('handleNewPostEvent', () => {
|
||||
const msg = {
|
||||
data: {
|
||||
post: JSON.stringify(post),
|
||||
mentions: ['user1'],
|
||||
},
|
||||
} as WebSocketMessage;
|
||||
|
||||
const mockedGetScreensInStack = jest.spyOn(NavigationStore, 'getScreensInStack');
|
||||
|
||||
mockedGetPostById.mockResolvedValue(undefined);
|
||||
mockedUpdateLastPostAt.mockResolvedValue({member: myChannelModel});
|
||||
mockedMarkChannelAsViewed.mockResolvedValue({member: myChannelModel});
|
||||
mockedGetCurrentUserId.mockResolvedValue('user1');
|
||||
mockedGetCurrentChannelId.mockResolvedValue('channel1');
|
||||
mockedFetchPostAuthors.mockResolvedValue({authors: []});
|
||||
mockedGetScreensInStack.mockReturnValue([Screens.CHANNEL]);
|
||||
mockedIsTablet.mockReturnValue(false);
|
||||
|
||||
it('should handle new post event - channel membership present', async () => {
|
||||
const userModel = {id: 'user1', username: 'username1'} as UserModel;
|
||||
const emitSpy = jest.spyOn(DeviceEventEmitter, 'emit');
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
jest.spyOn(operator, 'handlePosts').mockResolvedValue(postModels);
|
||||
jest.spyOn(operator, 'handleUsers').mockResolvedValue([userModel]);
|
||||
|
||||
mockedFetchPostAuthors.mockResolvedValueOnce({authors: [{id: 'user1', username: 'username1'} as UserProfile]});
|
||||
mockedGetMyChannel.mockResolvedValue(myChannelModel);
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(false);
|
||||
mockedShouldIgnorePost.mockReturnValue(false);
|
||||
|
||||
await handleNewPostEvent(serverUrl, msg);
|
||||
|
||||
expect(emitSpy).toHaveBeenCalledWith(Events.USER_STOP_TYPING, {
|
||||
channelId: 'channel1',
|
||||
rootId: undefined,
|
||||
userId: 'user1',
|
||||
now: expect.any(Number),
|
||||
});
|
||||
|
||||
expect(batchRecordsSpy).toHaveBeenCalledWith([userModel, {_preparedState: null, id: 'channel1', lastViewedAt: 1, manuallyUnread: false, mentionsCount: 0, messageCount: 4}, postModels[0]], 'handleNewPostEvent');
|
||||
});
|
||||
|
||||
it('should handle new post event - without channel membership present', async () => {
|
||||
const emitSpy = jest.spyOn(DeviceEventEmitter, 'emit');
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
jest.spyOn(operator, 'handlePosts').mockResolvedValue(postModels);
|
||||
|
||||
mockedGetMyChannel.mockResolvedValueOnce(undefined);
|
||||
mockedFetchMyChannel.mockResolvedValue({teamId: 'team1', memberships: [{user_id: 'user1', channel_id: 'channel1'}]} as MyChannelsRequest);
|
||||
mockedStoreMyChannelsForTeam.mockResolvedValue({models: [myChannelModel]});
|
||||
mockedGetMyChannel.mockResolvedValueOnce(myChannelModel);
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(false);
|
||||
mockedShouldIgnorePost.mockReturnValue(true);
|
||||
|
||||
await handleNewPostEvent(serverUrl, msg);
|
||||
|
||||
expect(emitSpy).toHaveBeenCalledWith(Events.USER_STOP_TYPING, {
|
||||
channelId: 'channel1',
|
||||
rootId: undefined,
|
||||
userId: 'user1',
|
||||
now: expect.any(Number),
|
||||
});
|
||||
|
||||
expect(batchRecordsSpy).toHaveBeenCalledWith(postModels, 'handleNewPostEvent');
|
||||
});
|
||||
|
||||
it('should handle new post event - CRT enabled, manually unread', async () => {
|
||||
const emitSpy = jest.spyOn(DeviceEventEmitter, 'emit');
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
jest.spyOn(operator, 'handlePosts').mockResolvedValue(postModels);
|
||||
|
||||
mockedGetMyChannel.mockResolvedValue({...myChannelModel, manuallyUnread: true} as MyChannelModel);
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(true);
|
||||
mockedShouldIgnorePost.mockReturnValue(false);
|
||||
mockedMarkChannelAsUnread.mockResolvedValue({member: myChannelModel});
|
||||
|
||||
await handleNewPostEvent(serverUrl, msg);
|
||||
|
||||
expect(emitSpy).toHaveBeenCalledWith(Events.USER_STOP_TYPING, {
|
||||
channelId: 'channel1',
|
||||
rootId: undefined,
|
||||
userId: 'user1',
|
||||
now: expect.any(Number),
|
||||
});
|
||||
|
||||
expect(batchRecordsSpy).toHaveBeenCalledWith([{_preparedState: null, id: 'channel1', lastViewedAt: 1, manuallyUnread: false, mentionsCount: 0, messageCount: 4}, postModels[0]], 'handleNewPostEvent');
|
||||
});
|
||||
|
||||
it('should handle new post event - out of order ws, CRT on, root id', async () => {
|
||||
const newPost = {...post, root_id: 'post2'} as Post;
|
||||
jest.spyOn(EphemeralStore, 'getLastPostWebsocketEvent').mockReturnValueOnce({deleted: true, post: newPost});
|
||||
const emitSpy = jest.spyOn(DeviceEventEmitter, 'emit');
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
jest.spyOn(operator, 'handlePosts').mockResolvedValue(postModels);
|
||||
|
||||
mockedGetMyChannel.mockResolvedValue(myChannelModel);
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(true);
|
||||
mockedShouldIgnorePost.mockReturnValue(false);
|
||||
|
||||
await handleNewPostEvent(serverUrl, {data: {post: JSON.stringify(newPost), mentions: []}} as WebSocketMessage);
|
||||
|
||||
expect(emitSpy).toHaveBeenCalledWith(Events.USER_STOP_TYPING, {
|
||||
channelId: 'channel1',
|
||||
rootId: 'post2',
|
||||
userId: 'user1',
|
||||
now: expect.any(Number),
|
||||
});
|
||||
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle new post event - from webhook and is tablet', async () => {
|
||||
const emitSpy = jest.spyOn(DeviceEventEmitter, 'emit');
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
jest.spyOn(operator, 'handlePosts').mockResolvedValue(postModels);
|
||||
|
||||
mockedGetMyChannel.mockResolvedValue(myChannelModel);
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(false);
|
||||
mockedShouldIgnorePost.mockReturnValue(false);
|
||||
mockedIsTablet.mockReturnValueOnce(true);
|
||||
mockedGetScreensInStack.mockReturnValue([]);
|
||||
|
||||
await handleNewPostEvent(serverUrl, {data: {post: JSON.stringify({...post, props: {from_webhook: 'true'}}), mentions: []}} as WebSocketMessage);
|
||||
|
||||
expect(mockedGetScreensInStack).toHaveBeenCalled();
|
||||
expect(emitSpy).toHaveBeenCalledWith(Events.USER_STOP_TYPING, {
|
||||
channelId: 'channel1',
|
||||
rootId: undefined,
|
||||
userId: 'user1',
|
||||
now: expect.any(Number),
|
||||
});
|
||||
|
||||
expect(batchRecordsSpy).toHaveBeenCalledWith([{_preparedState: null, id: 'channel1', lastViewedAt: 1, manuallyUnread: false, mentionsCount: 0, messageCount: 4}, postModels[0]], 'handleNewPostEvent');
|
||||
});
|
||||
|
||||
it('should handle new post event - no operator', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
await handleNewPostEvent('junk', msg);
|
||||
|
||||
expect(mockedGetCurrentUserId).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle new post event - existing post', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
mockedGetPostById.mockResolvedValueOnce(postModels[0]);
|
||||
|
||||
await handleNewPostEvent(serverUrl, msg);
|
||||
|
||||
expect(mockedGetIsCRTEnabled).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle new post event - malformed post data', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
mockedGetPostById.mockResolvedValueOnce(postModels[0]);
|
||||
|
||||
await handleNewPostEvent(serverUrl, {data: undefined} as WebSocketMessage);
|
||||
|
||||
expect(mockedGetCurrentUserId).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handlePostEdited', () => {
|
||||
const msg = {
|
||||
data: {
|
||||
post: JSON.stringify({id: 'post1', channel_id: 'channel1', user_id: 'user1', is_pinned: false}),
|
||||
},
|
||||
} as WebSocketMessage;
|
||||
|
||||
it('should handle post edited event', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
|
||||
mockedGetPostById.mockResolvedValue(postModels[0]);
|
||||
mockedFetchPostAuthors.mockResolvedValue({authors: []});
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(false);
|
||||
|
||||
await handlePostEdited(serverUrl, msg);
|
||||
|
||||
expect(mockedFetchChannelStats).toHaveBeenCalledWith(serverUrl, 'channel1');
|
||||
expect(batchRecordsSpy).toHaveBeenCalledWith([expect.any(PostsInChannelModel)], 'handlePostEdited');
|
||||
});
|
||||
|
||||
it('should handle post edited event - no operator', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
await handlePostEdited('junk', msg);
|
||||
|
||||
expect(mockedGetPostById).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle post edited event - malformed post data', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
mockedGetPostById.mockResolvedValueOnce(postModels[0]);
|
||||
|
||||
await handlePostEdited(serverUrl, {data: undefined} as WebSocketMessage);
|
||||
|
||||
expect(mockedGetPostById).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handlePostDeleted', () => {
|
||||
const deletedPost = {id: 'post1', channel_id: 'channel1', user_id: 'user1', root_id: 'root1', reply_count: 1};
|
||||
const msg = {
|
||||
data: {
|
||||
post: JSON.stringify(deletedPost),
|
||||
},
|
||||
} as WebSocketMessage;
|
||||
|
||||
const threadModel = {viewedAt: 1, id: 'thread1'} as ThreadModel;
|
||||
|
||||
it('should handle post deleted event', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(true);
|
||||
mockedGetPostById.mockResolvedValue(postModels[0]);
|
||||
mockedMarkPostAsDeleted.mockResolvedValue({model: postModels[0]});
|
||||
mockedUpdateThread.mockResolvedValue({model: threadModel});
|
||||
mockedGetChannelById.mockResolvedValue({id: 'channel1', teamId: 'team1'} as ChannelModel);
|
||||
|
||||
await handlePostDeleted(serverUrl, msg);
|
||||
|
||||
expect(mockedMarkPostAsDeleted).toHaveBeenCalledWith(serverUrl, expect.any(Object), true);
|
||||
expect(mockedUpdateThread).toHaveBeenCalledWith(serverUrl, 'root1', {reply_count: 0}, true);
|
||||
expect(mockedFetchThread).toHaveBeenCalledWith(serverUrl, 'team1', 'root1');
|
||||
|
||||
expect(batchRecordsSpy).toHaveBeenCalledWith([postModels[0], threadModel], 'handlePostDeleted');
|
||||
});
|
||||
|
||||
it('should handle post deleted event - missing thread and channel', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(true);
|
||||
mockedGetPostById.mockResolvedValue(postModels[0]);
|
||||
mockedMarkPostAsDeleted.mockResolvedValue({model: postModels[0]});
|
||||
mockedUpdateThread.mockResolvedValue({error: 'not found'});
|
||||
mockedGetChannelById.mockResolvedValue(undefined);
|
||||
|
||||
await handlePostDeleted(serverUrl, msg);
|
||||
|
||||
expect(mockedMarkPostAsDeleted).toHaveBeenCalledWith(serverUrl, expect.any(Object), true);
|
||||
expect(mockedUpdateThread).toHaveBeenCalledWith(serverUrl, 'root1', {reply_count: 0}, true);
|
||||
expect(mockedFetchThread).not.toHaveBeenCalled();
|
||||
|
||||
expect(batchRecordsSpy).toHaveBeenCalledWith(postModels, 'handlePostDeleted');
|
||||
});
|
||||
|
||||
it('should handle post deleted event - missing delete model and no root id', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords').mockImplementation(jest.fn());
|
||||
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(true);
|
||||
mockedGetPostById.mockResolvedValue(postModels[0]);
|
||||
mockedMarkPostAsDeleted.mockResolvedValue({error: 'not found'});
|
||||
|
||||
await handlePostDeleted(serverUrl, {data: {post: JSON.stringify({...deletedPost, root_id: ''})}} as WebSocketMessage);
|
||||
|
||||
expect(mockedMarkPostAsDeleted).toHaveBeenCalledWith(serverUrl, expect.any(Object), true);
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handlePostUnread', () => {
|
||||
const msg = {
|
||||
broadcast: {
|
||||
channel_id: 'channel1',
|
||||
team_id: 'team1',
|
||||
},
|
||||
data: {
|
||||
mention_count: 1,
|
||||
mention_count_root: 1,
|
||||
msg_count: 1,
|
||||
msg_count_root: 1,
|
||||
last_viewed_at: 12345,
|
||||
},
|
||||
} as WebSocketMessage;
|
||||
|
||||
it('should handle post unread event', async () => {
|
||||
mockedGetMyChannel.mockResolvedValue(myChannelModel);
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(false);
|
||||
mockedFetchMyChannel.mockResolvedValue({teamId: 'team1', memberships: [{user_id: 'user1', channel_id: 'channel1'}]} as MyChannelsRequest);
|
||||
mockedMarkChannelAsUnread.mockResolvedValue({member: myChannelModel});
|
||||
|
||||
await handlePostUnread(serverUrl, msg);
|
||||
|
||||
expect(mockedMarkChannelAsUnread).toHaveBeenCalledWith(serverUrl, 'channel1', 1, 1, 12345);
|
||||
});
|
||||
|
||||
it('should handle post unread event - CRT enabled, manually marked read', async () => {
|
||||
mockedGetMyChannel.mockResolvedValue({...myChannelModel, manuallyUnread: true} as MyChannelModel);
|
||||
mockedGetIsCRTEnabled.mockResolvedValue(true);
|
||||
mockedFetchMyChannel.mockResolvedValue({teamId: 'team1', memberships: [{user_id: 'user1', channel_id: 'channel1'}]} as MyChannelsRequest);
|
||||
mockedMarkChannelAsUnread.mockResolvedValue({member: myChannelModel});
|
||||
|
||||
await handlePostUnread(serverUrl, msg);
|
||||
|
||||
expect(mockedMarkChannelAsUnread).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle post unread event - no database', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
await handlePostUnread('junk', msg);
|
||||
|
||||
expect(mockedGetMyChannel).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handlePostAcknowledgementAdded', () => {
|
||||
const msg = {
|
||||
data: {
|
||||
acknowledgement: JSON.stringify({user_id: 'user1', post_id: 'post1', acknowledged_at: 12345}),
|
||||
},
|
||||
} as WebSocketMessage;
|
||||
|
||||
mockedGetCurrentUserId.mockResolvedValue('user1');
|
||||
|
||||
it('should handle post acknowledgement added event', async () => {
|
||||
jest.spyOn(EphemeralStore, 'isAcknowledgingPost').mockReturnValue(false);
|
||||
|
||||
await handlePostAcknowledgementAdded(serverUrl, msg);
|
||||
|
||||
expect(mockedAddPostAcknowledgement).toHaveBeenCalledWith(serverUrl, 'post1', 'user1', 12345);
|
||||
expect(mockedFetchMissingProfilesByIds).toHaveBeenCalledWith(serverUrl, ['user1']);
|
||||
});
|
||||
|
||||
it('should handle post acknowledgement added event - already acknowledging', async () => {
|
||||
jest.spyOn(EphemeralStore, 'isAcknowledgingPost').mockReturnValue(true);
|
||||
|
||||
await handlePostAcknowledgementAdded(serverUrl, msg);
|
||||
|
||||
expect(mockedAddPostAcknowledgement).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle post acknowledgement added event - no database', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
await handlePostAcknowledgementAdded('junk', msg);
|
||||
|
||||
expect(mockedGetCurrentUserId).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handlePostAcknowledgementRemoved', () => {
|
||||
const msg = {
|
||||
data: {
|
||||
acknowledgement: JSON.stringify({user_id: 'user1', post_id: 'post1'}),
|
||||
},
|
||||
} as WebSocketMessage;
|
||||
|
||||
mockedGetCurrentUserId.mockResolvedValue('user1');
|
||||
|
||||
it('should handle post acknowledgement removed event', async () => {
|
||||
jest.spyOn(EphemeralStore, 'isUnacknowledgingPost').mockReturnValue(false);
|
||||
|
||||
await handlePostAcknowledgementRemoved(serverUrl, msg);
|
||||
|
||||
expect(mockedRemovePostAcknowledgement).toHaveBeenCalledWith(serverUrl, 'post1', 'user1');
|
||||
});
|
||||
|
||||
it('should handle post acknowledgement added event - already unacknowledging', async () => {
|
||||
jest.spyOn(EphemeralStore, 'isUnacknowledgingPost').mockReturnValue(true);
|
||||
|
||||
await handlePostAcknowledgementRemoved(serverUrl, msg);
|
||||
|
||||
expect(mockedRemovePostAcknowledgement).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle post acknowledgement removed event - no database', async () => {
|
||||
const batchRecordsSpy = jest.spyOn(operator, 'batchRecords');
|
||||
|
||||
await handlePostAcknowledgementRemoved('junk', msg);
|
||||
|
||||
expect(mockedGetCurrentUserId).not.toHaveBeenCalled();
|
||||
expect(batchRecordsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -335,7 +335,7 @@ export async function handlePostAcknowledgementAdded(serverUrl: string, msg: Web
|
|||
if (!database) {
|
||||
return;
|
||||
}
|
||||
const currentUserId = getCurrentUserId(database);
|
||||
const currentUserId = await getCurrentUserId(database);
|
||||
if (EphemeralStore.isAcknowledgingPost(post_id) && currentUserId === user_id) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -355,7 +355,7 @@ export async function handlePostAcknowledgementRemoved(serverUrl: string, msg: W
|
|||
if (!database) {
|
||||
return;
|
||||
}
|
||||
const currentUserId = getCurrentUserId(database);
|
||||
const currentUserId = await getCurrentUserId(database);
|
||||
if (EphemeralStore.isUnacknowledgingPost(post_id) && currentUserId === user_id) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue