Initial local backup snapshot
This commit is contained in:
commit
acd9e14ba5
367 changed files with 118038 additions and 0 deletions
143
server/materialReturnWorkflow.test.ts
Normal file
143
server/materialReturnWorkflow.test.ts
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("./db", () => ({
|
||||
getMaterialReturnFollowupByRequestId: vi.fn(),
|
||||
upsertMaterialReturnFollowup: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("./mailer", () => ({
|
||||
sendOperationalEmail: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("./materialReturnEmail", () => ({
|
||||
generateMaterialReturnReminderEmail: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("./materialReturnPdf", () => ({
|
||||
generateMaterialReturnStatementPdf: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("./logisticsSettings", () => ({
|
||||
getLogisticsSettings: vi.fn(),
|
||||
}));
|
||||
|
||||
import * as db from "./db";
|
||||
import { getLogisticsSettings } from "./logisticsSettings";
|
||||
import { scheduleMaterialReturnFollowup } from "./materialReturnWorkflow";
|
||||
|
||||
describe("scheduleMaterialReturnFollowup", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
vi.mocked(getLogisticsSettings).mockResolvedValue({
|
||||
materialReturnLeadDays: 4,
|
||||
materialReturnGraceDays: 3,
|
||||
inventory: {
|
||||
tente3x3: 12,
|
||||
chapiteau5x5: 10,
|
||||
podium: 1,
|
||||
autres: null,
|
||||
},
|
||||
replacementValues: {
|
||||
tente3x3: 0,
|
||||
chapiteau5x5: 0,
|
||||
podium: 0,
|
||||
autres: null,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps the standard expiry window for a fresh follow-up", async () => {
|
||||
vi.mocked(db.getMaterialReturnFollowupByRequestId).mockResolvedValue(undefined);
|
||||
vi.mocked(db.upsertMaterialReturnFollowup).mockResolvedValue(1);
|
||||
|
||||
const request = {
|
||||
id: 12,
|
||||
associationId: 3,
|
||||
formData: JSON.stringify({ dateRestitution: "2026-06-15" }),
|
||||
} as any;
|
||||
|
||||
await scheduleMaterialReturnFollowup({
|
||||
request,
|
||||
serviceLabel: "Service technique",
|
||||
recipientEmails: ["agent@example.com"],
|
||||
});
|
||||
|
||||
expect(db.upsertMaterialReturnFollowup).toHaveBeenCalledTimes(1);
|
||||
const payload = vi.mocked(db.upsertMaterialReturnFollowup).mock.calls[0]?.[1];
|
||||
expect(payload.status).toBe("planifie");
|
||||
expect(new Date(payload.uploadTokenExpiresAt).toISOString().startsWith("2026-06-18")).toBe(true);
|
||||
});
|
||||
|
||||
it("reactivates an expired upload window when the follow-up is reassigned", async () => {
|
||||
const expiredDate = new Date();
|
||||
expiredDate.setDate(expiredDate.getDate() - 2);
|
||||
expiredDate.setHours(23, 59, 59, 999);
|
||||
|
||||
vi.mocked(db.getMaterialReturnFollowupByRequestId).mockResolvedValue({
|
||||
id: 4,
|
||||
requestId: 12,
|
||||
associationId: 3,
|
||||
status: "en_cours",
|
||||
uploadToken: "existing-token",
|
||||
uploadTokenExpiresAt: expiredDate,
|
||||
} as any);
|
||||
vi.mocked(db.upsertMaterialReturnFollowup).mockResolvedValue(4);
|
||||
|
||||
const request = {
|
||||
id: 12,
|
||||
associationId: 3,
|
||||
formData: JSON.stringify({ dateRestitution: "2026-05-01" }),
|
||||
} as any;
|
||||
|
||||
await scheduleMaterialReturnFollowup({
|
||||
request,
|
||||
serviceLabel: "Service technique",
|
||||
recipientEmails: ["agent@example.com"],
|
||||
});
|
||||
|
||||
const payload = vi.mocked(db.upsertMaterialReturnFollowup).mock.calls[0]?.[1];
|
||||
expect(payload.uploadToken).toBe("existing-token");
|
||||
expect(new Date(payload.uploadTokenExpiresAt).getTime()).toBeGreaterThan(Date.now());
|
||||
expect(payload.status).toBe("planifie");
|
||||
});
|
||||
|
||||
it("generates a new token and a fresh upload window when reactivation is explicit", async () => {
|
||||
const futureExpiry = new Date("2026-06-18T23:59:59.999Z");
|
||||
|
||||
vi.mocked(db.getMaterialReturnFollowupByRequestId).mockResolvedValue({
|
||||
id: 4,
|
||||
requestId: 12,
|
||||
associationId: 3,
|
||||
status: "en_attente",
|
||||
uploadToken: "existing-token",
|
||||
uploadTokenExpiresAt: futureExpiry,
|
||||
} as any);
|
||||
vi.mocked(db.upsertMaterialReturnFollowup).mockResolvedValue(4);
|
||||
|
||||
const request = {
|
||||
id: 12,
|
||||
associationId: 3,
|
||||
formData: JSON.stringify({ dateRestitution: "2026-06-15" }),
|
||||
} as any;
|
||||
const reactivatedAt = new Date("2026-06-20T10:30:00.000Z");
|
||||
|
||||
await scheduleMaterialReturnFollowup({
|
||||
request,
|
||||
serviceLabel: "Service technique",
|
||||
recipientEmails: ["agent@example.com"],
|
||||
}, {
|
||||
forceNewToken: true,
|
||||
forceImmediateSendWindow: true,
|
||||
reactivatedByUserId: 9,
|
||||
reactivatedAt,
|
||||
reactivationReason: "Suivi rouvert",
|
||||
});
|
||||
|
||||
const payload = vi.mocked(db.upsertMaterialReturnFollowup).mock.calls[0]?.[1];
|
||||
expect(payload.uploadToken).not.toBe("existing-token");
|
||||
expect(new Date(payload.uploadTokenExpiresAt).getTime()).toBeGreaterThan(futureExpiry.getTime());
|
||||
expect(new Date(payload.uploadTokenExpiresAt).getTime()).toBeGreaterThan(reactivatedAt.getTime());
|
||||
expect(payload.reactivatedByUserId).toBe(9);
|
||||
expect(payload.reactivationReason).toBe("Suivi rouvert");
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue