fix: allowlist uplift denial message

This commit is contained in:
Alexandre Brandizzi 2026-09-22 23:23:52 -03:00
parent c472ce2a91
commit c6e2704175
2 changed files with 51 additions and 21 deletions

View file

@ -15,6 +15,8 @@ import {
} from "@/app/v/[token]/dispatch/_components/use-uplift-evidence";
const ACTIVE_STATUSES = new Set(["Pending", "ChangesRequested"]);
const UPLIFT_REQUEST_PERMISSION_DENIAL = "Your role can't request uplifts on this work order.";
const UPLIFT_REQUEST_ERROR_FALLBACK = "Unable to request the NTE uplift. Please try again.";
type UpliftRequestsSectionProps = {
token: string;
@ -41,6 +43,12 @@ function scanErrorMessage(scan: EvidenceScanState): string {
return "Security scan timed out. Please try again once the file finishes scanning.";
}
function mapUpliftRequestError(error: unknown): string {
return error instanceof Error && error.message === UPLIFT_REQUEST_PERMISSION_DENIAL
? UPLIFT_REQUEST_PERMISSION_DENIAL
: UPLIFT_REQUEST_ERROR_FALLBACK;
}
function useVendorUpliftActions({
token,
dispatchId,
@ -97,11 +105,7 @@ function useVendorUpliftActions({
setInfoMessage("No approval required — the existing NTE already covers this amount.");
}
} catch (error) {
setFormError(
error instanceof Error && error.message
? error.message
: "Unable to request the NTE uplift. Please try again.",
);
setFormError(mapUpliftRequestError(error));
} finally {
setSubmitting(false);
}

View file

@ -8,6 +8,26 @@ afterEach(() => {
vi.restoreAllMocks();
});
function renderCreateForm() {
renderWithProviders(
<UpliftRequestsSection
token="portal-token"
dispatchId={7}
currentNte={100}
upliftRequests={[]}
locked={false}
onChanged={vi.fn()}
pollDocument={vi.fn(async () => undefined)}
/>,
{ withAuth: false },
);
}
function submitCreateForm() {
fireEvent.change(screen.getByLabelText("New total NTE"), { target: { value: "100" } });
fireEvent.click(screen.getByRole("button", { name: "Request uplift" }));
}
describe("UpliftRequestsSection create workflow", () => {
it("renders the server denial message when requestUplifts is denied", async () => {
const denialMessage = "Your role can't request uplifts on this work order.";
@ -18,26 +38,32 @@ describe("UpliftRequestsSection create workflow", () => {
}),
);
renderWithProviders(
<UpliftRequestsSection
token="portal-token"
dispatchId={7}
currentNte={100}
upliftRequests={[]}
locked={false}
onChanged={vi.fn()}
pollDocument={vi.fn(async () => undefined)}
/>,
{ withAuth: false },
);
renderCreateForm();
submitCreateForm();
fireEvent.change(screen.getByLabelText("New total NTE"), { target: { value: "100" } });
fireEvent.click(screen.getByRole("button", { name: "Request uplift" }));
await waitFor(() => expect(screen.getByRole("alert")).toHaveTextContent(denialMessage));
await waitFor(() => expect(screen.getByRole("alert").textContent).toBe(denialMessage));
expect(fetchMock).toHaveBeenCalledWith(
expect.stringMatching(/\/api\/vendor-portal\/dispatches\/7\/uplift-request$/),
expect.objectContaining({ method: "POST" }),
);
});
it("keeps unexpected server messages behind the generic fallback", async () => {
const unexpectedMessage = "SqlException: work order row failed";
vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(JSON.stringify({ message: unexpectedMessage }), {
status: 500,
headers: { "Content-Type": "application/json" },
}),
);
renderCreateForm();
submitCreateForm();
await waitFor(() =>
expect(screen.getByRole("alert").textContent).toBe(
"Unable to request the NTE uplift. Please try again.",
),
);
});
});