mattermost-mobile/app/actions/websocket/group.test.ts
Joram Wilander 0663d39365
Add tests to index, group and users websocket actions (#8486)
* test: Add tests for websocket index actions

* test: Add tests for websocket group actions

* test: Add tests for websocket users actions

* Fix missing import in index.test.ts

* Fix type in test after main merge

* Fix tests after main merge

* Updates per review feedback

* Remove unused import
2025-01-17 14:25:12 -05:00

262 lines
9.5 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {fetchGroupsForChannel, fetchGroupsForMember, fetchGroupsForTeam} from '@actions/remote/groups';
import DatabaseManager from '@database/manager';
import {deleteGroupChannelById, deleteGroupMembershipById, deleteGroupTeamById} from '@queries/servers/group';
import {generateGroupAssociationId} from '@utils/groups';
import {
handleGroupReceivedEvent,
handleGroupMemberAddEvent,
handleGroupMemberDeleteEvent,
handleGroupTeamAssociatedEvent,
handleGroupTeamDissociateEvent,
handleGroupChannelAssociatedEvent,
handleGroupChannelDissociateEvent,
} from './group';
jest.mock('@actions/remote/groups');
jest.mock('@database/manager');
jest.mock('@queries/servers/group');
jest.mock('@utils/groups');
jest.mock('@utils/log');
describe('WebSocket Group Actions', () => {
const serverUrl = 'baseHandler.test.com';
const groupId = 'group-id';
const userId = 'user-id';
const teamId = 'team-id';
const channelId = 'channel-id';
beforeEach(async () => {
jest.clearAllMocks();
await DatabaseManager.init([serverUrl]);
DatabaseManager.serverDatabases[serverUrl] = {
operator: {
handleGroups: jest.fn(),
handleGroupMembershipsForMember: jest.fn(),
handleGroupTeamsForTeam: jest.fn(),
handleGroupChannelsForChannel: jest.fn(),
},
} as any;
DatabaseManager.getServerDatabaseAndOperator = jest.fn().mockReturnValue({
database: {},
operator: {
handleGroups: jest.fn(),
handleGroupMembershipsForMember: jest.fn(),
handleGroupTeamsForTeam: jest.fn(),
handleGroupChannelsForChannel: jest.fn(),
},
});
});
describe('handleGroupReceivedEvent', () => {
it('should handle group received successfully', async () => {
const msg = {
data: {
group: JSON.stringify({id: groupId}),
},
} as WebSocketMessage;
await handleGroupReceivedEvent(serverUrl, msg);
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
expect(operator.handleGroups).toHaveBeenCalledWith({
groups: [{id: groupId}],
prepareRecordsOnly: false,
});
});
});
describe('handleGroupMemberAddEvent', () => {
it('should handle group member add successfully', async () => {
const msg = {
data: {
group_member: JSON.stringify({
group_id: groupId,
user_id: userId,
}),
},
} as WebSocketMessage;
await handleGroupMemberAddEvent(serverUrl, msg);
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
expect(operator.handleGroupMembershipsForMember).toHaveBeenCalledWith({
userId,
groups: [{id: groupId}],
prepareRecordsOnly: false,
});
});
});
describe('handleGroupMemberDeleteEvent', () => {
it('should handle group member delete successfully', async () => {
const msg = {
data: {
group_member: JSON.stringify({
group_id: groupId,
user_id: userId,
}),
},
} as WebSocketMessage;
jest.mocked(generateGroupAssociationId).mockReturnValue('association-id');
await handleGroupMemberDeleteEvent(serverUrl, msg);
const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
expect(deleteGroupMembershipById).toHaveBeenCalledWith(database, 'association-id');
});
});
describe('handleGroupTeamAssociatedEvent', () => {
it('should handle group team association successfully', async () => {
const msg = {
data: {
group_team: JSON.stringify({
group_id: groupId,
team_id: teamId,
}),
},
} as WebSocketMessage;
await handleGroupTeamAssociatedEvent(serverUrl, msg);
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
expect(operator.handleGroupTeamsForTeam).toHaveBeenCalledWith({
teamId,
groups: [{id: groupId}],
prepareRecordsOnly: false,
});
});
});
describe('handleGroupTeamDissociateEvent', () => {
it('should handle group team dissociation successfully', async () => {
const msg = {
data: {
group_team: JSON.stringify({
group_id: groupId,
team_id: teamId,
}),
},
} as WebSocketMessage;
jest.mocked(generateGroupAssociationId).mockReturnValue('association-id');
await handleGroupTeamDissociateEvent(serverUrl, msg);
const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
expect(deleteGroupTeamById).toHaveBeenCalledWith(database, 'association-id');
});
});
describe('handleGroupChannelAssociatedEvent', () => {
it('should handle group channel association successfully', async () => {
const msg = {
data: {
group_channel: JSON.stringify({
group_id: groupId,
channel_id: channelId,
}),
},
} as WebSocketMessage;
await handleGroupChannelAssociatedEvent(serverUrl, msg);
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
expect(operator.handleGroupChannelsForChannel).toHaveBeenCalledWith({
channelId,
groups: [{id: groupId}],
prepareRecordsOnly: false,
});
});
});
describe('handleGroupChannelDissociateEvent', () => {
it('should handle group channel dissociation successfully', async () => {
const msg = {
data: {
group_channel: JSON.stringify({
group_id: groupId,
channel_id: channelId,
}),
},
} as WebSocketMessage;
jest.mocked(generateGroupAssociationId).mockReturnValue('association-id');
await handleGroupChannelDissociateEvent(serverUrl, msg);
const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
expect(deleteGroupChannelById).toHaveBeenCalledWith(database, 'association-id');
});
});
describe('error handling', () => {
it('should handle errors and fetch groups on failure', async () => {
const msg = {
broadcast: {
team_id: teamId,
channel_id: channelId,
user_id: userId,
},
data: {
group: 'invalid json',
},
} as WebSocketMessage;
await handleGroupReceivedEvent(serverUrl, msg);
expect(fetchGroupsForTeam).toHaveBeenCalledWith(serverUrl, teamId);
expect(fetchGroupsForChannel).toHaveBeenCalledWith(serverUrl, channelId);
expect(fetchGroupsForMember).toHaveBeenCalledWith(serverUrl, userId);
});
it('should handle invalid json on all events', async () => {
const msg = {
broadcast: {
team_id: teamId,
},
data: {
group: 'invalid json',
group_member: 'invalid json',
group_team: 'invalid json',
group_channel: 'invalid json',
},
} as WebSocketMessage;
await handleGroupReceivedEvent(serverUrl, msg);
await handleGroupMemberAddEvent(serverUrl, msg);
await handleGroupMemberDeleteEvent(serverUrl, msg);
await handleGroupTeamAssociatedEvent(serverUrl, msg);
await handleGroupTeamDissociateEvent(serverUrl, msg);
await handleGroupChannelAssociatedEvent(serverUrl, msg);
await handleGroupChannelDissociateEvent(serverUrl, msg);
expect(fetchGroupsForTeam).toHaveBeenCalledWith(serverUrl, teamId);
expect(fetchGroupsForTeam).toHaveBeenCalledTimes(7);
});
it('should handle missing data', async () => {
const msg = {
broadcast: {
team_id: teamId,
},
data: {},
} as WebSocketMessage;
await handleGroupReceivedEvent(serverUrl, msg);
await handleGroupMemberAddEvent(serverUrl, msg);
await handleGroupMemberDeleteEvent(serverUrl, msg);
await handleGroupTeamAssociatedEvent(serverUrl, msg);
await handleGroupTeamDissociateEvent(serverUrl, msg);
await handleGroupChannelAssociatedEvent(serverUrl, msg);
await handleGroupChannelDissociateEvent(serverUrl, msg);
expect(DatabaseManager.getServerDatabaseAndOperator).not.toHaveBeenCalled();
});
});
});