diff --git a/src/components/orders-review-modal.test.tsx b/src/components/orders-review-modal.test.tsx
index 9db64ca..b6d2e35 100644
--- a/src/components/orders-review-modal.test.tsx
+++ b/src/components/orders-review-modal.test.tsx
@@ -5,19 +5,30 @@ vi.mock("@/components/ui/customer-search", () => ({
CustomerSearch: ({
onValueChange,
value,
+ customers,
}: {
onValueChange: (v: string) => void;
value: string;
customers: unknown[];
- }) => (
-
- ),
+ }) => {
+ // Surface the first non-selected customer's id as a data attribute
+ // so cascade tests can click it specifically. Falls back to
+ // "cust-new" when there's no other customer in the list.
+ const others = (customers as Array<{ id: string }>).filter(
+ (c) => c.id !== value,
+ );
+ const nextId = others[0]?.id ?? "cust-new";
+ return (
+
+ );
+ },
}));
vi.mock("sonner", () => ({
@@ -688,4 +699,73 @@ describe("OrdersReviewModal", () => {
expect(rekeyedRow?.getAttribute("data-pending-removal")).toBe("false");
});
});
+
+ describe("customer cascade (company + rep)", () => {
+ const expandedCustomerA: Customer = {
+ ...baseCustomer,
+ id: "cust-A",
+ customer: "Alice Anderson",
+ company: "comp-A",
+ expand: {
+ company: { ...baseCompany, id: "comp-A", company: "Atlas Corp" },
+ rep: { id: "user-1", name: "Riya Patel", email: "riya@atlas.test" },
+ },
+ };
+ const expandedCustomerB: Customer = {
+ ...baseCustomer,
+ id: "cust-B",
+ customer: "Bob Brown",
+ company: "comp-B",
+ expand: {
+ company: { ...baseCompany, id: "comp-B", company: "Beacon Ltd" },
+ rep: { id: "user-2", name: "Sam Jones", email: "sam@beacon.test" },
+ },
+ };
+
+ it("updates Company and Rep labels when the customer changes", () => {
+ const props = {
+ ...baseProps(),
+ customers: [expandedCustomerA, expandedCustomerB],
+ customer: expandedCustomerA,
+ order: { ...baseOrder, customer: "cust-A", company: "comp-A", rep: "Riya Patel" },
+ };
+ render();
+
+ // Baseline: Company and Rep show the persisted (A) values.
+ expect(screen.getByText("Atlas Corp")).toBeInTheDocument();
+ expect(screen.getByText("Riya Patel")).toBeInTheDocument();
+ expect(screen.queryByText("Beacon Ltd")).not.toBeInTheDocument();
+
+ // Pick customer B. The mock's data-next-id is computed from the
+ // customer list, so the click will pass cust-B.
+ fireEvent.click(screen.getByTestId("customer-search-mock"));
+
+ // Company and Rep should now reflect customer B's expands.
+ expect(screen.getByText("Beacon Ltd")).toBeInTheDocument();
+ expect(screen.getByText("Sam Jones")).toBeInTheDocument();
+ // The original A values are no longer in the labels.
+ expect(screen.queryByText("Atlas Corp")).not.toBeInTheDocument();
+ expect(screen.queryByText("Riya Patel")).not.toBeInTheDocument();
+ });
+
+ it("marks the modal dirty after a customer change cascades", () => {
+ const props = {
+ ...baseProps(),
+ customers: [expandedCustomerA, expandedCustomerB],
+ customer: expandedCustomerA,
+ order: { ...baseOrder, customer: "cust-A", company: "comp-A", rep: "Riya Patel" },
+ };
+ render();
+
+ // Find the Save button by accessible name. The modal's primary
+ // save action is the only one in the footer.
+ const saveBefore = screen.getByRole("button", { name: /save/i });
+ expect(saveBefore).toBeDisabled();
+
+ fireEvent.click(screen.getByTestId("customer-search-mock"));
+
+ const saveAfter = screen.getByRole("button", { name: /save/i });
+ expect(saveAfter).not.toBeDisabled();
+ });
+ });
});