Skip to content

fix(dev-tools): restore Query Tool's persisted query + clear FileAsset example warnings (#36692) - #37869

Merged
AP2300 merged 2 commits into
mainfrom
issue-36692-query-tool-persisted-query-fix
Oct 2, 2026
Merged

AP2300 merged 2 commits into
mainfrom
issue-36692-query-tool-persisted-query-fix

Conversation

@AP2300

@AP2300 AP2300 commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #36692 — addresses both items from @hmoreras' QA round on the merged #36781.

1. Query Tool did not persist the query (the QA blocker)

DotQueryToolStore composes the shared withPersistedQuery() feature correctly and did restore the last query — but the feature's onInit runs when the store is constructed, i.e. before the component's ngOnInit, which then unconditionally wrote the q URL param over it:

const query = params.get('q') ?? '';
this.store.setQuery(query);   // '' when you arrive from the Dev Tools menu

Arriving from the menu carries no q, so the restored value was replaced by '' a tick after it was restored. Query Tool is the only one of the three dev tools that reads URL params — which is exactly why ES Search and Velocity Playground kept their queries and this one did not. The shared helper in libs/data-access/dot-localstorage/ was never at fault and is unchanged.

The param is now applied only when the URL actually carries q. params.has('q') rather than a truthiness check, so a shared ?q= link still clears the editor instead of silently resurrecting the previous query. Deep links keep winning over the restored value and still auto-run; a restored query is left in the editor unexecuted, matching the sibling dev tools.

Worth knowing for re-testing: localStorage itself was never corrupted. The debounced write pipeline's skip(1) happened to swallow the stray '', so the stored entry survived — the query was only missing from the UI. Inspecting Application → Local Storage would have looked healthy.

2. Velocity Playground example ran with warnings

The pull files example referenced $f.fileSize, which is not a contentlet property — it resolved to null on every pulled file, so running the example greeted the user with five NULL_METHOD_RESULT warnings and printed the literal $f.fileSize in the output (the screenshot on the issue).

Size is a metadata-backed getter on FileAsset (getFileSize() → getMetadata().getSize()), reachable through the fileAsset binary field (FileAssetAPI.BINARY_FIELD, and FileAssetMap extends FileAsset). The example now reads $f.fileAsset.fileSize. fileName and mimeType do resolve on the contentlet, which is what made the mistake easy to miss.

I audited the other three Velocity examples and the Query Tool / ES Search example catalogs: all references resolve. The warnings banner is Velocity-only — it is fed by the VTL endpoint's CollectingInvalidReferenceHandler, so the other two portlets have no equivalent surface to clear.

Also checked (no code needed)

Three acceptance criteria on the issue are still unticked but were in fact delivered by #36781 — I verified rather than reimplemented:

  • Shared persistence helper lives in libs/data-access/src/lib/dot-localstorage/ (not duplicated per portlet)
  • All three portlets wire a Clear action to store.clearPersistedQuery() in their templates
  • Velocity's history / splitter storage is reconciled with the persisted-query key

Test plan

  • portlets-dot-query-tool-portlet — 58 tests
  • portlets-dot-velocity-playground-portlet — 124 tests
  • nx affected -t test --base=origin/main — 2,726 tests across 4 projects
  • nx affected -t lint + nx format:check clean
  • Manual (for QA): type a query in Query Tool, switch to another portlet, come back — query is restored
  • Manual (for QA): same round-trip in ES Search and Velocity Playground (regression guard — these already worked)
  • Manual (for QA): open a shared ?q=... Query Tool link — the deep link wins over the stored query and auto-runs
  • Manual (for QA): run the Velocity pull files example on an instance with files — no warning banner, sizes render as numbers

The Velocity fix was verified by reading the Java (FileAssetAPI, FileAsset.getFileSize(), ContentMap's binary-field branch), not by running it against an instance — worth an extra look during QA.

Testing notes

The new regression coverage sits in a dedicated describe that uses the real store. Every other describe in that spec mocks DotQueryToolStore, so the store-onInit-before-ngOnInit ordering was structurally invisible to them — which is how this shipped green. It covers restore-on-reopen, deep-link precedence, and that the stored entry is never erased. Confirmed failing first (expected '' to be '+contentType:Blog'), then passing.

🤖 Generated with Claude Code

This PR fixes: #36692

…t example warnings (#36692)

QA found the Query Tool losing its query on every return to the portlet, while
ES Search and Velocity Playground kept theirs.

The store composes `withPersistedQuery`, which restores the last query in its own
`onInit` — but that runs before the component's `ngOnInit`, which unconditionally
wrote the `q` URL param over it. Navigating in from the menu carries no `q`, so the
restored query was immediately replaced by ''. Query Tool is the only one of the
three dev tools that reads URL params, which is why only it regressed.

The param is now applied only when the URL actually carries `q` (`has`, not a
truthiness check, so a shared `?q=` still clears the editor rather than silently
resurrecting the previous query). Deep links keep winning over the restored value
and still auto-run; a restored query is left unexecuted, as in the sibling tools.

Also fixes the second item QA raised: the Velocity Playground "pull files" example
referenced `$f.fileSize`, which is not a contentlet property — it resolved to null
on every file, so the example ran with five NULL_METHOD_RESULT warnings and printed
the literal `$f.fileSize`. Size is a metadata-backed getter on FileAsset, reachable
through the `fileAsset` binary field (`$f.fileAsset.fileSize`); `fileName` and
`mimeType` do resolve on the contentlet, which is what made the mistake easy to miss.
The other three examples were audited and resolve cleanly.

Tests: a new real-store describe in the page spec (every other describe mocks the
store, so the onInit ordering was invisible to them) covering restore-on-reopen,
deep-link precedence, and that the stored entry is never erased; plus a guard on
the example catalog.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
hmoreras
hmoreras previously approved these changes Oct 2, 2026
…istence specs

Review feedback from @hmoreras on #37869: the "no debounced erase" test passes
with the ngOnInit guard reverted, so it does not guard the fix — and the comments
on it and on the sibling L209 test asserted the opposite.

Both claims verified before changing anything. Reverting the guard locally fails
exactly two tests (restore-on-reopen and the setQuery contract); the erase test
stays green. And fake timers DO drive this debounce — `flushEffects()` first, so
the rxMethod effect creates the timer, then `advanceTimersByTime`, as
with-persisted-query.feature.spec.ts already does. The earlier comment blaming
zone.js was wrong; the missing piece was flushEffects, not the clock.

- L209 comment: drop the false claim that the stray '' deletes the stored entry.
  `skip(1)` absorbs it; the damage is confined to the editor the user sees.
- Kept the erase test but renamed and reframed it as what it is: an invariant
  guard that reopening never destroys the saved query, explicitly flagged as NOT
  a regression test for this fix. `skip(1)` is the only thing between a stray
  write-on-init and silent data loss, so it is worth pinning on its own.
- Switched it to fake timers, dropping a 400 ms real sleep from the suite.
  Confirmed non-vacuous with a throwaway probe: typing a value and advancing the
  clock does land it in localStorage, so a real erase would be observed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@AP2300
AP2300 enabled auto-merge October 2, 2026 15:37
@AP2300
AP2300 added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit f7a0e6a Oct 2, 2026
54 of 58 checks passed
@AP2300
AP2300 deleted the issue-36692-query-tool-persisted-query-fix branch October 2, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area : Frontend PR changes Angular/TypeScript frontend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Dev tools consistency: remove dark mode from velocity-playground and persist last query across query-tool, es-search, and velocity-playground

2 participants