fix: guard pending refusal dialog

This commit is contained in:
Alexandre Brandizzi 2026-08-10 13:31:12 -03:00
parent 4d2ee40d60
commit 3f4d64d7b6
2 changed files with 38 additions and 1 deletions

View file

@ -12,6 +12,7 @@ import {
type RefuseDispatchValues,
} from "@/domain/vendor-portal/schemas/refuse-dispatch-schema";
import { queryKeys } from "@/infra/query-key/query-key";
import { guardDialogClose } from "@/lib/dialog-guard";
type RefuseDispatchDialogProps = {
open: boolean;
@ -75,7 +76,11 @@ export function RefuseDispatchDialog({
: "";
return (
<Dialog open={open} onClose={onClose} aria-labelledby="refuse-dispatch-title">
<Dialog
open={open}
onClose={guardDialogClose(refuseMutation.isPending, onClose)}
aria-labelledby="refuse-dispatch-title"
>
<DialogTitle id="refuse-dispatch-title">Refuse dispatch</DialogTitle>
<form onSubmit={(event) => void submit(event)}>
<DialogContent>

View file

@ -137,4 +137,36 @@ describe("RefuseDispatchDialog", () => {
await waitFor(() => expect(onClose).toHaveBeenCalled());
expect(vendorPortalApi.refuse).not.toHaveBeenCalled();
});
it("blocks Escape and backdrop close while a refusal is pending, then closes on success", async () => {
let resolveRefusal!: (value: { id: number; status: string }) => void;
vi.spyOn(vendorPortalApi, "refuse").mockImplementation(
() =>
new Promise((resolve) => {
resolveRefusal = resolve;
}),
);
const onClose = vi.fn();
renderDialog({ onClose });
await act(async () => {
fireEvent.click(screen.getByRole("button", { name: "Refuse dispatch" }));
});
await waitFor(() => expect(screen.getByRole("button", { name: "Refusing…" })).toBeDisabled());
expect(screen.getByRole("button", { name: "Cancel" })).toBeDisabled();
const backdrop = document.querySelector(".MuiBackdrop-root");
expect(backdrop).not.toBeNull();
fireEvent.click(backdrop as Element);
fireEvent.keyDown(document.body, { key: "Escape" });
expect(onClose).not.toHaveBeenCalled();
await act(async () => {
resolveRefusal({ id: 9, status: "Refused" });
});
await waitFor(() => expect(onClose).toHaveBeenCalled());
});
});