Increase branch test coverage of actions/remote files (#8370)

* Increase branch test coverage for actions/remote/command

* Increase branch test coverage for actions/remote/session

* Increase branch test coverage for actions/remote/post
This commit is contained in:
Joram Wilander 2024-11-25 12:02:34 -05:00 committed by GitHub
parent 99383f265f
commit 71f1d99041
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 531 additions and 2 deletions

View file

@ -107,6 +107,15 @@ describe('executeCommand', () => {
expect(result).toEqual({error: 'invalid_url database not found'});
});
it('handle client error', async () => {
jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(() => {
throw error;
});
const result = await executeCommand(serverUrl, intl, message, channelId, rootId);
expect(result).toEqual({error});
});
it('handle apps enabled', async () => {
jest.spyOn(AppsManager, 'isAppsEnabled').mockResolvedValue(true);
const parser = {
@ -164,6 +173,34 @@ describe('executeCommand', () => {
expect(result).toEqual({data: {trigger_id: 'trigger_id'}});
});
it('handle /code command execution with successful response', async () => {
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
jest.spyOn(AppsManager, 'isAppsEnabled').mockResolvedValue(false);
const mockSetTriggerId = jest.fn();
jest.spyOn(IntegrationsManager, 'getManager').mockReturnValue({
setTriggerId: mockSetTriggerId,
} as any);
const result = await executeCommand(serverUrl, intl, '/code', channelId, rootId);
expect(mockClient.executeCommand).toHaveBeenCalledWith('/code ', args);
expect(mockSetTriggerId).toHaveBeenCalledWith('trigger_id');
expect(result).toEqual({data: {trigger_id: 'trigger_id'}});
});
it('handle command execution with no trigger id', async () => {
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
jest.spyOn(AppsManager, 'isAppsEnabled').mockResolvedValue(false);
mockClient.executeCommand.mockResolvedValueOnce({} as never);
const result = await executeCommand(serverUrl, intl, message, channelId, rootId);
expect(mockClient.executeCommand).toHaveBeenCalledWith(message, args);
expect(result).toEqual({data: {}});
});
it('handle command execution with error response', async () => {
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
@ -181,6 +218,16 @@ describe('executeCommand', () => {
describe('executeAppCommand', () => {
const msg = 'test message';
it('should handle a undefined creq', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({errorMessage: 'Error occurred'}),
};
const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args);
expect(result).toEqual({error: {message: 'Error occurred'}});
});
it('should handle a successful command execution with OK response', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}),
@ -196,6 +243,20 @@ describe('executeAppCommand', () => {
expect(result).toEqual({data: {}});
});
it('should handle OK response with no text', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}),
};
(AppCommandParser as jest.Mock).mockReturnValue(parser);
(doAppSubmit as jest.Mock).mockResolvedValue({data: {type: AppCallResponseTypes.OK}});
const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args);
expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg);
expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {}, intl);
expect(result).toEqual({data: {}});
});
it('should handle an error response', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}),
@ -210,6 +271,20 @@ describe('executeAppCommand', () => {
expect(result).toEqual({error: {message: 'Error occurred'}});
});
it('should handle an error response with no text', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}),
};
(AppCommandParser as jest.Mock).mockReturnValue(parser);
(doAppSubmit as jest.Mock).mockResolvedValue({error: {}});
const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args);
expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg);
expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {}, intl);
expect(result).toEqual({error: {message: 'Unknown error.'}});
});
it('should handle a form response', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {context: {}}, errorMessage: null}),
@ -225,6 +300,20 @@ describe('executeAppCommand', () => {
expect(result).toEqual({data: {}});
});
it('should handle a form response with no form', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {context: {}}, errorMessage: null}),
};
(AppCommandParser as jest.Mock).mockReturnValue(parser);
(doAppSubmit as jest.Mock).mockResolvedValue({data: {type: AppCallResponseTypes.FORM}});
const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args);
expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg);
expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {context: {}}, intl);
expect(result).toEqual({data: {}});
});
it('should handle a navigate response', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}),
@ -239,6 +328,20 @@ describe('executeAppCommand', () => {
expect(result).toEqual({data: {}});
});
it('should handle a navigate response with no url', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}),
};
(AppCommandParser as jest.Mock).mockReturnValue(parser);
(doAppSubmit as jest.Mock).mockResolvedValue({data: {type: AppCallResponseTypes.NAVIGATE}});
const result = await executeAppCommand(serverUrl, intl, parser as any, msg, args);
expect(parser.composeCommandSubmitCall).toHaveBeenCalledWith(msg);
expect(doAppSubmit).toHaveBeenCalledWith(serverUrl, {}, intl);
expect(result).toEqual({data: {}});
});
it('should handle an unknown response type', async () => {
const parser = {
composeCommandSubmitCall: jest.fn().mockResolvedValue({creq: {}, errorMessage: null}),

View file

@ -3,7 +3,7 @@
/* eslint-disable max-lines */
import {ActionType, Post} from '@constants';
import {ActionType, Post, ServerErrors} from '@constants';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import PostModel from '@database/models/server/post';
@ -121,6 +121,16 @@ jest.mock('@queries/servers/thread', () => {
};
});
let mockAddRecentReaction: jest.Mock;
jest.mock('@actions/local/reactions', () => {
const original = jest.requireActual('@actions/local/reactions');
mockAddRecentReaction = jest.fn(() => [{user_id: 'userid1', emoji_name: 'smile'}]);
return {
...original,
addRecentReaction: mockAddRecentReaction,
};
});
beforeAll(() => {
// eslint-disable-next-line
// @ts-ignore
@ -143,6 +153,28 @@ describe('create, update & delete posts', () => {
expect(result.error).toBeTruthy();
});
it('createPost - handle client error', async () => {
jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(throwFunc);
const result = await createPost(serverUrl, post1);
expect(result).toBeDefined();
expect(result.error).toBeTruthy();
});
it('createPost - handle existing failed post', async () => {
await operator.handlePosts({
actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL,
order: [post1.id],
posts: [{...post1, props: {failed: false}}],
prepareRecordsOnly: false,
});
const result = await createPost(serverUrl, {...post1, pending_post_id: post1.id});
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.data).toBe(false);
});
it('createPost - fail create', async () => {
mockClient.createPost.mockImplementationOnce(jest.fn(throwFunc));
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
@ -153,6 +185,45 @@ describe('create, update & delete posts', () => {
expect(result.data).toBeTruthy();
});
it('createPost - fail on deleted root post server error', async () => {
mockClient.createPost.mockImplementationOnce(jest.fn(() => {
// eslint-disable-next-line no-throw-literal
throw {message: 'error', server_error_id: ServerErrors.DELETED_ROOT_POST_ERROR};
}));
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await createPost(serverUrl, post1);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.data).toBeTruthy();
});
it('createPost - fail on town square read only server error', async () => {
mockClient.createPost.mockImplementationOnce(jest.fn(() => {
// eslint-disable-next-line no-throw-literal
throw {message: 'error', server_error_id: ServerErrors.TOWN_SQUARE_READ_ONLY_ERROR};
}));
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await createPost(serverUrl, post1);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.data).toBeTruthy();
});
it('createPost - fail on plugin dismissed post server error', async () => {
mockClient.createPost.mockImplementationOnce(jest.fn(() => {
// eslint-disable-next-line no-throw-literal
throw {message: 'error', server_error_id: ServerErrors.PLUGIN_DISMISSED_POST_ERROR};
}));
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await createPost(serverUrl, post1);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.data).toBeTruthy();
});
it('createPost - root', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
@ -162,6 +233,16 @@ describe('create, update & delete posts', () => {
expect(result.data).toBeTruthy();
});
it('createPost - without reactions', async () => {
mockAddRecentReaction.mockImplementationOnce(() => []);
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await createPost(serverUrl, post1);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.data).toBeTruthy();
});
it('createPost - reply', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
@ -177,6 +258,14 @@ describe('create, update & delete posts', () => {
expect(result.error).toBeTruthy();
});
it('retryFailedPost - handle client error', async () => {
jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(throwFunc);
const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1}));
expect(result).toBeDefined();
expect(result.error).toBeTruthy();
});
it('retryFailedPost - base case', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
@ -192,6 +281,42 @@ describe('create, update & delete posts', () => {
expect(result.error).toBeTruthy();
});
it('retryFailedPost - fail on deleted root post server error', async () => {
mockClient.createPost.mockImplementationOnce(jest.fn(() => {
// eslint-disable-next-line no-throw-literal
throw {message: 'error', server_error_id: ServerErrors.DELETED_ROOT_POST_ERROR};
}));
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1}));
expect(result).toBeDefined();
expect(result.error).toBeDefined();
});
it('retryFailedPost - fail on town square read only server error', async () => {
mockClient.createPost.mockImplementationOnce(jest.fn(() => {
// eslint-disable-next-line no-throw-literal
throw {message: 'error', server_error_id: ServerErrors.TOWN_SQUARE_READ_ONLY_ERROR};
}));
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1}));
expect(result).toBeDefined();
expect(result.error).toBeDefined();
});
it('retryFailedPost - fail on plugin dismissed post server error', async () => {
mockClient.createPost.mockImplementationOnce(jest.fn(() => {
// eslint-disable-next-line no-throw-literal
throw {message: 'error', server_error_id: ServerErrors.PLUGIN_DISMISSED_POST_ERROR};
}));
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await retryFailedPost(serverUrl, mockPostModel({id: post1.id, prepareUpdate: jest.fn(), toApi: async () => post1}));
expect(result).toBeDefined();
expect(result.error).toBeDefined();
});
it('togglePinPost - handle database not found', async () => {
const result = await togglePinPost('foo', '');
expect(result).toBeDefined();
@ -382,6 +507,65 @@ describe('get posts', () => {
expect(result.posts?.length).toBe(2);
});
it('fetchPostsForChannel - base case with since', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
await operator.handleMyChannel({channels: [{
id: channelId,
team_id: teamId,
total_msg_count: 0,
creator_id: user1.id,
} as Channel],
myChannels: [{
id: 'id',
channel_id: channelId,
user_id: user1.id,
msg_count: 0,
} as ChannelMembership],
prepareRecordsOnly: false});
await operator.handlePosts({
actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL,
order: [post1.id],
posts: [post1],
prepareRecordsOnly: false,
});
const result = await fetchPostsForChannel(serverUrl, channelId, true);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
});
it('fetchPostsForChannel - no posts with since', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
await operator.handleMyChannel({channels: [{
id: channelId,
team_id: teamId,
total_msg_count: 0,
creator_id: user1.id,
} as Channel],
myChannels: [{
id: 'id',
channel_id: channelId,
user_id: user1.id,
msg_count: 0,
} as ChannelMembership],
prepareRecordsOnly: false});
await operator.handlePosts({
actionType: ActionType.POSTS.RECEIVED_IN_CHANNEL,
order: [post1.id],
posts: [post1],
prepareRecordsOnly: false,
});
mockClient.getPostsSince.mockImplementationOnce(jest.fn(() => ({posts: {}, order: []})));
const result = await fetchPostsForChannel(serverUrl, channelId, true);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(0);
});
it('fetchPostsForChannel - request error', async () => {
mockClient.getPosts.mockImplementationOnce(jest.fn(throwFunc));
@ -419,8 +603,30 @@ describe('get posts', () => {
expect(result.posts?.length).toBe(2);
});
it('fetchPosts - no CRT', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockGetIsCRTEnabled.mockImplementationOnce(() => false);
const result = await fetchPosts(serverUrl, channelId);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
});
it('fetchPosts - no authors needed', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => []));
const result = await fetchPosts(serverUrl, channelId);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
});
it('fetchPostsBefore - handle database not found', async () => {
const result = await fetchPostsBefore('foo', '', '') as {error: unknown};
const result = await fetchPostsBefore('foo', '', '', 50, true) as {error: unknown};
expect(result).toBeDefined();
expect(result.error).toBeTruthy();
});
@ -438,6 +644,48 @@ describe('get posts', () => {
expect(result.posts?.length).toBe(2);
});
it('fetchPostsBefore - no CRT', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockGetIsCRTEnabled.mockImplementationOnce(() => false);
const result = await fetchPostsBefore(serverUrl, channelId, post1.id) as {
posts: Post[];
order: string[];
previousPostId: string | undefined;
};
expect(result).toBeDefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
});
it('fetchPostsBefore - no authors needed', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => []));
const result = await fetchPostsBefore(serverUrl, channelId, post1.id) as {
posts: Post[];
order: string[];
previousPostId: string | undefined;
};
expect(result).toBeDefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
});
it('fetchPostsBefore - no posts', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockClient.getPostsBefore.mockImplementationOnce(jest.fn(() => ({posts: {}, order: []})));
const result = await fetchPostsBefore(serverUrl, channelId, post1.id) as {
posts: Post[];
order: string[];
previousPostId: string | undefined;
};
expect(result).toBeDefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(0);
});
it('fetchPostsSince - handle database not found', async () => {
const result = await fetchPostsSince('foo', '', 0);
expect(result).toBeDefined();
@ -500,6 +748,40 @@ describe('get posts', () => {
expect(result.posts?.[1].id).toBe(reply1.id);
});
it('fetchPostThread - no CRT', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockGetIsCRTEnabled.mockImplementationOnce(() => false);
const result = await fetchPostThread(serverUrl, post1.id);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
expect(result.posts?.[0].id).toBe(post1.id);
expect(result.posts?.[1].id).toBe(reply1.id);
});
it('fetchPostThread - no authors needed', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => []));
const result = await fetchPostThread(serverUrl, post1.id);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
});
it('fetchPostThread - no posts', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockClient.getPostThread.mockImplementationOnce(jest.fn(() => ({posts: {}, order: []})));
const result = await fetchPostThread(serverUrl, post1.id);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(0);
});
it('fetchPostsAround - handle database not found', async () => {
const result = await fetchPostsAround('foo', '', '');
expect(result).toBeDefined();
@ -516,6 +798,28 @@ describe('get posts', () => {
expect(result.posts?.length).toBe(2);
});
it('fetchPostsAround - no CRT', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockGetIsCRTEnabled.mockImplementationOnce(() => false);
const result = await fetchPostsAround(serverUrl, channelId, post2.id, 100, true);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
});
it('fetchPostsAround - no authors needed', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => []));
const result = await fetchPostsAround(serverUrl, channelId, post2.id, 100, true);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.posts).toBeTruthy();
expect(result.posts?.length).toBe(2);
});
it('fetchMissingChannelsFromPosts - handle database not found', async () => {
const result = await fetchMissingChannelsFromPosts('foo', []);
expect(result).toBeDefined();
@ -548,6 +852,38 @@ describe('get posts', () => {
expect(result.post?.id).toBe(post2.id);
});
it('fetchPostById - no CRT', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockGetIsCRTEnabled.mockImplementationOnce(() => false);
const result = await fetchPostById(serverUrl, post2.id);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.post).toBeDefined();
expect(result.post?.id).toBe(post2.id);
});
it('fetchPostById - no authors needed', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
mockClient.getProfilesByIds.mockImplementationOnce(jest.fn(() => []));
const result = await fetchPostById(serverUrl, post2.id);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.post).toBeDefined();
expect(result.post?.id).toBe(post2.id);
});
it('fetchPostById - fetch only', async () => {
await operator.handleSystem({systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_USER_ID, value: user1.id}], prepareRecordsOnly: false});
const result = await fetchPostById(serverUrl, post2.id, true);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
expect(result.post).toBeDefined();
expect(result.post?.id).toBe(post2.id);
});
it('fetchSavedPosts - handle database not found', async () => {
const result = await fetchSavedPosts('foo');
expect(result).toBeDefined();

View file

@ -3,6 +3,8 @@
/* eslint-disable max-lines */
import {Platform} from 'react-native';
import {GLOBAL_IDENTIFIERS, SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import NetworkManager from '@managers/network_manager';
@ -12,6 +14,7 @@ import {
forceLogoutIfNecessary,
fetchSessions,
login,
logout,
cancelSessionNotification,
scheduleSessionNotification,
sendPasswordResetEmail,
@ -109,6 +112,13 @@ describe('sessions', () => {
expect(result.error).toBeDefined();
});
it('addPushProxyVerificationStateFromLogin - no verification', async () => {
mockGetPushProxyVerificationState.mockImplementationOnce(() => '');
const result = await addPushProxyVerificationStateFromLogin(serverUrl);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
});
it('addPushProxyVerificationStateFromLogin - base case', async () => {
const result = await addPushProxyVerificationStateFromLogin(serverUrl);
expect(result).toBeDefined();
@ -146,6 +156,13 @@ describe('sessions', () => {
expect(result).toBeUndefined();
});
it('fetchSessions - handle client error', async () => {
jest.spyOn(NetworkManager, 'getClient').mockImplementationOnce(throwFunc);
const result = await fetchSessions(serverUrl, user1.id);
expect(result).toBeUndefined();
});
it('fetchSessions - base case', async () => {
const result = await fetchSessions(serverUrl, user1.id);
expect(result).toBeDefined();
@ -168,6 +185,21 @@ describe('sessions', () => {
expect(result.failed).toBe(true);
});
it('login - handle throw after login request', async () => {
jest.spyOn(DatabaseManager, 'setActiveServerDatabase').mockImplementationOnce(throwFunc);
const result = await login(serverUrl, {config: {DiagnosticId: 'diagnosticid'}} as LoginArgs);
expect(result).toBeDefined();
expect(result.error).toBeDefined();
expect(result.failed).toBe(false);
});
it('logout - base case', async () => {
const result = await logout(serverUrl, true, true, true);
expect(result).toBeDefined();
expect(result.data).toBeDefined();
});
it('cancelSessionNotification - handle not found database', async () => {
const result = await cancelSessionNotification('foo');
expect(result).toBeDefined();
@ -192,6 +224,12 @@ describe('sessions', () => {
expect(result.error).toBeUndefined();
});
it('cancelSessionNotification - no expired session', async () => {
const result = await cancelSessionNotification(serverUrl);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
});
it('scheduleSessionNotification - handle not found database', async () => {
const result = await scheduleSessionNotification('foo');
expect(result).toBeDefined();
@ -216,6 +254,20 @@ describe('sessions', () => {
expect(result.error).toBeUndefined();
});
it('scheduleSessionNotification - no session', async () => {
mockClient.getSessions.mockImplementationOnce(() => []);
const result = await scheduleSessionNotification(serverUrl);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
});
it('scheduleSessionNotification - null sessions', async () => {
mockClient.getSessions.mockImplementationOnce(() => null as any);
const result = await scheduleSessionNotification(serverUrl);
expect(result).toBeDefined();
expect(result.error).toBeUndefined();
});
it('sendPasswordResetEmail - handle error', async () => {
mockClient.sendPasswordResetEmail.mockImplementationOnce(jest.fn(throwFunc));
const result = await sendPasswordResetEmail('foo', '');
@ -245,6 +297,15 @@ describe('sessions', () => {
expect(result.failed).toBe(false);
});
it('ssoLogin - handle throw after login request', async () => {
jest.spyOn(DatabaseManager, 'setActiveServerDatabase').mockImplementationOnce(throwFunc);
const result = await ssoLogin(serverUrl, 'servername', 'diagnosticid', 'authtoken', 'csrftoken');
expect(result).toBeDefined();
expect(result.error).toBeDefined();
expect(result.failed).toBe(false);
});
it('findSession - handle not found database', async () => {
const result = await findSession('foo', []);
expect(result).toBeUndefined();
@ -277,8 +338,35 @@ describe('sessions', () => {
expect(session).toBeDefined();
});
it('findSession - non-match device token', async () => {
await DatabaseManager.appDatabase?.operator.handleGlobal({
globals: [{id: GLOBAL_IDENTIFIERS.DEVICE_TOKEN, value: 'diffdeviceid'}],
prepareRecordsOnly: false,
});
const session = await findSession(serverUrl, [session1]);
expect(session).toBeDefined();
});
it('findSession - by csrf', async () => {
const session = await findSession(serverUrl, [session1]);
expect(session).toBeDefined();
});
it('findSession - no csrf token', async () => {
mockGetCSRFFromCookie.mockResolvedValueOnce('');
const session = await findSession(serverUrl, [session1]);
expect(session).toBeUndefined();
});
it('findSession - by os', async () => {
const session = await findSession(serverUrl, [{...session1, props: {os: Platform.OS, csrf: 'diffcsrfid'}}]);
expect(session).toBeDefined();
});
it('findSession - handle error', async () => {
jest.spyOn(DatabaseManager, 'getServerDatabaseAndOperator').mockImplementationOnce(throwFunc);
const result = await findSession(serverUrl, []);
expect(result).toBeUndefined();
});
});

View file

@ -149,6 +149,8 @@ export const logout = async (serverUrl: string, skipServerLogout = false, remove
if (!skipEvents) {
DeviceEventEmitter.emit(Events.SERVER_LOGOUT, {serverUrl, removeServer});
}
return {data: true};
};
export const cancelSessionNotification = async (serverUrl: string) => {