Current User: Fix reload not fetching fresh data when entity events fire#22719
Conversation
|
Claude finished @madsrasmussen's task in 3m 18s —— View job PR ReviewTarget: Fixes a stale-promise bug in
Suggestions
ApprovedThe fix is minimal and correct — clearing |
There was a problem hiding this comment.
Pull request overview
Fixes a regression/bug in the Backoffice current-user context where event-triggered reloads could return an already-resolved load() promise instead of performing a fresh fetch, and adds a regression test that verifies the current user state actually updates after related entity changes.
Changes:
- Clear
#loadPromisebefore running the debounced reload, ensuring entity events always trigger a freshload(). - Add a regression test that mutates a user group and verifies
allowedSectionschanges after an entity-updated event. - Simplify test timing helpers by using
aTimeoutfrom@open-wc/testing.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/Umbraco.Web.UI.Client/src/packages/user/current-user/current-user.context.ts |
Clears cached load() promise on debounced reload so event-driven reloads fetch fresh data. |
src/Umbraco.Web.UI.Client/src/packages/user/current-user/current-user.context.test.ts |
Adds regression coverage for “fresh data” reload behavior and refactors delays to aTimeout. |
|
@claude what do you think about introducing an abort controller in this case? Cause what if a current load is still executing when the loadDebounce gets triggered? |
There was a problem hiding this comment.
Good fix — the root cause is clear and the solution is minimal and well-targeted.
Summary
The load() method intentionally caches its in-flight promise in #loadPromise so concurrent callers coalesce onto a single fetch. The bug was that once the promise resolved it was never cleared, so any subsequent call to load() (including the event-triggered debounced reload) returned the settled promise immediately without re-fetching.
The fix — clearing #loadPromise inside #loadDebounced before calling load() — is the right approach: it invalidates the cache only on the event-driven reload path, leaving the coalescing behaviour intact for concurrent initial loads.
What looks good
- Fix is surgically scoped. Only the debounced event-reload path clears the promise; direct
load()calls still share the in-flight promise as intended. - No double-fetch risk.
#loadPromise = undefinedis set synchronously beforeload(), soload()always creates a fresh#doLoad()assignment. The observer key'observeUser'ensures the old subscription is replaced rather than duplicated. - Test cleanup is a net improvement. Replacing the inline
new Promise((resolve) => setTimeout(resolve, 200))withaTimeout(200)from@open-wc/testingis idiomatic and removes the duplicated localwaithelper. - New regression test is solid. The
reload fetches fresh datasuite exercises the actual data flow end-to-end (repo save → entity event → reload → observable value check), which directly validates the bug scenario rather than just the reload counter. UmbUserGroupDetailStoreadded to the test host — correctly supplies the dependency the new test needs.
Minor note
The 200 ms aTimeout appears in every test case (both old and new). That's fine for correctness, but worth noting that if this suite ever grows large, the cumulative wait time could slow CI. Not a blocker — just something to keep in mind if the suite ever needs a speed pass.
Overall this is a clean, low-risk bugfix with good test coverage.
Summary
A local "cache" has been introduced in the current user context that always returns the last resolved promise with data. This prevents the context from reloading current user data when a user or user group is updated. The PR ensures that the cached promise is cleared before reloading the current user.
The PR is kept internal because the reload feature has not been released yet.
Test plan