ZDDC/tests
ZDDC 8edbb81958 feat(browse): lost-update protection for editors + shared conflict dialog
Two users editing the same file online could silently clobber each other:
the editor's save did a bare PUT with no precondition, even though the master
already enforces optimistic concurrency (fileapi.go checkIfMatch → 412). Now
the editor sends a precondition and surfaces a conflict UI instead of
overwriting.

- util.js: saveFile(node, content, contentType, opts) sends `If-Match: <etag>`
  (or `If-Unmodified-Since` fallback) unless opts.force; returns {etag} from
  the PUT response (so save→edit→save adopts the new version and doesn't
  false-conflict); throws ConflictError (.status===412) on a precondition
  failure so callers branch cleanly. New saveCopy() parks a conflicting edit
  as `<stem>-conflict-<ts>.<ext>` (collision-probed) without losing either side.
- preview.js: getContentWithVersion(node) → {buf, etag, lastModified} captured
  from the content GET (the listing JSON carries no per-file etag); threaded
  into the editor ctx and exported. getArrayBuffer left untouched.
- conflict.js (new): shared, callback-driven dialog — mine-vs-theirs diff
  (reuses zddc.diff + css/history.css) + Overwrite / Reload-theirs /
  Save-a-copy / Cancel. Never calls saveFile/showFilePreview itself, so the
  deferred Phase 5 cache-outbox conflict UI can reuse it with its own callbacks.
- preview-markdown.js / preview-yaml.js: capture + forward the version token,
  adopt the returned etag on success, and on 412 open the dialog (Overwrite
  re-fetches the current etag then re-saves — re-conflicts on a third writer
  rather than blind-forcing; Reload clears dirty first so the renderInline
  guard skips its confirm). FS-Access mode sends no precondition (no
  concurrency) and never conflicts.
- build.sh: concat conflict.js after util.js.
- tests/conflict.spec.js (+ playwright project): If-Match sent, ConflictError
  on 412, new-etag returned, force omits the precondition, dialog renders the
  diff and each action resolves via its callback. Drives the fresh dist build
  over file:// with a stubbed fetch (the test binary embeds the committed
  browse.html, not dist, so a server-mode E2E would run stale code).

All browse + diff + conflict specs pass (18).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 16:24:15 -05:00
..
data test,docs(zip): browse/archive zip-transmittal coverage + fixture + docs 2026-05-12 12:35:48 -05:00
fixtures test,docs(zip): browse/archive zip-transmittal coverage + fixture + docs 2026-05-12 12:35:48 -05:00
lib test: server-backed Playwright harness + /.tokens spec 2026-05-08 10:09:54 -05:00
archive-cascade.spec.js feat: lockstep release infra + cascade/.archive fixes + profile perf + page redesign 2026-05-01 20:11:38 -05:00
archive.spec.js test,docs(zip): browse/archive zip-transmittal coverage + fixture + docs 2026-05-12 12:35:48 -05:00
browse.spec.js fix: clear the 14 stale Playwright baseline failures 2026-05-21 11:24:30 -05:00
build-label.spec.js fix: clear the 14 stale Playwright baseline failures 2026-05-21 11:24:30 -05:00
classifier.spec.js Initial commit 2026-04-27 11:05:47 -05:00
conflict.spec.js feat(browse): lost-update protection for editors + shared conflict dialog 2026-06-03 16:24:15 -05:00
diff.spec.js feat(browse): markdown version-history viewer with diff + restore 2026-05-28 12:49:00 -05:00
form-safety.spec.js feat(form): ui:mirrorFrom — reflect a sibling field into a read-only field 2026-05-21 15:44:43 -05:00
landing.spec.js fix: clear the 14 stale Playwright baseline failures 2026-05-21 11:24:30 -05:00
logo.spec.js refactor: nest lifecycle slots per-party + add virtual top-level aggregators 2026-05-21 07:57:45 -05:00
schema.spec.js Initial commit 2026-04-27 11:05:47 -05:00
tables.spec.js feat(tables): read-only cells, show server-derived fields on create, clearer conflict 2026-05-21 15:34:22 -05:00
toast.spec.js feat(shared): non-blocking toast helper available to every tool 2026-05-09 19:04:41 -05:00
tokens.spec.js test: server-backed Playwright harness + /.tokens spec 2026-05-08 10:09:54 -05:00
transmittal-drag-drop.spec.js Initial commit 2026-04-27 11:05:47 -05:00
transmittal-init-check.spec.js Initial commit 2026-04-27 11:05:47 -05:00
transmittal-validation.spec.js test(transmittal): cover the publish-time validation gate 2026-05-21 16:49:23 -05:00
transmittal.spec.js Initial commit 2026-04-27 11:05:47 -05:00
zddc-filter.spec.js Initial commit 2026-04-27 11:05:47 -05:00
zddc-source.spec.js test(shared): smoke tests for the zddc-source.js FS-Access polyfill 2026-05-09 18:49:11 -05:00
zddc.spec.js Initial commit 2026-04-27 11:05:47 -05:00