import { faker } from '@faker-js/faker'; import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatDepartment, IUser, LivechatDepartmentDTO } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; import { expect } from 'chai'; import { api, credentials, request } from '../api-data'; import { makeAgentAvailable } from './rooms'; import { createAgentAndReLogin, createAnAwayAgent, createAnOfflineAgent } from './users'; import type { WithRequiredProperty } from './utils'; const NewDepartmentData = ((): Partial => ({ enabled: true, name: `new department ${Random.id()}`, description: 'created from api', showOnRegistration: true, email: faker.internet.email(), showOnOfflineForm: true, }))(); export const createDepartment = async ( departmentData?: Partial, agents?: { agentId: string; count?: string; order?: string }[], ): Promise => { const department = { ...NewDepartmentData, ...departmentData }; const response = await request .post(api('livechat/department')) .set(credentials) .send({ department, ...(agents && { agents }), }) .expect(200); return response.body.department; }; const updateDepartment = async (departmentId: string, departmentData: Partial): Promise => { const response = await request .put(api(`livechat/department/${departmentId}`)) .set(credentials) .send({ department: departmentData, }) .expect(200); return response.body.department; }; export type OnlineAgent = { user: WithRequiredProperty; credentials: Credentials; }; export const createDepartmentWithAnOnlineAgent = async (): Promise<{ department: ILivechatDepartment; agent: OnlineAgent }> => { const { user, credentials: agentCredentials } = await createAgentAndReLogin(); const department = await createDepartment(); await addOrRemoveAgentFromDepartment(department._id, { agentId: user._id, username: user.username }, true); await makeAgentAvailable(agentCredentials); return { department, agent: { credentials: agentCredentials, user, }, }; }; export const createDepartmentWith2OnlineAgents = async (): Promise<{ department: ILivechatDepartment; agent1: OnlineAgent; agent2: OnlineAgent; }> => { const [agent1, agent2] = await Promise.all([createAgentAndReLogin(), createAgentAndReLogin()]); const department = await createDepartment( { enabled: true, name: Random.id(), showOnRegistration: true, email: `${Random.id()}@example.com`, showOnOfflineForm: true, }, [{ agentId: agent1.user._id }, { agentId: agent2.user._id }], ); await Promise.all([makeAgentAvailable(agent1.credentials), makeAgentAvailable(agent2.credentials)]); return { department, agent1, agent2, }; }; export const createDepartmentWithAgent = async (agent: OnlineAgent): Promise<{ department: ILivechatDepartment; agent: OnlineAgent }> => { const { user, credentials } = agent; const department = await createDepartment(); await addOrRemoveAgentFromDepartment(department._id, { agentId: user._id, username: user.username }, true); return { department, agent: { credentials, user, }, }; }; export const addOrRemoveAgentFromDepartment = async ( departmentId: string, agent: { agentId: string; username: string; count?: number; order?: number }, add: boolean, ) => { const response = await request .post(api(`livechat/department/${departmentId}/agents`)) .set(credentials) .send({ ...(add ? { upsert: [agent], remove: [] } : { remove: [agent], upsert: [] }), }); if (response.status !== 200) { throw new Error(`Failed to add or remove agent from department. Status code: ${response.status}\n${response.body}`); } }; export const createDepartmentWithAnOfflineAgent = async ({ allowReceiveForwardOffline = false, fallbackForwardDepartment, departmentsAllowedToForward, }: { allowReceiveForwardOffline?: boolean; fallbackForwardDepartment?: string; departmentsAllowedToForward?: string[]; }): Promise<{ department: ILivechatDepartment; agent: { credentials: Credentials; user: WithRequiredProperty; }; }> => { const { user, credentials } = await createAnOfflineAgent(); const department = (await createDepartment({ allowReceiveForwardOffline, fallbackForwardDepartment, departmentsAllowedToForward, })) as ILivechatDepartment; await addOrRemoveAgentFromDepartment(department._id, { agentId: user._id, username: user.username }, true); return { department, agent: { credentials, user, }, }; }; export const createDepartmentWithAnAwayAgent = async ({ allowReceiveForwardOffline = false, fallbackForwardDepartment, departmentsAllowedToForward, }: { allowReceiveForwardOffline?: boolean; fallbackForwardDepartment?: string; departmentsAllowedToForward?: string[]; }): Promise<{ department: ILivechatDepartment; agent: { credentials: Credentials; user: WithRequiredProperty; }; }> => { const { user, credentials } = await createAnAwayAgent(); const department = (await createDepartment({ allowReceiveForwardOffline, fallbackForwardDepartment, departmentsAllowedToForward, })) as ILivechatDepartment; await addOrRemoveAgentFromDepartment(department._id, { agentId: user._id, username: user.username }, true); return { department, agent: { credentials, user, }, }; }; export const archiveDepartment = async (departmentId: string): Promise => { await request .post(api(`livechat/department/${departmentId}/archive`)) .set(credentials) .expect(200); }; export const disableDepartment = async (department: Omit): Promise => { department.enabled = false; delete department._updatedAt; const updatedDepartment = await updateDepartment(department._id, department); expect(updatedDepartment.enabled).to.be.false; }; export const deleteDepartment = async (departmentId: string): Promise => { await request .delete(api(`livechat/department/${departmentId}`)) .set(credentials) .expect(200); }; export const getDepartmentById = async (departmentId: string): Promise => { const response = await request .get(api(`livechat/department/${departmentId}`)) .set(credentials) .expect(200); return response.body.department; };