import { describe, expect, it, vi } from 'vitest'; import { StaffService } from './staff.service.js'; import type { PrismaService } from '../prisma/prisma.service.js'; import { ErrorCodes } from '../common/error-codes.js'; import { runWithRequestContext } from '../common/context/request-context.js'; import type { RequestContext } from '../common/context/request-context.js'; const ctx: RequestContext = { tenantCode: 'T001', userId: 'u1', username: 'admin', super: false, dataScope: 'self', orgCode: null, orgCodes: [], }; const baseDto = { name: '张三', idCardNo: '530102199001011234', phone: '13800000000', jobType: 'nurse', workType: 'full', employStatus: 'on', }; function makeService(overrides: { findFirst?: ReturnType; create?: ReturnType } = {}) { const findFirst = overrides.findFirst ?? vi.fn().mockResolvedValue(null); const create = overrides.create ?? vi.fn().mockResolvedValue({ id: 's1', ...baseDto, tenantCode: 'T001' }); const prisma = { client: { staff: { findFirst, create } } }; return { service: new StaffService(prisma as unknown as PrismaService), findFirst, create }; } describe('StaffService', () => { it('create 自动注入 tenantCode/createdBy', async () => { const { service, create } = makeService(); await runWithRequestContext(ctx, () => service.createStaff(baseDto)); expect(create).toHaveBeenCalledWith({ data: { ...baseDto, tenantCode: 'T001', createdBy: 'u1' }, }); }); it('userId 已被占用时 create 抛 STAFF_USER_LINKED', async () => { const findFirst = vi.fn().mockResolvedValue({ id: 's-other', userId: 'u9' }); const create = vi.fn(); const { service } = makeService({ findFirst, create }); await expect( runWithRequestContext(ctx, () => service.createStaff({ ...baseDto, userId: 'u9' })), ).rejects.toMatchObject({ response: { code: ErrorCodes.STAFF_USER_LINKED } }); expect(findFirst).toHaveBeenCalledWith({ where: { userId: 'u9' } }); expect(create).not.toHaveBeenCalled(); }); it('userId 为空时不校验、直接创建', async () => { const findFirst = vi.fn(); const { service, create } = makeService({ findFirst }); await runWithRequestContext(ctx, () => service.createStaff(baseDto)); expect(findFirst).not.toHaveBeenCalled(); expect(create).toHaveBeenCalled(); }); });