Files
tech-log-frontend/tests/features
DongHyeonkaandClaude Opus 5 d84b57bb3f fix: let the mock's dependency revision observe the Asset store
`createMockStudioGateway`'s default `dependencyRevision.current()` returned a
literal constant and never consulted `dependencies.assets`, so the staleness
guards in `createStudioPreview` and `publishStudioDocument` could not fire for
an asset-store mutation between validate and preview.

The live case: a document references an evidence key with `alt=""` and the
store holds only a `decorative: true` Asset for it, so validation is correctly
VALID with zero issues. A newer `decorative: false` Asset then wins that key.
Preview succeeds, the figure resolves to `decorative: false, alt: ""`, and
publish snapshots it verbatim -- a meaningful image with no accessible name,
validated clean, with nothing anywhere reporting an error.

The default now folds the Asset store into the revision. Each Asset is reduced
to the fields the mock's own validation and projection read -- identity and
resolution order (`id`, `assetKey`, `updatedAt`), resolvability
(`managementStatus`, `publicPath`), the alt rule (`decorative`, `altText`), and
what the published `ResolvedAsset` carries (`mediaType`, `width`, `height`) --
canonicalized with `stableStringify`, sorted, and folded into a 128-bit FNV-1a
digest. Sorting the canonical strings is what makes it order-independent, which
this mock's reproducibility across the suite depends on.

It is a projection rather than the whole record because the excluded fields cost
sensitivity without buying any. `usageCount` is the clearest: it counts
referencing documents, so on a real backend publishing any document that uses an
Asset would invalidate every other author's in-flight validation, while changing
nothing the validator or renderer reads.

An empty store still reports the bare catalog constant -- that is the world the
seeded fixtures were validated against, and `fixtures.ts` now shares the one
definition rather than retyping the literal.

`findResolvableAsset` is untouched: it is a single-point-in-time predicate and
is correct as it stands. Seeing a change *between* two points is the revision's
job. A caller-supplied `dependencyRevision` still wins outright.

The asset-picker test that reached `failureOf`'s `ContentFormatError` branch did
so only because the revision could not move; it now pins its own revision to
keep reaching the projection, and asserts the problem detail so the two 409
paths cannot be confused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 18:44:53 +09:00
..