From 0d95a320711eae3d7a46e126124ec51367b70cc3 Mon Sep 17 00:00:00 2001 From: Codex Review Integration Date: Wed, 16 Sep 2026 21:12:22 -0300 Subject: [PATCH] feat(uplifts): refresh work-order views after decisions (SH-214) --- .../uplifts/use-cases/use-uplift-actions.ts | 3 ++ .../uplifts/use-uplift-actions.test.tsx | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/test/domain/uplifts/use-uplift-actions.test.tsx diff --git a/src/domain/uplifts/use-cases/use-uplift-actions.ts b/src/domain/uplifts/use-cases/use-uplift-actions.ts index 3ffedc21..9dda66a7 100644 --- a/src/domain/uplifts/use-cases/use-uplift-actions.ts +++ b/src/domain/uplifts/use-cases/use-uplift-actions.ts @@ -26,6 +26,9 @@ function invalidateUpliftQueries( dispatchId?: string | number, ) { void queryClient.invalidateQueries({ queryKey: queryKeys.uplifts.all }); + // Queue decisions update the same uplift records rendered by Work Order views. + // Invalidate that shared cache even when the queue has no dispatch context. + void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.all }); if (dispatchId !== undefined && dispatchId !== "") { void queryClient.invalidateQueries({ queryKey: queryKeys.uplifts.forDispatch(dispatchId) }); void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.dispatch(dispatchId) }); diff --git a/src/test/domain/uplifts/use-uplift-actions.test.tsx b/src/test/domain/uplifts/use-uplift-actions.test.tsx new file mode 100644 index 00000000..ac37f8bf --- /dev/null +++ b/src/test/domain/uplifts/use-uplift-actions.test.tsx @@ -0,0 +1,48 @@ +import type { ReactNode } from "react"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { act, renderHook, waitFor } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; + +const approve = vi.fn(); + +vi.mock("@/domain/uplifts/api/uplifts-api", () => ({ + upliftsApi: { + approve: (...args: unknown[]) => approve(...args), + }, +})); + +vi.mock("react-toastify", () => ({ + toast: { error: vi.fn(), success: vi.fn(), warning: vi.fn() }, +})); + +import { useApproveUplift } from "@/domain/uplifts/use-cases/use-uplift-actions"; +import { queryKeys } from "@/infra/query-key/query-key"; + +function makeWrapper(client: QueryClient) { + return function Wrapper({ children }: { children: ReactNode }) { + return {children}; + }; +} + +describe("useApproveUplift", () => { + it("refreshes work-order views after a queue decision", async () => { + approve.mockResolvedValueOnce(undefined); + const client = new QueryClient({ + defaultOptions: { queries: { retry: false }, mutations: { retry: false } }, + }); + const invalidateSpy = vi.spyOn(client, "invalidateQueries"); + const { result } = renderHook(() => useApproveUplift(), { + wrapper: makeWrapper(client), + }); + + act(() => { + result.current.mutate({ id: 17 }); + }); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + + expect(approve).toHaveBeenCalledWith(17, undefined); + expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: queryKeys.uplifts.all }); + expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: queryKeys.workOrders.all }); + }); +});