fix: preserve reconciliation authorities
This commit is contained in:
@@ -33,6 +33,7 @@ function FormHarness(props: Readonly<{
|
||||
| Readonly<{ ok: true; value: string }>
|
||||
| Readonly<{ ok: false; error: ReturnType<typeof createFailure> }>
|
||||
>;
|
||||
resetOnSuccess?: boolean;
|
||||
}>) {
|
||||
const form = useAppForm({
|
||||
schema,
|
||||
@@ -45,6 +46,7 @@ function FormHarness(props: Readonly<{
|
||||
};
|
||||
},
|
||||
submit: props.submit,
|
||||
resetOnSuccess: props.resetOnSuccess,
|
||||
});
|
||||
return (
|
||||
<Form pending={form.pending} onSubmit={(event) => void form.submitForm(event)}>
|
||||
@@ -63,6 +65,10 @@ function FormHarness(props: Readonly<{
|
||||
<Button onClick={() => form.reset()} disabled={!form.dirty}>
|
||||
Reset
|
||||
</Button>
|
||||
<Button onClick={() => form.settleApplied()}>Confirm applied</Button>
|
||||
<Button onClick={() => form.settleNotApplied()}>
|
||||
Confirm not applied
|
||||
</Button>
|
||||
<output data-testid="dirty">{String(form.dirty)}</output>
|
||||
<output data-testid="result">{form.result}</output>
|
||||
</Form>
|
||||
@@ -152,6 +158,81 @@ describe("local form facade", () => {
|
||||
expect(window.location.href).not.toContain(secretLike);
|
||||
expect(JSON.stringify(localStorage)).not.toContain(secretLike);
|
||||
});
|
||||
|
||||
it("blocks a second submit while the prior effect remains unknown", async () => {
|
||||
const user = userEvent.setup();
|
||||
const submit = vi.fn(async () => ({
|
||||
ok: false as const,
|
||||
error: createFailure("SERVER_FAILURE", "CREATE_ENTITY", 0, {
|
||||
effect: "MAYBE_APPLIED",
|
||||
}),
|
||||
}));
|
||||
render(<FormHarness submit={submit} resetOnSuccess={false} />);
|
||||
const name = screen.getByRole("textbox", { name: /Name/ });
|
||||
await user.type(name, "Alpha");
|
||||
await user.click(screen.getByRole("button", { name: "Submit" }));
|
||||
expect(await screen.findByTestId("result")).toHaveTextContent(
|
||||
"effect-unknown",
|
||||
);
|
||||
|
||||
await user.clear(name);
|
||||
await user.type(name, "Beta");
|
||||
await user.click(screen.getByRole("button", { name: "Submit" }));
|
||||
|
||||
expect(submit).toHaveBeenCalledOnce();
|
||||
expect(screen.getByTestId("result")).toHaveTextContent("effect-unknown");
|
||||
});
|
||||
|
||||
it("settles the submitted unknown snapshot without accepting later edits", async () => {
|
||||
const user = userEvent.setup();
|
||||
const submit = vi.fn(async () => ({
|
||||
ok: false as const,
|
||||
error: createFailure("SERVER_FAILURE", "CREATE_ENTITY", 0, {
|
||||
effect: "MAYBE_APPLIED",
|
||||
}),
|
||||
}));
|
||||
render(<FormHarness submit={submit} resetOnSuccess={false} />);
|
||||
const name = screen.getByRole("textbox", { name: /Name/ });
|
||||
await user.type(name, "Alpha");
|
||||
await user.click(screen.getByRole("button", { name: "Submit" }));
|
||||
await screen.findByText("effect-unknown");
|
||||
await user.clear(name);
|
||||
await user.type(name, "Beta");
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Confirm applied" }));
|
||||
|
||||
expect(name).toHaveValue("Beta");
|
||||
expect(screen.getByTestId("result")).toHaveTextContent("success");
|
||||
expect(screen.getByTestId("dirty")).toHaveTextContent("true");
|
||||
await user.clear(name);
|
||||
await user.type(name, "Alpha");
|
||||
expect(screen.getByTestId("dirty")).toHaveTextContent("false");
|
||||
});
|
||||
|
||||
it("releases an unknown submission only after explicit not-applied settlement", async () => {
|
||||
const user = userEvent.setup();
|
||||
const submit = vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce({
|
||||
ok: false as const,
|
||||
error: createFailure("SERVER_FAILURE", "CREATE_ENTITY", 0, {
|
||||
effect: "MAYBE_APPLIED",
|
||||
}),
|
||||
})
|
||||
.mockResolvedValueOnce({ ok: true as const, value: "saved" });
|
||||
render(<FormHarness submit={submit} resetOnSuccess={false} />);
|
||||
await user.type(screen.getByRole("textbox", { name: /Name/ }), "Alpha");
|
||||
await user.click(screen.getByRole("button", { name: "Submit" }));
|
||||
await screen.findByText("effect-unknown");
|
||||
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Confirm not applied" }),
|
||||
);
|
||||
expect(screen.getByTestId("result")).toHaveTextContent("idle");
|
||||
await user.click(screen.getByRole("button", { name: "Submit" }));
|
||||
|
||||
expect(submit).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("dirty navigation guard", () => {
|
||||
|
||||
Reference in New Issue
Block a user