const { DEFAULT_APPROVAL_RULES, DEFAULT_FEATURE_FLAGS, ENABLED_EXPENSE_TYPES, seedApprovalRules, seedExpenseTypes, seedFeatureFlags, } = require("../../../src/scripts/seed-config"); describe("default travel expense types", () => { it("keeps intercity bus tickets separate from the two travel allowances", () => { expect(ENABLED_EXPENSE_TYPES).toEqual( expect.arrayContaining([ expect.objectContaining({ code: "travel_bus", name: "大巴车票", category: "travel" }), expect.objectContaining({ code: "travel_meal", name: "伙食补助费", category: "travel" }), expect.objectContaining({ code: "travel_local_transport_allowance", name: "市内交通补助费", category: "travel", }), ]), ); const travelCodes = ENABLED_EXPENSE_TYPES.filter((item) => ["travel_bus", "travel_meal", "travel_local_transport_allowance"].includes(item.code), ); expect(travelCodes).toHaveLength(3); }); it("upserts the distinct travel types by stable code", async () => { const upsert = vi.fn().mockResolvedValue({}); await seedExpenseTypes({ expenseType: { upsert } }); for (const [code, name] of [ ["travel_bus", "大巴车票"], ["travel_meal", "伙食补助费"], ["travel_local_transport_allowance", "市内交通补助费"], ]) { expect(upsert).toHaveBeenCalledWith( expect.objectContaining({ where: { code }, update: expect.objectContaining({ name, enabled: true }), create: expect.objectContaining({ code, name, enabled: true }), }), ); } }); }); describe("small-team default reimbursement approval rules", () => { it("uses finance for every owner fallback and finance review node", () => { expect(DEFAULT_APPROVAL_RULES).toEqual([ expect.objectContaining({ name: "小额", level1_role: "manager", level2_role: "finance", level3_role: null, owner_self_fallback_role: "finance", }), expect.objectContaining({ name: "中额", level1_role: "manager", level2_role: "finance", level3_role: null, owner_self_fallback_role: "finance", }), expect.objectContaining({ name: "大额", level1_role: "manager", level2_role: "ceo", level3_role: "finance", owner_self_fallback_role: "finance", }), ]); }); it("preserves existing production approval rules instead of replacing them", async () => { const approvalRule = { count: vi.fn().mockResolvedValue(3), createMany: vi.fn(), deleteMany: vi.fn(), }; await expect(seedApprovalRules({ approvalRule })).resolves.toEqual({ created: 0, preserved: 3, }); expect(approvalRule.createMany).not.toHaveBeenCalled(); expect(approvalRule.deleteMany).not.toHaveBeenCalled(); }); it("creates the three defaults only for an empty approval-rule table", async () => { const approvalRule = { count: vi.fn().mockResolvedValue(0), createMany: vi.fn().mockResolvedValue({ count: 3 }), }; await expect(seedApprovalRules({ approvalRule })).resolves.toEqual({ created: 3, preserved: 0, }); expect(approvalRule.createMany).toHaveBeenCalledWith({ data: DEFAULT_APPROVAL_RULES.map((item) => ({ ...item, enabled: true, created_by: null, updated_by: null, })), }); }); }); describe("trialrun payment batch baseline", () => { it("creates payment_batch_v1 as globally enabled", () => { expect(DEFAULT_FEATURE_FLAGS).toContainEqual({ flag_key: "payment_batch_v1", override_mode: "force_on", rollout_type: "global", department_ids: [], note: "bootstrap default: force_on", }); }); it("preserves an existing payment flag instead of overwriting it", async () => { const create = vi.fn(async ({ data }) => { if (data.flag_key === "payment_batch_v1") { throw Object.assign(new Error("unique conflict"), { code: "P2002" }); } return data; }); const prisma = { featureFlag: { create } }; await expect(seedFeatureFlags(prisma)).resolves.toBeUndefined(); expect(create).toHaveBeenCalledWith({ data: expect.objectContaining({ flag_key: "payment_batch_v1", override_mode: "force_on", }), }); expect(prisma.featureFlag.update).toBeUndefined(); expect(prisma.featureFlag.upsert).toBeUndefined(); }); });