mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-06 05:22:04 +00:00
fix(work-orders): show evidence scan failures on uplift create
Rejected and timed-out scans throw UpliftEvidenceScanError so the create toast uses the client scan message instead of the generic fallback.
This commit is contained in:
parent
10137bd427
commit
6a575536c7
3 changed files with 60 additions and 3 deletions
|
|
@ -37,6 +37,13 @@ function scanFailureMessage(scanStatus: "Rejected" | "Timeout"): string {
|
|||
return "The evidence file is still being scanned. Try again in a moment.";
|
||||
}
|
||||
|
||||
export class UpliftEvidenceScanError extends Error {
|
||||
constructor(readonly outcome: "Rejected" | "Timeout") {
|
||||
super(scanFailureMessage(outcome));
|
||||
this.name = "UpliftEvidenceScanError";
|
||||
}
|
||||
}
|
||||
|
||||
async function waitForPassedScan(
|
||||
workOrderId: string | number,
|
||||
file: File,
|
||||
|
|
@ -51,11 +58,11 @@ async function waitForPassedScan(
|
|||
return uploaded.id;
|
||||
}
|
||||
if (document.scanStatus === "Rejected") {
|
||||
throw new Error(scanFailureMessage("Rejected"));
|
||||
throw new UpliftEvidenceScanError("Rejected");
|
||||
}
|
||||
await pause(POLL_INTERVAL_MS);
|
||||
}
|
||||
throw new Error(scanFailureMessage("Timeout"));
|
||||
throw new UpliftEvidenceScanError("Timeout");
|
||||
}
|
||||
|
||||
export async function submitWorkOrderUplift(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ import { isHTTPError, isNetworkError, isTimeoutError } from "ky";
|
|||
import { toast } from "react-toastify";
|
||||
import { mapHttpStatusToMessage, REQUEST_UPLIFTS_ROLE_DENIAL_MESSAGE } from "@/api/api-error";
|
||||
import { workOrderUpliftsApi } from "@/domain/work-orders/api/work-order-uplifts-api";
|
||||
import { submitWorkOrderUplift } from "@/domain/work-orders/use-cases/submit-work-order-uplift";
|
||||
import {
|
||||
submitWorkOrderUplift,
|
||||
UpliftEvidenceScanError,
|
||||
} from "@/domain/work-orders/use-cases/submit-work-order-uplift";
|
||||
import type {
|
||||
CreateWorkOrderUpliftInput,
|
||||
WorkOrderUplift,
|
||||
|
|
@ -33,6 +36,9 @@ function createUpliftErrorMessage(error: unknown): string {
|
|||
if (isNetworkError(error) || isTimeoutError(error)) {
|
||||
return error.message;
|
||||
}
|
||||
if (error instanceof UpliftEvidenceScanError) {
|
||||
return error.message;
|
||||
}
|
||||
return CREATE_UPLIFT_ERROR_FALLBACK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import { act, renderHook, waitFor } from "@testing-library/react";
|
||||
import type { ReactNode } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { workOrderUpliftsApi } from "@/domain/work-orders/api/work-order-uplifts-api";
|
||||
import { useCreateWorkOrderUplift } from "@/domain/work-orders/use-cases/use-work-order-uplifts";
|
||||
import { createTestQueryClient } from "@/test/test-utils";
|
||||
|
||||
vi.mock("react-toastify", () => ({
|
||||
toast: { error: vi.fn(), success: vi.fn() },
|
||||
}));
|
||||
|
||||
function wrapper({ children }: { children: ReactNode }) {
|
||||
return <QueryClientProvider client={createTestQueryClient()}>{children}</QueryClientProvider>;
|
||||
}
|
||||
|
||||
describe("useCreateWorkOrderUplift scan errors", () => {
|
||||
beforeEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
vi.mocked(toast.error).mockClear();
|
||||
});
|
||||
|
||||
it("shows the security-scan rejection message when evidence is rejected", async () => {
|
||||
vi.spyOn(workOrderUpliftsApi, "uploadEvidence").mockResolvedValue({
|
||||
id: 22,
|
||||
scanStatus: "Rejected",
|
||||
originalFileName: "quote.pdf",
|
||||
});
|
||||
const create = vi.spyOn(workOrderUpliftsApi, "create");
|
||||
const quote = new File(["%PDF"], "quote.pdf", { type: "application/pdf" });
|
||||
const { result } = renderHook(() => useCreateWorkOrderUplift(7), { wrapper });
|
||||
|
||||
act(() => {
|
||||
result.current.mutate({ amount: 25, notes: "Leak", files: [quote] });
|
||||
});
|
||||
|
||||
await waitFor(() => expect(toast.error).toHaveBeenCalledTimes(1));
|
||||
expect(vi.mocked(toast.error).mock.calls[0]?.[0]).toBe(
|
||||
"The evidence file was rejected by the security scan.",
|
||||
);
|
||||
expect(create).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue