fix(web): reject non-finite numbers, and keep the branch picker with the raw draft
Two more from Copilot's second pass, both real.
- Every JSON-draft parser now rejects a value `JSON.stringify` cannot write
back. `JSON.parse("1e400")` yields `Infinity`, which serializes as `null` —
so an editor showing `1e400` would have sent `null`, which is exactly the
misreport `isSerializableJson` was written for. `parseJsonObjectDraft`
already guarded; the raw-arguments editor and the Edit-and-replay modal did
not, and neither did `SchemaJsonField`'s `parseJsonDraft` — the last
predates this PR but is the same defect in the same family, so it is fixed
with them rather than left as the odd one out.
- Editing a root union's discriminator in the raw document now moves the
Variant picker. Nothing in `values` names a branch, so the index is held by
the form and was only re-derived on `resetKey` or a rewritten union; a raw
edit had no other signal, so `{"kind":"email"}` → `{"kind":"sms",…}` left
the picker on Email and switching back to the widgets rendered the Email
branch over SMS values. The current branch is kept when the values identify
none, since the discriminator is absent every time it is retyped.
The raw editor is keyed by entity only, not by entity-and-branch like the
per-field editors: it holds the whole arguments object, so a branch move must
re-sync it rather than remount it — a remount would reformat the text being
typed and drop the caret to the top.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UL9retfvAXRgvi6EWk4SY4
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
c9fb461bf0
commit
b4083ee5fb
1 changed files with 218 additions and 8 deletions
|
|
@ -88,6 +88,16 @@ describe("EditReplayModal", () => {
|
|||
expect(screen.getByText(/must be a JSON object/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// `JSON.parse("1e400")` yields `Infinity`, which `JSON.stringify` writes back
|
||||
// as `null` — so Send would dispatch a number the user never typed while the
|
||||
// editor still showed what they wrote.
|
||||
it("disables Send for a number that cannot survive being sent", async () => {
|
||||
renderWithMantine(<EditReplayModal {...baseProps} />);
|
||||
await setAceText('{"limit":1e400}');
|
||||
expect(screen.getByRole("button", { name: "Send" })).toBeDisabled();
|
||||
expect(screen.getByText(/Numbers must be finite/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("closes without sending when cancelled", async () => {
|
||||
const user = userEvent.setup();
|
||||
const onSend = vi.fn();
|
||||
|
|
|
|||
Loading…
Reference in a new issue