Skip to content

test(frontend): pin allowed_accounts UI enforcement#587

Merged
cristim merged 2 commits into
feat/multicloud-web-frontendfrom
test/frontend-allowed-accounts-313
May 27, 2026
Merged

test(frontend): pin allowed_accounts UI enforcement#587
cristim merged 2 commits into
feat/multicloud-web-frontendfrom
test/frontend-allowed-accounts-313

Conversation

@cristim
Copy link
Copy Markdown
Member

@cristim cristim commented May 20, 2026

Summary

Add allowed-accounts.test.ts covering the three frontend surfaces that rely on the backend's allowed_accounts filtering (issue #313):

  • Account chip (3 tests): when listAccounts returns a filtered subset the chip option list contains exactly those accounts plus the All Accounts sentinel. Disallowed accounts never appear. Zero-account case yields only the sentinel.
  • History list (2 tests): the UI renders exactly the rows returned by getHistory with no additional client-side account filtering. Empty response yields zero rendered rows.
  • 403 on Cancel (1 test): when cancelPurchase rejects with a 403 (disallowed account accessed via deep link or stale tab) the handler surfaces a user-friendly error toast instead of an unhandled exception.

Closes #313

Test plan

  • All 6 new tests pass (jest src/__tests__/allowed-accounts.test.ts)
  • Pre-commit hooks pass

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for account filtering behavior in the topbar, history list rendering, and error handling during purchase cancellation operations.

Review Change Stack

Add allowed-accounts.test.ts covering the three frontend surfaces that
rely on the backend's allowed_accounts filtering:

1. Account chip: when listAccounts returns a filtered subset the chip
   option list contains exactly those accounts plus the All Accounts
   sentinel. Disallowed accounts never appear. Zero-account case yields
   only the sentinel.

2. History list: the UI renders exactly the rows returned by getHistory
   with no additional client-side account filtering. Empty response
   yields zero rendered rows.

3. 403 on Cancel: when cancelPurchase rejects with a 403 (disallowed
   account accessed via deep link or stale tab) the handler surfaces a
   user-friendly error toast instead of an unhandled exception.
@cristim cristim added triaged Item has been triaged priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-quarter Within the quarter impact/many Affects most users labels May 20, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Warning

Review limit reached

@cristim, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 42 minutes and 52 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a9a2c832-c130-430a-a2c7-103a906b430d

📥 Commits

Reviewing files that changed from the base of the PR and between 418e850 and 57bd5dd.

📒 Files selected for processing (1)
  • frontend/src/__tests__/allowed-accounts.test.ts
📝 Walkthrough

Walkthrough

This PR adds a comprehensive Jest test suite (allowed-accounts.test.ts) that validates frontend UI surfaces respect the backend's allowed_accounts permission enforcement. The tests cover account chip filtering, history list rendering, and 403 error handling on user actions.

Changes

Allowed Accounts UI Enforcement Tests

Layer / File(s) Summary
Test setup, mocks, and imports
frontend/src/__tests__/allowed-accounts.test.ts (lines 1–70)
Test header documents the three pinned UI surfaces. Jest mocks for API endpoints (listAccounts, getHistory, cancelPurchase), toast/confirm/navigation utilities, and helper modules are established; then modules under test are imported.
DOM helpers and factory functions
frontend/src/__tests__/allowed-accounts.test.ts (lines 71–131)
Utilities to create topbar and history DOM containers, construct date and row DOM nodes, and a makeHistoryRow factory to generate history row objects with configurable field overrides.
Account chip filtering tests
frontend/src/__tests__/allowed-accounts.test.ts (lines 136–211)
Three test cases: (1) chip options are populated from listAccounts results; (2) disallowed accounts are omitted; (3) when listAccounts returns empty, only the "All Accounts" sentinel appears.
History rendering and error handling tests
frontend/src/__tests__/allowed-accounts.test.ts (lines 217–286)
Three test cases: (1) history table rows exactly match getHistory API results; (2) empty purchase list renders no rows; (3) a 403 error on cancelPurchase triggers an error toast rather than an unhandled exception.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • LeanerCloud/CUDly#358: Updates users.test.ts to align with allowed_accounts enforcement; both PRs validate frontend compliance with the backend's per-account permission filtering.

Poem

🐰 A new test suite hops in with cheer,
To pin what users should and can see here—
Chip filters, history rows, error toasts too,
All dancing together to keep accounts true! 🎯✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'test(frontend): pin allowed_accounts UI enforcement' directly aligns with the main change: adding Jest tests for the allowed_accounts UI enforcement feature.
Linked Issues check ✅ Passed The PR implements all key coding requirements from #313: account chip tests (disallowed accounts omitted, empty state handled), history list tests (renders API-returned rows with no client-side filtering), and 403 error handling test with user-friendly toast.
Out of Scope Changes check ✅ Passed All changes are within scope: only a new test file added covering the three frontend surfaces (account chip, history list, 403 error handling) specified in the linked issue #313 objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/frontend-allowed-accounts-313

Comment @coderabbitai help to get the list of available commands and usage tips.

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 20, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim cristim added type/chore Maintenance / non-user-visible effort/m Days labels May 20, 2026
@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 22, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 22, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 25, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
frontend/src/__tests__/allowed-accounts.test.ts (1)

259-285: 💤 Low value

Consider clarifying the console.error spy comment and async timing.

The test validates the 403 error handling requirement correctly. Two minor observations:

  1. Comment clarity (line 260-261): The comment mentions "history.ts's catch block" but the 403 error originates from the cancel button handler, not from the loadHistory() catch block (which succeeds on line 273). Consider clarifying which error path is being silenced.

  2. Async timing (line 277): The 10ms setTimeout wait is somewhat arbitrary. While it works in practice, consider using waitFor utilities or Jest fake timers for more deterministic async handling in future tests.

Neither issue affects correctness, and the test successfully validates that a 403 from cancelPurchase triggers an error toast rather than an unhandled exception.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/__tests__/allowed-accounts.test.ts` around lines 259 - 285,
Update the test comment to accurately state that the console.error spy is
silencing the error emitted by the cancel button handler (the rejection from
api.cancelPurchase), not from loadHistory(), so replace "history.ts's catch
block" with a phrase referencing the cancel handler/cancelPurchase rejection;
additionally, replace the arbitrary await new Promise((r) => setTimeout(r, 10))
with a deterministic async wait (e.g., use Jest DOM/Testing Library's waitFor or
proper Jest fake timers) to await the UI/toast update after invoking the button
so the expectation on showToast is stable (references: loadHistory,
api.cancelPurchase, showToast, the console.error spy).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@frontend/src/__tests__/allowed-accounts.test.ts`:
- Around line 259-285: Update the test comment to accurately state that the
console.error spy is silencing the error emitted by the cancel button handler
(the rejection from api.cancelPurchase), not from loadHistory(), so replace
"history.ts's catch block" with a phrase referencing the cancel
handler/cancelPurchase rejection; additionally, replace the arbitrary await new
Promise((r) => setTimeout(r, 10)) with a deterministic async wait (e.g., use
Jest DOM/Testing Library's waitFor or proper Jest fake timers) to await the
UI/toast update after invoking the button so the expectation on showToast is
stable (references: loadHistory, api.cancelPurchase, showToast, the
console.error spy).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 52956104-32ff-4309-be14-3ffd6e3af5a9

📥 Commits

Reviewing files that changed from the base of the PR and between bc8831b and 418e850.

📒 Files selected for processing (1)
  • frontend/src/__tests__/allowed-accounts.test.ts

… per CR

Replace the arbitrary 10ms setTimeout with waitFor from @testing-library/dom
so the 403-cancel toast assertion waits deterministically for the mock to be
called. Also correct the comment from "history.ts's catch block" to "cancel
button handler's catch block" which accurately identifies the code path.
@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 27, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim cristim merged commit c6b7c61 into feat/multicloud-web-frontend May 27, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/m Days impact/many Affects most users priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/chore Maintenance / non-user-visible urgency/this-quarter Within the quarter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant