Skip to content

Tests: drag-and-drop and undo-on-cancel coverage (deferred from #264) #270

@CarlosNZ

Description

@CarlosNZ

Two areas of behaviour that weren't covered in the §3 test push (#264#269) because each has its own setup cost and was considered lower-priority than landing the core regression net first. Capturing here so they don't get forgotten.

Drag-and-drop

src/hooks/useDragNDrop.tsx wires native HTML5 drag events on collection rows and value rows. Currently zero test coverage. The reason it wasn't tackled in #269: jsdom doesn't fire real drag events, RTL's userEvent has no DnD API, and react-dnd-style abstractions aren't in play here — we'd have to drive dragStart / dragOver / drop via fireEvent manually and assert on the resulting setData shape.

Scenarios worth covering

  • Rearrange keys within an object — setData reflects the new order, values intact
  • Rearrange elements within an array — same
  • Drag from a collection into a sibling collection — restructures both source and destination
  • Drag onto a leaf (should be rejected or no-op, depending on current behaviour — lock it in)
  • restrictDrag (boolean) hides drag affordance / blocks the drop
  • restrictDrag (function) selectively allows/blocks per node, same shape as the §5 functional-restriction tests
  • Drag interaction during edit — should cancel or be blocked

Approach

fireEvent.dragStart(source, { dataTransfer }) + fireEvent.dragOver(target) + fireEvent.drop(target, { dataTransfer }). The dataTransfer object needs to be supplied (jsdom doesn't construct one automatically). Worth wrapping in a helper, e.g. dragAndDrop(source, target), so each test is one line.

Undo-on-cancel

ValueNodeWrapper.tsx:245-246 (and the matching code in CollectionNode.tsx:272-273) restores previousValue when a cancel happens after a type change. The contract here is subtle: changing a value's type (e.g. string → object) immediately fires setData with the converted default; if the user then cancels, the editor reverts both the type and the value. This was the bug behind the now-closed #122 — easy to regress if anyone refactors the cancel path.

Scenarios worth covering

  • Type-change-then-cancel reverts to the original type and value (in one PR with the test, asserting on both setData calls)
  • Cancel after just opening edit mode (no change made) — no setData revert call needed
  • Cancel after type change AND value change — verify which value is restored (likely the pre-type-change one)
  • Cancel after multiple consecutive type changes — does it revert all the way, or just the last?

Approach

Plain RTL — the cancel path goes through the keyboard handler and the Cancel icon, both already exercised in #269. The complication is asserting on a sequence of setData calls. Use setData.mock.calls directly and inspect each entry, not just toHaveBeenCalledWith.

Acceptance

  • Both areas covered with tests in test/JsonEditor.test.tsx (or a sibling file if the file grows past comfort)
  • The DnD helper, if introduced, lives in test/ and is reused across tests
  • pnpm test green; new tests follow the contract-not-implementation discipline noted in CLAUDE.md

Priority

Low. The §4 / §16 refactors don't deeply touch DnD or undo-on-cancel paths, so the absence of these tests isn't a blocker. Pick up when there's a natural moment — e.g. before any refactor that does touch them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    V2To include in Version 2

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions