R45 A2-A7 员工附件与培训证书管理
这个提交包含在:
@@ -21,6 +21,12 @@ async function buildApp({ permissionCodes = ["system.users"], stats } = {}) {
|
||||
{ id: "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb", name: "研发部" },
|
||||
]);
|
||||
const contractCount = vi.fn().mockResolvedValue(2);
|
||||
const certificateGroupBy = vi.fn().mockResolvedValue([
|
||||
{ employee_id: "emp-1" },
|
||||
{ employee_id: "emp-2" },
|
||||
{ employee_id: "emp-3" },
|
||||
]);
|
||||
const certificateCount = vi.fn().mockResolvedValue(4);
|
||||
|
||||
app.decorate("prisma", {
|
||||
employee: {
|
||||
@@ -36,6 +42,11 @@ async function buildApp({ permissionCodes = ["system.users"], stats } = {}) {
|
||||
count: stats?.employeeContractCount ?? contractCount,
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
employeeCertificate: {
|
||||
groupBy: stats?.employeeCertificateGroupBy ?? certificateGroupBy,
|
||||
count: stats?.employeeCertificateCount ?? certificateCount,
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
});
|
||||
app.decorate("authenticate", async (request) => {
|
||||
request.employee = {
|
||||
@@ -68,12 +79,12 @@ async function buildApp({ permissionCodes = ["system.users"], stats } = {}) {
|
||||
});
|
||||
|
||||
await app.register(employeesRoutes, { prefix: "/api" });
|
||||
return { app, employeeGroupBy, employeeCount, departmentFindMany, contractCount };
|
||||
return { app, employeeGroupBy, employeeCount, departmentFindMany, contractCount, certificateGroupBy, certificateCount };
|
||||
}
|
||||
|
||||
describe("employees stats route", () => {
|
||||
it("returns aggregated employee stats for read-only viewers", async () => {
|
||||
const { app, employeeGroupBy, employeeCount, departmentFindMany, contractCount } = await buildApp({
|
||||
const { app, employeeGroupBy, employeeCount, departmentFindMany, contractCount, certificateGroupBy, certificateCount } = await buildApp({
|
||||
permissionCodes: ["report.dashboard.view"],
|
||||
});
|
||||
|
||||
@@ -92,10 +103,18 @@ describe("employees stats route", () => {
|
||||
expect(payload.data.recentMovements.hires).toBe(3);
|
||||
expect(payload.data.recentMovements.departures).toBe(1);
|
||||
expect(payload.data.expiringContracts.count).toBe(2);
|
||||
expect(payload.data.certificateSummary).toEqual({
|
||||
dateFrom: payload.data.asOfDate,
|
||||
dateTo: expect.any(String),
|
||||
validHolderCount: 3,
|
||||
expiringSoonCount: 4,
|
||||
});
|
||||
expect(employeeGroupBy).toHaveBeenCalledTimes(2);
|
||||
expect(employeeCount).toHaveBeenCalledTimes(2);
|
||||
expect(departmentFindMany).toHaveBeenCalledTimes(1);
|
||||
expect(contractCount).toHaveBeenCalledTimes(1);
|
||||
expect(certificateGroupBy).toHaveBeenCalledTimes(1);
|
||||
expect(certificateCount).toHaveBeenCalledTimes(1);
|
||||
|
||||
await app.close();
|
||||
});
|
||||
|
||||
在新工单中引用
屏蔽一个用户