Skip to content

test(settings): backfill unit tests for team / billing / notifications panels (#1870)#2089

Merged
senamakel merged 1 commit into
tinyhumansai:mainfrom
CodeGhost21:tests/settings-panels-team-billing-notifications
May 20, 2026
Merged

test(settings): backfill unit tests for team / billing / notifications panels (#1870)#2089
senamakel merged 1 commit into
tinyhumansai:mainfrom
CodeGhost21:tests/settings-panels-team-billing-notifications

Conversation

@CodeGhost21

@CodeGhost21 CodeGhost21 commented May 18, 2026

Copy link
Copy Markdown
Contributor

Closes #1870

Summary

Issue #1870 — group 2 of the i18n coverage gap.

PR #1518 (Chinese i18n) surfaced a pre-existing testing gap: many settings panels had zero test files. This PR addresses the team / billing / notifications subset called out in the issue's suggested decomposition.

Adds per-component RTL + Vitest suites for 8 panels:

Panel Tests Coverage focus
BillingPanel 4 auto-open flow, error state, re-open click, back navigation
NotificationsPanel 6 DND skeleton/toggle/rollback, per-category toggles, redux preference seeding
NotificationRoutingPanel 6 pipeline stats card, per-provider load + retry hint, threshold formatting, payload shape
MessagingPanel 5 default-channel selector, loading + error, ChannelSetupModal open/close, updatePreferences wiring
TeamPanel 8 list/active badge, create/join/switch/leave, manage navigation, localized error fallback
TeamMembersPanel 7 admin vs. non-admin affordances, role-change + remove confirmations, empty state, route-context teamId
TeamInvitesPanel 6 code rendering with state badges, generate/revoke/copy, admin gating, empty state
TeamManagementPanel 8 admin-only entry, not-found + access-denied branches, sub-route navigation, edit-name + delete confirm

50 new tests total. Behavior-focused per the in-repo convention — exercising RPC payload shapes, modal confirmation flows, optimistic-UI rollback, and i18n-resolved labels rather than implementation details.

Test plan

  • pnpm test src/components/settings/panels — 230/230 pass across 26 files
  • pnpm compile — clean
  • ESLint clean on the 8 new files
  • Prettier applied

Remaining work (tracked separately)

Per #1870, groups 3–5 are still untested and will land as separate PRs:

  • Group 3: debug panels (MemoryDebugPanel, VoiceDebugPanel, WebhooksDebugPanel, LocalModelDebugPanel, ScreenAwarenessDebugPanel, AutocompleteDebugPanel)
  • Group 4: top-level pages (Accounts, Conversations, Intelligence, Invites, Notifications, Webhooks)
  • Group 5: onboarding (BetaBanner, ChatProviderPage, ReferralApplyStep)

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for settings panels including billing, messaging, notifications, notification routing, and team management
    • Verified settings panel functionality across navigation flows, data operations, and error handling to ensure reliability and stability

Review Change Stack

…s panels (tinyhumansai#1870)

Issue tinyhumansai#1870 — group 2 of the i18n coverage gap. Adds per-component RTL
+ Vitest suites for the eight settings panels the i18n PR (tinyhumansai#1518)
surfaced as untested:

- BillingPanel (4 tests) — auto-open flow, error state, re-open click,
  back-navigation wiring.
- NotificationsPanel (6 tests) — DND skeleton/toggle/rollback,
  per-category toggles, redux preference seeding.
- NotificationRoutingPanel (6 tests) — pipeline stats card, per-provider
  load + retry hint, threshold formatting, setNotificationSettings
  payload shape.
- MessagingPanel (5 tests) — default-channel selector, loading + error
  states, ChannelSetupModal open/close, updatePreferences wiring.
- TeamPanel (8 tests) — list/active badge, create/join/switch/leave,
  manage navigation, localized error fallback.
- TeamMembersPanel (7 tests) — admin vs. non-admin affordances, role
  change + remove confirmations, empty state, route-context teamId
  resolution.
- TeamInvitesPanel (6 tests) — code rendering with state badges,
  generate/revoke/copy flows, admin gating, empty state.
- TeamManagementPanel (8 tests) — admin-only entry, not-found + access-
  denied branches, member/invite sub-route navigation, edit-name +
  delete confirm modals.

All 50 new tests pass; full panels suite is 230/26. `pnpm compile`
clean and ESLint clean on the new files.
@CodeGhost21 CodeGhost21 requested a review from a team May 18, 2026 10:56
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR adds comprehensive test suites for eight settings panel components: Billing, Messaging, NotificationRouting, Notifications, TeamInvites, TeamManagement, TeamMembers, and TeamPanel. Tests verify UI rendering, user interactions, async state flows, and API integration using mocked dependencies and React Testing Library assertions.

Changes

Settings Panels Test Coverage

Layer / File(s) Summary
Billing and Messaging Panel Tests
app/src/components/settings/panels/BillingPanel.test.tsx, app/src/components/settings/panels/MessagingPanel.test.tsx
BillingPanel tests verify mount-time openUrl calls, button interactions, and navigation. MessagingPanel tests validate loading/error states, channel selector rendering, modal open/close, and API calls for setting default channels. Both mock navigation hooks and external dependencies.
Notification Settings Panel Tests
app/src/components/settings/panels/NotificationRoutingPanel.test.tsx, app/src/components/settings/panels/NotificationsPanel.test.tsx
NotificationRoutingPanel tests verify stats card rendering, provider threshold display, toggle interactions, and per-provider error states. NotificationsPanel tests validate category and DND toggles, optimistic updates, rollback on failure, and Redux preference mapping. Both mock notification services and provide Redux store builders.
Team Management Panel Tests
app/src/components/settings/panels/TeamPanel.test.tsx, app/src/components/settings/panels/TeamManagementPanel.test.tsx, app/src/components/settings/panels/TeamMembersPanel.test.tsx, app/src/components/settings/panels/TeamInvitesPanel.test.tsx
TeamPanel tests cover team list rendering, create/join/leave/switch flows, manage navigation, and error handling. TeamManagementPanel tests verify settings/deletion modals and sub-route navigation. TeamMembersPanel tests validate member rendering, role-change/remove confirmation flows, and admin-gating. TeamInvitesPanel tests verify invite generation, revocation, copy-to-clipboard, and empty states. All use mocked team API and core state provider with fixture builders.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #1870: This PR directly addresses test coverage for the untested settings panel components referenced in the issue backfill.

Suggested labels

working

Suggested reviewers

  • graycyrus

Poem

🐰 Eight panels tested end to end,
With mocks and flows that always blend,
Billing, messaging, notifications too,
Teams and invites—all tried and true!
From billing dashes to team embrace,
Coverage blooms in every place.

🚥 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 title accurately summarizes the main change: adding unit tests for multiple settings panels (team, billing, notifications). It's concise, clear, and directly reflects the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 18, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@app/src/components/settings/panels/TeamInvitesPanel.test.tsx`:
- Around line 120-123: The test is fragile because it clicks the first "Copy
invite code" button from screen.getAllByRole; instead scope the click to the
invite row that contains the text "ACTIVE-123" so order changes won't break the
test: locate the row element for "ACTIVE-123" (e.g. via
screen.getByText('ACTIVE-123') and its closest row/container), use
testing-library's within(row) to find the button by role/name
(within(row).getByRole('button', { name: 'Copy invite code' })), then call
fireEvent.click on that button.

In `@app/src/components/settings/panels/TeamManagementPanel.test.tsx`:
- Around line 155-157: The test currently clicks the last element from
screen.findAllByRole('button', { name: 'Delete Team' }) which is fragile;
instead scope the query to the confirmation modal/dialog: locate the dialog
(e.g., via screen.findByRole('dialog') or byAccessibleName if given), then use
within(dialog).getByRole('button', { name: 'Delete Team' }) or
within(dialog).findByRole to target and click the confirm button. Replace the
array-index click with this scoped query (referencing screen.findAllByRole,
fireEvent.click and using within from `@testing-library/react` to scope to the
dialog).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c4af7aa7-8dc6-4475-ab78-1a021f694a5e

📥 Commits

Reviewing files that changed from the base of the PR and between 70fdedc and 19e0efb.

📒 Files selected for processing (8)
  • app/src/components/settings/panels/BillingPanel.test.tsx
  • app/src/components/settings/panels/MessagingPanel.test.tsx
  • app/src/components/settings/panels/NotificationRoutingPanel.test.tsx
  • app/src/components/settings/panels/NotificationsPanel.test.tsx
  • app/src/components/settings/panels/TeamInvitesPanel.test.tsx
  • app/src/components/settings/panels/TeamManagementPanel.test.tsx
  • app/src/components/settings/panels/TeamMembersPanel.test.tsx
  • app/src/components/settings/panels/TeamPanel.test.tsx

Comment on lines +120 to +123
// Active invite is the first one in the list; its Copy button is the
// first "Copy invite code" button.
const copyBtns = screen.getAllByRole('button', { name: 'Copy invite code' });
fireEvent.click(copyBtns[0]);

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid order-coupled selection for the copy action.

Line 122 + Line 123 rely on the first matching button, which can silently target the wrong invite if list order changes. Prefer scoping the click to the row containing ACTIVE-123 so this test stays stable.

As per coding guidelines, “Keep tests deterministic: avoid real network calls, time-sensitive flakes, or hidden global state.”

🤖 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 `@app/src/components/settings/panels/TeamInvitesPanel.test.tsx` around lines
120 - 123, The test is fragile because it clicks the first "Copy invite code"
button from screen.getAllByRole; instead scope the click to the invite row that
contains the text "ACTIVE-123" so order changes won't break the test: locate the
row element for "ACTIVE-123" (e.g. via screen.getByText('ACTIVE-123') and its
closest row/container), use testing-library's within(row) to find the button by
role/name (within(row).getByRole('button', { name: 'Copy invite code' })), then
call fireEvent.click on that button.

Comment on lines +155 to +157
const buttons = await screen.findAllByRole('button', { name: 'Delete Team' });
// The last one rendered is the confirmation button inside the modal.
fireEvent.click(buttons[buttons.length - 1]);

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Target the confirm button via dialog scope, not array index.

Line 157 clicks the last "Delete Team" button found, which is fragile if button order changes. Scope the query to the confirmation modal/dialog and click that specific action.

As per coding guidelines, “Keep tests deterministic: avoid real network calls, time-sensitive flakes, or hidden global state.”

🤖 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 `@app/src/components/settings/panels/TeamManagementPanel.test.tsx` around lines
155 - 157, The test currently clicks the last element from
screen.findAllByRole('button', { name: 'Delete Team' }) which is fragile;
instead scope the query to the confirmation modal/dialog: locate the dialog
(e.g., via screen.findByRole('dialog') or byAccessibleName if given), then use
within(dialog).getByRole('button', { name: 'Delete Team' }) or
within(dialog).findByRole to target and click the confirm button. Replace the
array-index click with this scoped query (referencing screen.findAllByRole,
fireEvent.click and using within from `@testing-library/react` to scope to the
dialog).

@senamakel senamakel merged commit 14ee688 into tinyhumansai:main May 20, 2026
28 of 30 checks passed
mtkik pushed a commit to mtkik/openhuman-meet that referenced this pull request May 21, 2026
CodeGhost21 added a commit to CodeGhost21/openhuman that referenced this pull request May 22, 2026
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backfill unit tests for intelligence/memory components (i18n coverage gap from #1518)

2 participants