mirror of
https://github.com/Sea-Haven-Industries/seahaven-ap.git
synced 2026-10-07 16:18:53 +00:00
fix(frontend): sync approvals; fix invoice not-found query (AP-6)
Keep approvals inbox rows aligned when detail stubs transition status, and return null from useInvoice so missing ids hit the not-found UI instead of a query error.
This commit is contained in:
parent
532c0f7f85
commit
b00a3311f5
6 changed files with 44 additions and 3 deletions
|
|
@ -43,4 +43,10 @@ test.describe("invoice detail 3-pane shell", () => {
|
|||
await expect(page).toHaveURL(/\/invoices\/inv-/);
|
||||
await expect(page.getByTestId("invoice-document-viewer")).toBeVisible();
|
||||
});
|
||||
|
||||
test("unknown invoice id shows not-found warning", async ({ page }) => {
|
||||
await page.goto("/invoices/missing-invoice");
|
||||
await expect(page.getByTestId("invoice-not-found")).toBeVisible();
|
||||
await expect(page.getByTestId("invoice-document-viewer")).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
type MockInvoiceLine,
|
||||
type MockInvoiceStatus,
|
||||
} from "@/mocks";
|
||||
import { approvalQueryKeys } from "@/domain/approvals/query-keys";
|
||||
import { invoiceQueryKeys } from "@/domain/invoices/query-keys";
|
||||
|
||||
async function invalidateInvoiceQueries(
|
||||
|
|
@ -37,9 +38,9 @@ export function useInvoice(id: string | undefined) {
|
|||
queryKey: invoiceQueryKeys.detail(id ?? ""),
|
||||
queryFn: () => {
|
||||
if (!id) {
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
return getMockInvoice(id);
|
||||
return getMockInvoice(id) ?? null;
|
||||
},
|
||||
enabled: Boolean(id),
|
||||
});
|
||||
|
|
@ -117,6 +118,7 @@ export function useTransitionInvoiceStatus() {
|
|||
}) => Promise.resolve(transitionMockInvoiceStatus(id, status, activity)),
|
||||
onSuccess: async (_data, variables) => {
|
||||
await invalidateInvoiceQueries(queryClient, variables.id);
|
||||
await queryClient.invalidateQueries({ queryKey: approvalQueryKeys.all });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,23 @@ export function updateMockApprovalStatus(
|
|||
return { ...updated };
|
||||
}
|
||||
|
||||
/** Keep inbox rows aligned when invoice detail stubs transition status. */
|
||||
export function syncMockApprovalsForInvoice(
|
||||
invoiceId: string,
|
||||
status: MockApprovalStatus,
|
||||
): MockApprovalItem[] {
|
||||
const updated: MockApprovalItem[] = [];
|
||||
approvalStore = approvalStore.map((item) => {
|
||||
if (item.invoiceId !== invoiceId) {
|
||||
return item;
|
||||
}
|
||||
const next = { ...item, status };
|
||||
updated.push({ ...next });
|
||||
return next;
|
||||
});
|
||||
return updated;
|
||||
}
|
||||
|
||||
export function resetMockApprovals(): void {
|
||||
approvalStore = seedApprovals.map((item) => ({ ...item }));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,12 @@ describe("mocks module", () => {
|
|||
});
|
||||
expect(approved.status).toBe("approved");
|
||||
expect(approved.activity.some((entry) => entry.message === "Approved")).toBe(true);
|
||||
expect(getMockPendingApprovals().some((item) => item.invoiceId === "inv-2")).toBe(false);
|
||||
expect(getMockApprovals().find((item) => item.invoiceId === "inv-2")?.status).toBe("approved");
|
||||
});
|
||||
|
||||
it("returns undefined for unknown invoice ids", () => {
|
||||
expect(getMockInvoice("missing-invoice")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("switches mock session user", () => {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ export {
|
|||
getMockApprovals,
|
||||
getMockPendingApprovals,
|
||||
resetMockApprovals,
|
||||
syncMockApprovalsForInvoice,
|
||||
updateMockApprovalStatus,
|
||||
type MockApprovalItem,
|
||||
type MockApprovalStatus,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { syncMockApprovalsForInvoice } from "@/mocks/approvals";
|
||||
import { areMocksEnabled } from "@/mocks/env";
|
||||
|
||||
export type MockInvoiceStatus = "pending_approval" | "approved" | "scheduled" | "paid" | "rejected";
|
||||
|
|
@ -515,11 +516,19 @@ export function transitionMockInvoiceStatus(
|
|||
createdAt: activity.createdAt ?? new Date().toISOString(),
|
||||
};
|
||||
|
||||
return replaceInvoice(index, {
|
||||
const updated = replaceInvoice(index, {
|
||||
...current,
|
||||
status,
|
||||
activity: [...current.activity, nextActivity],
|
||||
});
|
||||
|
||||
if (status === "approved" || status === "rejected") {
|
||||
syncMockApprovalsForInvoice(id, status);
|
||||
} else if (status === "pending_approval") {
|
||||
syncMockApprovalsForInvoice(id, "pending");
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
/** Test helper to restore seed data between unit tests. */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue