test(stock-orders): tighten total-value + edit-reset assertions

The total-value case now locates each cell by its column header so a
regression that swapped Ordered (R) and Received (R) would fail. The
edit-draft case now closes the modal after Edit and asserts
editPurchaseId resets to '', so a regression that leaked the id into
a subsequent 'New' click would fail.

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
SJCoetz 2026-08-03 15:18:39 +02:00
parent 760f088ec9
commit 18e1d97b6c

View file

@ -172,7 +172,7 @@ describe("StockOrdersTable — edit draft button", () => {
expect(screen.queryByTestId("edit-draft-button")).toBeNull();
});
it("clicking Edit opens the modal with editPurchaseId set to the row id", () => {
it("clicking Edit opens the modal with editPurchaseId set to the row id, and resets it on close", () => {
const rows = [
makeRow({ id: "po-abc", status: "draft", purchase_number: "PO26000001STK" }),
];
@ -180,9 +180,16 @@ describe("StockOrdersTable — edit draft button", () => {
const modal = screen.getByTestId("quick-draft-modal");
expect(modal.dataset.open).toBe("false");
expect(modal.dataset.editPurchaseId).toBe("");
fireEvent.click(screen.getByTestId("edit-draft-button"));
expect(modal.dataset.open).toBe("true");
expect(modal.dataset.editPurchaseId).toBe("po-abc");
// Closing the modal from edit mode must clear editPurchaseId so a
// subsequent "New" click doesn't inherit the stale id.
fireEvent.click(screen.getByTestId("quick-draft-modal-close"));
expect(modal.dataset.open).toBe("false");
expect(modal.dataset.editPurchaseId).toBe("");
});
});
@ -191,7 +198,7 @@ describe("StockOrdersTable — total value columns", () => {
cleanup();
});
it("renders ordered_value and received_value formatted as ZAR currency", () => {
it("renders ordered_value and received_value in the correct columns", () => {
const row = makeRow({
id: "po-1",
status: "draft",
@ -199,11 +206,36 @@ describe("StockOrdersTable — total value columns", () => {
});
row.ordered_value = 521;
row.received_value = 75;
render(<StockOrdersTable rows={[row]} currentStatus="" page={1} totalPages={1} />);
// formatCurrency uses Intl with en-ZA / ZAR — the exact glyph
// and spacing can vary by ICU version, so assert on the numeric
// parts instead.
expect(screen.getAllByText(/521/).length).toBeGreaterThan(0);
expect(screen.getAllByText(/75/).length).toBeGreaterThan(0);
// Locate each value cell by its column header so a swap regression
// would fail. The two `<TableHead>`s are siblings in the single
// header row inside the shadcn `<Table>`; the body row sits in a
// sibling `<tbody>` within the same `<table>`.
const orderedHeader = screen.getByRole("columnheader", { name: /ordered/i });
const receivedHeader = screen.getByRole("columnheader", { name: /received/i });
const headersRow = orderedHeader.closest("tr")!;
const headers = Array.from(headersRow.querySelectorAll("th"));
const orderedColIdx = headers.indexOf(orderedHeader as HTMLTableCellElement);
const receivedColIdx = headers.indexOf(receivedHeader as HTMLTableCellElement);
// The shadcn `<Table>` wraps the `<table>` in a `<div>`, so walk
// up to the `<table>` ancestor to safely reach the sibling
// `<tbody>` rather than relying on `.nextElementSibling`.
const table = orderedHeader.closest("table")!;
const bodyRow = table.querySelector("tbody > tr")!;
const bodyCells = Array.from(bodyRow.querySelectorAll("td"));
const orderedCell = bodyCells[orderedColIdx];
const receivedCell = bodyCells[receivedColIdx];
// formatCurrency uses Intl with en-ZA / ZAR — substring on the
// numeric part to stay ICU-version-tolerant. Assert each value
// is in its own column and not the other's.
expect(orderedCell).toHaveTextContent("521");
expect(orderedCell).not.toHaveTextContent("75");
expect(receivedCell).toHaveTextContent("75");
expect(receivedCell).not.toHaveTextContent("521");
});
});