Skip to content

Prevent stale Turbo snapshot on user account/edit pages. OP-19674 - #24454

Open
dfriquet wants to merge 2 commits into
release/17.7from
bug/op-19674-department-stale-after-turbo-restore
Open

Prevent stale Turbo snapshot on user account/edit pages. OP-19674#24454
dfriquet wants to merge 2 commits into
release/17.7from
bug/op-19674-department-stale-after-turbo-restore

Conversation

@dfriquet

@dfriquet dfriquet commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Ticket

https://community.openproject.org/wp/OP-19674

What are you trying to accomplish?

When an administrator changes a user's attributes out-of-band (e.g. their department, or a custom field like Job title), the account page (/my/account) and the admin user-edit page (/users/:id/edit) could keep showing the old values. Persistence was always correct — this is purely browser/Turbo caching.

There are two independent caching layers at play, so there are two fixes:

Layer Symptom Fix
Turbo's in-memory snapshot Returning to the page via the Back button re-rendered the cached snapshot (all browsers) <meta name="turbo-cache-control" content="no-cache"> on both pages
Browser HTTP cache + bfcache Firefox served the page stale on Ctrl+R reload and history-back (the app only sends must-revalidate) Cache-Control: no-store on both actions

The two are complementary — neither alone is sufficient. Chrome revalidates on reload, so it never showed the reload staleness (Firefox-only); Chrome did show the Turbo-snapshot staleness on Back, which the meta fixes.

What approach did you choose and why?

  • Meta via content_for :header_tags, matching the pattern already used by the Angular layout.
  • no-store via a small prevent_response_caching before_action (ApplicationController) on MyController#account and UsersController#edit, scoped to just these actions rather than globally.

Each fix is committed with the example(s) it accounts for (the shared spec file grows across the two commits).

Tests

One :js spec file (account_fresh_after_out_of_band_change_spec.rb) with a shared setup and three examples, each asserting the department and job title update after an out-of-band change:

  • history-back — red→green with the meta (the reproducible Turbo-snapshot case, all browsers).
  • reload and forward menu-nav — green cross-browser guards; their staleness is Firefox-only (the no-store fix, verified manually in Firefox, since Chrome/Cuprite reload fresh regardless).

The fix→example attribution was verified in both Cuprite and a real Chrome instance.

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

Comment on lines +20 to +21
# Leave via a Turbo visit so the account snapshot gets cached.
page.execute_script("window.Turbo.visit('#{projects_path}')")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you not perform a Turbo visit by clicking on Projects in the global menu?

I'd prefer to avoid calling Turbo implementation directly from examples (although I guess we could create a turbo_visit helper` if we find we really need to do this a lot.

@dfriquet
dfriquet force-pushed the bug/op-19674-department-stale-after-turbo-restore branch from c1492d9 to e430efb Compare July 27, 2026 15:30
dfriquet added 2 commits July 27, 2026 17:37
Returning to these pages through the browser history rendered Turbo's cached
snapshot, showing a department (and other attributes) an administrator had changed
out-of-band. Mark them turbo-cache-control: no-cache so a restoration visit refetches.
Firefox serves these pages stale from the HTTP cache / bfcache on reload and
history-back; the Turbo meta only covers Turbo's own snapshot. no-store opts out
of both, fixing Firefox. Chrome revalidates and is already fresh on reload and
forward navigation, so those two examples pass there and act as cross-browser guards.
@dfriquet
dfriquet force-pushed the bug/op-19674-department-stale-after-turbo-restore branch from e430efb to ad7e73f Compare July 27, 2026 15:38
@github-actions

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./modules/backlogs/spec/features/inbox_column_spec.rb[1:7:1]
  • rspec ./spec/features/portfolios/create_spec.rb[1:1:1]
🤖 Ask Copilot to investigate

Copy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer.

@copilot The following spec(s) are flaky in CI (first seen on PR #24454, linked for reference only):

- `rspec ./modules/backlogs/spec/features/inbox_column_spec.rb[1:7:1]`
- `rspec ./spec/features/portfolios/create_spec.rb[1:1:1]`

Treat this as a standalone task, unrelated to PR #24454. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24454 or reuse that branch.

Follow the playbook in docs/development/testing/handling-flaky-tests/README.md to find the root cause and fix the underlying race — do not skip, delete, or weaken the spec to make it pass; disabling is a last resort per the playbook, and only with a bug ticket. Verify the fix by running the spec(s) repeatedly (e.g. `script/bulk_run_rspec --run-count 10`).

If you cannot reproduce the flake or are not confident in a fix after reasonable investigation, do not fabricate a change or skip the spec to force CI green. Instead, leave the pull request in draft and document what you tried, the suspected cause, and any leads in its description, then assign @dfriquet to take over.

Once the fix is verified, title the PR after the spec(s) it fixes, and use the PR description to explain the root cause, how the change resolves it, and the before/after results. Label the PR `flaky-spec`, assign @dfriquet, and request a review from @dfriquet.
On every commit, set @dfriquet as the sole co-author with a `Co-authored-by:` trailer (use their GitHub no-reply email so it links to their account), so it is traceable who dispatched the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants