Skip to content

Commit 84829c4

Browse files
committed
fix(e2e): stabilise submit mutation + campaign stats disclosure locator
- \`declaration.submit\`: replace the \`sql\`COALESCE(...)\`\` template with a straight select-then-update. The tagged-template form hung the submit mutation on the CI e2e env (compliance / declaration step 6 / fileUpload flows all timed out waiting for post-submit navigation). The new form is simpler and matches how the rest of the router reads + writes. - Admin stats e2e: wait for the chart figure before opening the disclosure, and target the \`<summary>\` via CSS since Chromium's ARIA tree for \`<details>/<summary>\` varies and \`getByRole('button')\` was timing out.
1 parent 5a99609 commit 84829c4

3 files changed

Lines changed: 33 additions & 20 deletions

File tree

packages/app/src/e2e/admin-stats-campagne.e2e.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,17 @@ test.describe("admin campaign progression stats", () => {
6565
test("accessible alternative table lists the same data", async ({ page }) => {
6666
await page.goto("/admin/stats/campagne");
6767

68-
await page
69-
.getByRole("group", { name: /^années à comparer/i })
70-
.getByRole("checkbox", { name: "2024" })
71-
.check()
72-
.catch(() => {
73-
/* already checked by default selection */
74-
});
68+
// Wait for the chart to be rendered — the table renders next to it only
69+
// once the tRPC query resolves.
70+
await expect(
71+
page.getByRole("figure", { name: /courbe de progression cumulative/i }),
72+
).toBeVisible();
7573

74+
// The table lives inside a <details> disclosure — use the summary text
75+
// directly rather than a role match (varies across browsers).
7676
await page
77-
.getByRole("button", {
78-
name: /consulter les données du graphique sous forme de tableau/i,
77+
.locator("summary", {
78+
hasText: /consulter les données du graphique sous forme de tableau/i,
7979
})
8080
.click();
8181

packages/app/src/server/api/routers/__tests__/declaration.test.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -268,18 +268,25 @@ describe("declarationRouter", () => {
268268
);
269269
});
270270

271-
it("sets submittedAt via COALESCE so resubmits preserve the first date", async () => {
272-
const mockDb = createMockDb();
271+
it("keeps the existing submittedAt when one is already present", async () => {
272+
const firstSubmission = new Date("2024-01-15T09:00:00Z");
273+
const mockDb = createMockDb([{ submittedAt: firstSubmission }]);
273274
const caller = await createCaller(mockDb);
274275

275276
await caller.submit();
276277

277278
const call = mockSet.mock.calls[0]?.[0] as Record<string, unknown>;
278-
expect(call).toHaveProperty("submittedAt");
279-
// Drizzle `sql` tag produces an SQL object with a queryChunks array.
280-
expect(call.submittedAt).toMatchObject({
281-
queryChunks: expect.any(Array),
282-
});
279+
expect(call.submittedAt).toBe(firstSubmission);
280+
});
281+
282+
it("stamps submittedAt with now when the row has never been submitted", async () => {
283+
const mockDb = createMockDb([{ submittedAt: null }]);
284+
const caller = await createCaller(mockDb);
285+
286+
await caller.submit();
287+
288+
const call = mockSet.mock.calls[0]?.[0] as Record<string, unknown>;
289+
expect(call.submittedAt).toBeInstanceOf(Date);
283290
});
284291

285292
it("throws when siret is missing", async () => {

packages/app/src/server/api/routers/declaration.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { TRPCError } from "@trpc/server";
2-
import { and, eq, isNull, sql } from "drizzle-orm";
2+
import { and, eq, isNull } from "drizzle-orm";
33
import {
44
saveCompliancePathSchema,
55
updateEmployeeCategoriesSchema,
@@ -454,14 +454,20 @@ export const declarationRouter = createTRPCRouter({
454454
const year = getCurrentYear();
455455
const now = new Date();
456456

457+
// Preserve the very first submission date — resubmissions after
458+
// corrections must not move the campaign progression curve.
459+
const [existing] = await ctx.db
460+
.select({ submittedAt: declarations.submittedAt })
461+
.from(declarations)
462+
.where(and(eq(declarations.siren, siren), eq(declarations.year, year)))
463+
.limit(1);
464+
457465
await ctx.db
458466
.update(declarations)
459467
.set({
460468
status: "submitted",
461469
currentStep: 6,
462-
// Preserve the very first submission date — resubmissions after
463-
// corrections must not move the campaign progression curve.
464-
submittedAt: sql`COALESCE(${declarations.submittedAt}, ${now})`,
470+
submittedAt: existing?.submittedAt ?? now,
465471
updatedAt: now,
466472
})
467473
.where(and(eq(declarations.siren, siren), eq(declarations.year, year)));

0 commit comments

Comments
 (0)