2023-11-07 07:26:45 -08:00
|
|
|
import { CollaborationService } from '@/collaboration/collaboration.service';
|
|
|
|
import type { Logger } from '@/Logger';
|
2023-11-10 06:04:26 -08:00
|
|
|
import type { User } from '@db/entities/User';
|
2023-11-07 07:26:45 -08:00
|
|
|
import type { UserService } from '@/services/user.service';
|
|
|
|
import { CollaborationState } from '@/collaboration/collaboration.state';
|
|
|
|
import type { Push } from '@/push';
|
|
|
|
import type {
|
|
|
|
WorkflowClosedMessage,
|
|
|
|
WorkflowOpenedMessage,
|
|
|
|
} from '@/collaboration/collaboration.message';
|
2024-01-02 08:53:24 -08:00
|
|
|
import type { UserRepository } from '@/databases/repositories/user.repository';
|
|
|
|
import { mock } from 'jest-mock-extended';
|
2023-11-07 07:26:45 -08:00
|
|
|
|
|
|
|
describe('CollaborationService', () => {
|
|
|
|
let collaborationService: CollaborationService;
|
|
|
|
let mockLogger: Logger;
|
|
|
|
let mockUserService: jest.Mocked<UserService>;
|
2024-01-02 08:53:24 -08:00
|
|
|
let mockUserRepository: jest.Mocked<UserRepository>;
|
2023-11-07 07:26:45 -08:00
|
|
|
let state: CollaborationState;
|
|
|
|
let push: Push;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2024-01-02 08:53:24 -08:00
|
|
|
mockLogger = mock<Logger>();
|
|
|
|
mockUserService = mock<UserService>();
|
|
|
|
mockUserRepository = mock<UserRepository>();
|
|
|
|
push = mock<Push>();
|
2023-11-07 07:26:45 -08:00
|
|
|
state = new CollaborationState();
|
2024-01-02 08:53:24 -08:00
|
|
|
|
|
|
|
collaborationService = new CollaborationService(
|
|
|
|
mockLogger,
|
|
|
|
push,
|
|
|
|
state,
|
|
|
|
mockUserService,
|
|
|
|
mockUserRepository,
|
|
|
|
);
|
2023-11-07 07:26:45 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('workflow opened message', () => {
|
|
|
|
const userId = 'test-user';
|
|
|
|
const workflowId = 'test-workflow';
|
|
|
|
|
|
|
|
const message: WorkflowOpenedMessage = {
|
|
|
|
type: 'workflowOpened',
|
|
|
|
workflowId,
|
|
|
|
};
|
|
|
|
|
2024-05-31 05:06:13 -07:00
|
|
|
const expectActiveUsersChangedMessage = () => {
|
2023-11-07 07:26:45 -08:00
|
|
|
expect(push.sendToUsers).toHaveBeenCalledWith(
|
|
|
|
'activeWorkflowUsersChanged',
|
|
|
|
{
|
|
|
|
workflowId,
|
|
|
|
activeUsers: [
|
|
|
|
{
|
|
|
|
user: { id: userId },
|
|
|
|
lastSeen: expect.any(Date),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
[userId],
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
describe('user is not yet active', () => {
|
|
|
|
it('updates state correctly', async () => {
|
2024-01-02 08:53:24 -08:00
|
|
|
mockUserRepository.getByIds.mockResolvedValueOnce([{ id: userId } as User]);
|
2023-11-07 07:26:45 -08:00
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
|
|
|
expect(state.getActiveWorkflowUsers(workflowId)).toEqual([
|
|
|
|
{
|
|
|
|
lastSeen: expect.any(Date),
|
|
|
|
userId,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sends active workflow users changed message', async () => {
|
2024-01-02 08:53:24 -08:00
|
|
|
mockUserRepository.getByIds.mockResolvedValueOnce([{ id: userId } as User]);
|
2023-11-07 07:26:45 -08:00
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
2024-05-31 05:06:13 -07:00
|
|
|
expectActiveUsersChangedMessage();
|
2023-11-07 07:26:45 -08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('user is already active', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
state.addActiveWorkflowUser(workflowId, userId);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('updates state correctly', async () => {
|
2024-01-02 08:53:24 -08:00
|
|
|
mockUserRepository.getByIds.mockResolvedValueOnce([{ id: userId } as User]);
|
2023-11-07 07:26:45 -08:00
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
|
|
|
expect(state.getActiveWorkflowUsers(workflowId)).toEqual([
|
|
|
|
{
|
|
|
|
lastSeen: expect.any(Date),
|
|
|
|
userId,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sends active workflow users changed message', async () => {
|
2024-01-02 08:53:24 -08:00
|
|
|
mockUserRepository.getByIds.mockResolvedValueOnce([{ id: userId } as User]);
|
2023-11-07 07:26:45 -08:00
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
2024-05-31 05:06:13 -07:00
|
|
|
expectActiveUsersChangedMessage();
|
2023-11-07 07:26:45 -08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('workflow closed message', () => {
|
|
|
|
const userId = 'test-user';
|
|
|
|
const workflowId = 'test-workflow';
|
|
|
|
|
|
|
|
const message: WorkflowClosedMessage = {
|
|
|
|
type: 'workflowClosed',
|
|
|
|
workflowId,
|
|
|
|
};
|
|
|
|
|
|
|
|
describe('user is active', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
state.addActiveWorkflowUser(workflowId, userId);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('updates state correctly', async () => {
|
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
|
|
|
expect(state.getActiveWorkflowUsers(workflowId)).toEqual([]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not send active workflow users changed message', async () => {
|
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
|
|
|
expect(push.sendToUsers).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('user is not active', () => {
|
|
|
|
it('updates state correctly', async () => {
|
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
|
|
|
expect(state.getActiveWorkflowUsers(workflowId)).toEqual([]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not send active workflow users changed message', async () => {
|
|
|
|
await collaborationService.handleUserMessage(userId, message);
|
|
|
|
|
|
|
|
expect(push.sendToUsers).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|