mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 09:32:06 +00:00
fix(workorders): retry off-list saves on the conflict's current version
This commit is contained in:
parent
47cdca55c2
commit
3e849f47de
2 changed files with 47 additions and 0 deletions
|
|
@ -181,6 +181,9 @@ async function runPatchAndSyncDetail(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof BoardPatchPartialSaveError) {
|
if (error instanceof BoardPatchPartialSaveError) {
|
||||||
recordSavedRow(sync, id, error.partialRow);
|
recordSavedRow(sync, id, error.partialRow);
|
||||||
|
} else if (error instanceof BoardPatchConflictError && error.currentState) {
|
||||||
|
// A retry before the refetch lands must patch the server's current version.
|
||||||
|
recordSavedRow(sync, id, error.currentState);
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import type { ReactNode } from "react";
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { act, renderHook, waitFor } from "@testing-library/react";
|
import { act, renderHook, waitFor } from "@testing-library/react";
|
||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { BoardPatchConflictError } from "@/domain/work-orders/errors/board-patch-errors";
|
||||||
import type { WorkOrderBoardDetail } from "@/domain/work-orders/types/work-order-board-detail";
|
import type { WorkOrderBoardDetail } from "@/domain/work-orders/types/work-order-board-detail";
|
||||||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||||
import { queryKeys } from "@/infra/query-key/query-key";
|
import { queryKeys } from "@/infra/query-key/query-key";
|
||||||
|
|
@ -195,6 +196,49 @@ describe("useWorkOrderTableMutations for a work order outside the loaded list",
|
||||||
expect(patchBoardField.mock.calls[1][1]).toMatchObject({ workOrderVersion: "saved-1" });
|
expect(patchBoardField.mock.calls[1][1]).toMatchObject({ workOrderVersion: "saved-1" });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("retries an off-list save on the conflict's current version, not the stale panel row", async () => {
|
||||||
|
const client = makeClient();
|
||||||
|
client.setQueryData<WorkOrderBoardDetail>(queryKeys.workOrders.boardDetail(9), {
|
||||||
|
info: DETAIL_ROW,
|
||||||
|
} as WorkOrderBoardDetail);
|
||||||
|
patchBoardField.mockRejectedValueOnce(
|
||||||
|
new BoardPatchConflictError("Work order was modified.", {
|
||||||
|
...DETAIL_ROW,
|
||||||
|
rowVersion: "server-current",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const onRetrySuccess = vi.fn();
|
||||||
|
const onFirstError = vi.fn();
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useWorkOrderTableMutations({
|
||||||
|
onPatch: vi.fn(),
|
||||||
|
clearPatch: vi.fn(),
|
||||||
|
getRow: () => undefined,
|
||||||
|
}),
|
||||||
|
{ wrapper: makeWrapper(client) },
|
||||||
|
);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.patchField(
|
||||||
|
9,
|
||||||
|
{ dueDate: "2026-10-09" },
|
||||||
|
{ fallbackRow: DETAIL_ROW, onError: onFirstError },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitFor(() => expect(onFirstError).toHaveBeenCalled());
|
||||||
|
act(() => {
|
||||||
|
result.current.patchField(
|
||||||
|
9,
|
||||||
|
{ dueDate: "2026-10-09" },
|
||||||
|
{ fallbackRow: DETAIL_ROW, onSuccess: onRetrySuccess },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => expect(onRetrySuccess).toHaveBeenCalled());
|
||||||
|
expect(patchBoardField.mock.calls[1][1]).toMatchObject({ workOrderVersion: "server-current" });
|
||||||
|
});
|
||||||
|
|
||||||
it("prefers the table row when it still holds the work order", async () => {
|
it("prefers the table row when it still holds the work order", async () => {
|
||||||
const tableRow = { ...DETAIL_ROW, rowVersion: "table-version" };
|
const tableRow = { ...DETAIL_ROW, rowVersion: "table-version" };
|
||||||
const onSuccess = vi.fn();
|
const onSuccess = vi.fn();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue