const workflowRoutes = require("../../../src/routes/workflow"); describe("Workflow Route Permissions", () => { const { listAllowedActionsForTask, parseTaskListQuery } = workflowRoutes.__testables; it("allows leave approvers to act on leave tasks", () => { const actions = listAllowedActionsForTask( { employee: { permissionCodes: ["leave.approve"] } }, { status: "pending", workflow_instance: { entity_type: "leave" }, }, true, ); expect(actions).toEqual(["approve", "reject", "return"]); }); it("does not allow expense approvers to act on leave tasks without leave.approve", () => { const actions = listAllowedActionsForTask( { employee: { permissionCodes: ["expense.approve"] } }, { status: "pending", workflow_instance: { entity_type: "leave" }, }, true, ); expect(actions).toEqual([]); }); it("allows procurement approvers to act on purchase tasks", () => { const actions = listAllowedActionsForTask( { employee: { permissionCodes: ["procurement.approve"] } }, { status: "pending", workflow_instance: { entity_type: "purchase_request" }, }, true, ); expect(actions).toEqual(["approve", "reject", "return"]); }); it("allows travel approvers to act on travel tasks", () => { const actions = listAllowedActionsForTask( { employee: { permissionCodes: ["travel.approve"] } }, { status: "pending", workflow_instance: { entity_type: "travel_request" }, }, true, ); expect(actions).toEqual(["approve", "reject", "return"]); }); it("allows transfer on approval tasks when actor also has expense.transfer", () => { const reimbursementActions = listAllowedActionsForTask( { employee: { permissionCodes: ["expense.approve", "expense.transfer"] } }, { status: "pending", workflow_instance: { entity_type: "reimbursement" }, }, true, ); const leaveActions = listAllowedActionsForTask( { employee: { permissionCodes: ["leave.approve", "expense.transfer"] } }, { status: "pending", workflow_instance: { entity_type: "leave" }, }, true, ); const purchaseActions = listAllowedActionsForTask( { employee: { permissionCodes: ["procurement.approve", "expense.transfer"] } }, { status: "pending", workflow_instance: { entity_type: "purchase_request" }, }, true, ); const travelActions = listAllowedActionsForTask( { employee: { permissionCodes: ["travel.approve", "expense.transfer"] } }, { status: "pending", workflow_instance: { entity_type: "travel_request" }, }, true, ); expect(reimbursementActions).toContain("transfer"); expect(leaveActions).toContain("transfer"); expect(purchaseActions).toContain("transfer"); expect(travelActions).toContain("transfer"); }); it("does not allow transfer without matching approve permission", () => { const actions = listAllowedActionsForTask( { employee: { permissionCodes: ["expense.transfer"] } }, { status: "pending", workflow_instance: { entity_type: "leave" }, }, true, ); expect(actions).toEqual([]); }); it("parses optional workflow entityType filter for PC approval center", () => { expect(parseTaskListQuery({ status: "pending", entityType: "purchase_request", page: "2" })).toMatchObject({ status: "pending", entityType: "purchase_request", page: 2, pageSize: 20, }); }); it("rejects unsupported workflow entityType filters", () => { expect(() => parseTaskListQuery({ entityType: "invoice_pool" })).toThrow("参数校验失败"); }); });