Skip to content

Feature: Core Component & Service API Test Coverage (vertex app)#3694

Merged
Baalmart merged 21 commits into
stagingfrom
unit-testing-setup
Jun 28, 2026
Merged

Feature: Core Component & Service API Test Coverage (vertex app)#3694
Baalmart merged 21 commits into
stagingfrom
unit-testing-setup

Conversation

@Codebmk

@Codebmk Codebmk commented Jun 28, 2026

Copy link
Copy Markdown
Member

Description

This pull request drastically expands our frontend test suite, introducing extensive unit test coverage for our custom React hooks, shared components, shadcn UI elements, and API service boundaries. These changes ensure our core rendering and network mechanisms are highly robust and validated offline without relying on staging backend services. (Note: The core Vitest infrastructure setup and CI/CD automation were addressed in a previous PR.)

Key Changes

1. UI & Component Testing

  • Core UI coverage: Tested 30+ Radix/shadcn UI components (Dialog, Tooltip, Select, Button, Accordion, etc.), verifying user-event interactions, state changes, and accessibility-compliant rendering.
  • Shared Abstractions: Extracted robust unit tests for shared functional wrappers like ReusableTable, ReusableSelectInput, ReusableButton, and ReusableFileUpload. Removed obsolete defaultProps in ReusableTable for strict mode compliance.
  • Warning Remediation: Proactively resolved React DOM nesting warnings and accessibility labeling issues discovered during testing.

2. API Boundary & Mock Infrastructure

  • Mock Factories: Added apiResponseFactory.ts and nextAuth.ts mocks to simulate full HTTP/Auth environments natively, removing external mock adapter dependencies.
  • Proxy Validation: Validated the createProxyHandler (App Router) and createSecureApiClient (Axios interceptors), asserting accurate token injections, network degradation error handling, and 401 session-clear behaviors.
  • Service Layer: Achieved 100% mocked coverage on network-service.ts, onboardingService.ts, and core utilities.

3. Redux & Hook Architecture

  • State Initialization: Refactored store.ts to cleanly use combineReducers, allowing test suites to spin up isolated Redux trees and reset state reliably.
  • Hook Validations: Added tests for stateful utilities, platform detection fallbacks, and banner severity assertions.

Commits Included

  • d845948 Update changelog.md
  • df6784a Add tests for network, onboarding, proxy, platform
  • 1a27e89 Update tests and remove ReusableTable defaultProps
  • 96acc8e Add unit tests for UI components
  • ec983b1 Add tests for shared and UI components
  • 7be62ca Assert info severity in banner test
  • b69c38a Use combineReducers to create root reducer
  • 8ce1def Add hook tests and test utilities

Verification

  • Run npm run test to execute the 250+ new unit tests. Ensure a 100% pass rate.
  • Validated that the newly added API mocks successfully replicate complex error conditions (404s, timeouts) accurately offline.

Summary by CodeRabbit

  • Documentation
    • Added an updated changelog entry and testing guidance for the latest release.
  • Tests
    • Expanded automated coverage across many UI components, shared controls, hooks, and API-related utilities.
    • Added stronger interaction, accessibility, and error-state checks, plus reusable test helpers and mocks.
  • Chores
    • Added CI checks for type validation and test runs with coverage reporting.

Codebmk added 10 commits June 28, 2026 15:12
Add comprehensive unit tests for proxyConfig, vertex-config, useContextAwareRouting, api-routing, and utils to improve coverage and validate edge cases. Refactor useContextAwareRouting by extracting isRouteAccessible into a standalone exported helper and update the hook to call it with the sidebar config, making routing logic easier to test and reuse. Tests include environment mocking and logger stubs for validateProxyConfig and various cases for API URL resolution, path versioning, class name utilities, and elapsed duration calculations.
Add comprehensive unit tests for core hooks (useBannerWithDelay, useClipboard, useCohorts, useDevices, useGroups, usePermissions, useRecentlyVisited, useRoles, useServerSideTableState, useSites, useUserContext, useWindow). Introduce test helpers and mocks: renderWithProviders, renderHookWithProviders, createTestQueryClient, and setupStore (configuring relevant Redux slices). Also add simple test factories (device, organization, user) and various API/adapter/permission/banner mocks to standardize the testing environment and improve coverage for hook behavior.
Replace the inline reducer object with a combined `rootReducer` using Redux Toolkit's `combineReducers`. Adds the `combineReducers` import and constructs a single root reducer from user, sites, devices, grids, cohorts, and groups slices before passing it to `configureStore`. This centralizes reducer composition and makes extending or replacing reducers easier in tests and runtime.
Update useBannerWithDelay test to expect the banner payload to include severity: "info". The assertion in src/vertex/core/hooks/useBannerWithDelay.test.tsx now checks for { message: "Second", severity: "info" }, reflecting the banner payload change to include a default severity.
Add Vitest + React Testing Library unit tests for multiple shared and UI components. New tests cover shared components (ReusableButton, ReusableFileUpload, ReusableInputField, ReusableSelectInput, ReusableTable, ReusableToast, CardWrapper) and many UI primitives (accordion, alert, avatar, badge, banner, button, calendar, card, checkbox, combobox, command, date-picker, dialog, dropdown-menu, empty-state, form, input, label, popover, progress, select, skeleton, switch, tabs, textarea, tooltip). Tests assert accessibility roles, user interactions, and component states; and include necessary mocks for browser APIs (clipboard, PointerEvent, ResizeObserver, scrollIntoView) and app contexts (next/navigation, banner-context) to stabilize JSDOM test runs.
Add comprehensive Vitest + React Testing Library unit tests for various UI components under src/vertex/components/ui. Tests cover ErrorBoundary, alert dialog, chart container, collapsible, custom dialog, forbidden error/page, hcaptcha widget, hover card, multi-select, pagination, permission tooltip, scroll area, select field, separator, sheet, sonner/toaster, stepper, table, and toast. Includes necessary test-time mocks/stubs (ResizeObserver, PointerEvent, next/navigation, react-redux, env constants, tooltip/provider, next-themes, use-toast) and uses userEvent for interaction tests to validate rendering and basic behaviors.
Modify ReusableTable to use a plain <style> tag (remove styled-jsx) and remove the defaultProps block. Update several unit tests: ErrorBoundary test now prevents & cleans up window error events to avoid noisy logs; chart test imports vi, mocks recharts' ResponsiveContainer and wraps ChartContainer in a sized div to stabilize rendering; custom-dialog test adds Dialog title/description nodes; stepper test simplifies children to plain spans and removes unused StepTitle/StepDescription imports. These changes address test stability and clean up component defaults.
Add comprehensive unit tests and test utilities for core services and utils. New tests cover network-service (axios/fetch flows, errors, timeouts), onboardingService (secureApiProxy patch calls), proxyClient (request forwarding, auth/api token injection, error handling), secureApiProxyClient (axios interceptors, token handling, response error behavior), and platform (Mac architecture detection fallbacks). Also add test factories (apiResponseFactory) for mocking Axios/Fetch responses and next-auth mocks (nextAuth) to simplify session and server-session stubbing.
Refactor multiple UI test files to improve TypeScript types and remove unused imports. Replaced broad any casts with stricter types (unknown, never, Record<string, unknown>, and React.ReactNode) including vi.importActual typing and mock component props. Unified MockPointerEvent assignment to window.PointerEvent as never and adjusted ReusableTable test to use String(val) and a never cast for columns. Also removed unused imports (AvatarImage, Banner variants, userEvent) and added typed Tooltip mocks to reduce TS errors and improve type safety across tests.
@Codebmk Codebmk self-assigned this Jun 28, 2026
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

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

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

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

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 47ffef3c-aabe-4d10-8a05-9cab04bb0566

📥 Commits

Reviewing files that changed from the base of the PR and between e203f33 and b3998e9.

📒 Files selected for processing (18)
  • src/vertex/app/changelog.md
  • src/vertex/components/ui/ErrorBoundary.test.tsx
  • src/vertex/components/ui/chart.test.tsx
  • src/vertex/components/ui/combobox.test.tsx
  • src/vertex/components/ui/date-picker.test.tsx
  • src/vertex/components/ui/dialog.test.tsx
  • src/vertex/components/ui/dropdown-menu.test.tsx
  • src/vertex/components/ui/hcaptcha-widget.test.tsx
  • src/vertex/components/ui/multi-select.test.tsx
  • src/vertex/components/ui/popover.test.tsx
  • src/vertex/components/ui/select.test.tsx
  • src/vertex/core/hooks/useContextAwareRouting.test.ts
  • src/vertex/core/hooks/useContextAwareRouting.ts
  • src/vertex/core/services/network-service.test.ts
  • src/vertex/core/utils/platform.test.ts
  • src/vertex/core/utils/secureApiProxyClient.test.ts
  • src/vertex/lib/api-routing.test.ts
  • src/vertex/test/utils/domMocks.ts
📝 Walkthrough

Walkthrough

Adds a comprehensive Vitest + React Testing Library test suite across the src/vertex codebase, covering UI primitives, shared wrapper components, custom hooks, API proxy utilities, services, and routing helpers. Introduces shared test infrastructure (render utilities, mock factories, QueryClient config, NextAuth mocks). Also exports isRouteAccessible from useContextAwareRouting, removes ReusableTable.defaultProps, and switches its JSX style tag.

Changes

Vitest Testing Infrastructure and Coverage

Layer / File(s) Summary
Test utilities, factories, and mocks
src/vertex/test/utils/renderWithProviders.tsx, src/vertex/test/utils/renderHookWithProviders.tsx, src/vertex/test/mocks/queryClient.ts, src/vertex/test/mocks/nextAuth.ts, src/vertex/test/factories/*
Adds setupStore, renderWithProviders, renderHookWithProviders wrapping Redux + React Query providers; a test-optimized QueryClient; NextAuth session mocks and reset helper; and createMockUser, createMockDevice, createMockOrganization, mockAxiosSuccess/Error, mockFetchSuccess/Error factories.
isRouteAccessible extraction and test
src/vertex/core/hooks/useContextAwareRouting.ts, src/vertex/core/hooks/useContextAwareRouting.test.ts
Extracts route-access logic into an exported isRouteAccessible(route, sidebarConfig) helper; updates the hook's useEffect to call it with explicit sidebarConfig; adds table-driven tests.
Config validation tests
src/vertex/core/config/proxyConfig.test.ts, src/vertex/core/config/vertex-config.test.ts
Table-driven tests for getEndpointConfig, getAuthOptions, validateProxyConfig (env var presence/validity), and validateVertexConfig (org, adapter, auth, map constraints).
API routing and utility tests
src/vertex/lib/api-routing.test.ts, src/vertex/lib/utils.test.ts, src/vertex/core/utils/platform.test.ts
Tests for URL resolution/versioning helpers, cn/stripTrailingSlash/getElapsedDurationMapper utilities, and getMacArchitecture platform detection.
Proxy client and interceptor tests
src/vertex/core/utils/proxyClient.test.ts, src/vertex/core/utils/secureApiProxyClient.test.ts
Tests for createProxyHandler (method gating, forwarding, auth/token injection, error mapping) and secureApiProxyClient axios interceptors (JWT header, API token URL modification, network/auth event dispatch, 401 invalidation).
Service tests
src/vertex/core/services/network-service.test.ts, src/vertex/core/services/onboardingService.test.ts
Tests for networkService (requests, status update, submit with abort/timeout) and onboardingService (user/group patch with endpoint, payload, header assertions).
Custom hook tests
src/vertex/core/hooks/use*.test.tsx
Tests for useBannerWithDelay, useClipboard, useCohorts, useDevices, useGroups, usePermissions, useRecentlyVisited, useRoles, useServerSideTableState, useSites, useUserContext, useWindowSize.
Shared wrapper component tests + ReusableTable fix
src/vertex/components/shared/*/..., src/vertex/components/shared/table/ReusableTable.tsx
Tests for ReusableButton, CardWrapper, ReusableFileUpload, ReusableInputField, ReusableSelectInput, ReusableTable, ReusableToast; removes ReusableTable.defaultProps and switches <style jsx> to <style>.
UI component tests
src/vertex/components/ui/*.test.tsx
Tests for all UI primitives and composites: ErrorBoundary, Accordion, AlertDialog, Alert, Avatar, Badge, Banner, Button, Calendar, Card, Chart, Checkbox, Collapsible, ComboBox, Command, CustomDialog, DatePicker, Dialog, DropdownMenu, EmptyState, ForbiddenError/Page, Form, HCaptchaWidget, HoverCard, Input, Label, MultiSelect, Pagination, PermissionTooltip, Popover, Progress, ScrollArea, Select/SelectField, Separator, Sheet, Skeleton, Sonner, Stepper, Switch, Table, Tabs, Textarea, Toast, Toaster, Tooltip.
Changelog
src/vertex/app/changelog.md
Adds a v2.0.8 entry documenting the Vitest/RTL setup, CI workflows, test coverage additions, and API boundary testing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • airqo-platform/AirQo-frontend#3572: Refactored AccordionItem to use forwardRef, which is directly exercised by the new accordion.test.tsx suite added in this PR.
  • airqo-platform/AirQo-frontend#3613: Introduced or refactored API routing helpers (resolveApiOrigin, resolveVersionedApiPath) that are directly tested by the new api-routing.test.ts suite.

Suggested labels

ready for review, feature, vertex

Suggested reviewers

  • Baalmart
  • OchiengPaul442

Poem

🧪 No more cowboy code flying blind,
Components and hooks now tested and lined.
Mock factories spin up devices and users,
Proxy clients checked — no more abusers.
🎉 Green bars ahead, the CI sings,
Coverage achieved on all the things!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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: expanded core component, hook, and service API test coverage in the vertex app.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch unit-testing-setup

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@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: 11

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/vertex/components/shared/table/ReusableTable.tsx (1)

1475-1479: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the scrollbar rule scoped to this table

<style> makes .scrollbar-hide global, so any other element using that class will pick up this scrollbar suppression too. Switch back to style jsx unless the global leak is intentional.

💡 Minimal fix
-      <style>{`
+      <style jsx>{`
       .scrollbar-hide::-webkit-scrollbar {
         display: none;
       }
     `}</style>
🤖 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 `@src/vertex/components/shared/table/ReusableTable.tsx` around lines 1475 -
1479, The scrollbar suppression rule is leaking globally because the plain style
block makes .scrollbar-hide apply outside ReusableTable. Update the style usage
in ReusableTable to be component-scoped again by switching back to style jsx,
keeping the scrollbar-hiding rule local to this table only. Use the existing
ReusableTable style block and the .scrollbar-hide selector as the place to fix.
🟡 Minor comments (12)
src/vertex/app/changelog.md-15-16 (1)

15-16: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

"Replaced legacy test runners" is misleading.

The PR objectives state this "expands the frontend test suite" and "adds a comprehensive Vitest + RTL test suite" — there's no evidence that existing runners were removed or replaced. This wording could mislead consumers into thinking a migration occurred rather than additive coverage. Consider "Added Vitest & React Testing Library alongside existing test infrastructure" or similar.

🤖 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 `@src/vertex/app/changelog.md` around lines 15 - 16, Update the changelog entry
in changelog.md to avoid implying a migration: the phrase in the “Vitest & React
Testing Library” bullet should not say “Replaced legacy test runners.” Instead,
revise it to reflect that Vitest and React Testing Library were added alongside
the existing test infrastructure. Keep the “CI/CD Pipeline” bullet unchanged
unless needed for wording consistency.
src/vertex/test/utils/renderHookWithProviders.tsx-8-14 (1)

8-14: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Don't let renderOptions.wrapper replace the providers.

Line 32 spreads renderOptions after wrapper: Wrapper, so any caller-provided wrapper drops the Redux and Query providers entirely. This helper should either omit wrapper from its public options or compose it explicitly.

Suggested fix
-interface ExtendedRenderHookOptions<Props> extends RenderHookOptions<Props> {
+interface ExtendedRenderHookOptions<Props>
+  extends Omit<RenderHookOptions<Props>, "wrapper"> {
   preloadedState?: any;
 }
@@
   return {
     store,
     queryClient,
-    ...renderHook(renderCallback, { wrapper: Wrapper, ...renderOptions }),
+    ...renderHook(renderCallback, { ...renderOptions, wrapper: Wrapper }),
   };
 }

Also applies to: 32-32

🤖 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 `@src/vertex/test/utils/renderHookWithProviders.tsx` around lines 8 - 14, The
renderHookWithProviders helper is letting a caller-supplied
renderOptions.wrapper override the internal provider wrapper, which removes the
Redux and Query providers. Update renderHookWithProviders so wrapper cannot be
replaced from the public options, or explicitly compose any external wrapper
with the existing Wrapper used for providers. Keep the fix centered on
renderHookWithProviders and the Wrapper/renderOptions spread so the providers
are always preserved.
src/vertex/test/utils/renderWithProviders.tsx-14-17 (1)

14-17: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the provider wrapper authoritative.

ExtendedRenderOptions still allows wrapper, and Line 52 lets it override Wrapper. That means a custom wrapper can remove the Redux/React Query providers and make tests stop reflecting the real app setup.

Suggested fix
-interface ExtendedRenderOptions extends Omit<RenderOptions, "queries"> {
+interface ExtendedRenderOptions extends Omit<RenderOptions, "queries" | "wrapper"> {
   preloadedState?: any;
   route?: string;
 }
@@
-  return { store, queryClient, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
+  return { store, queryClient, ...render(ui, { ...renderOptions, wrapper: Wrapper }) };
 }

Also applies to: 52-52

🤖 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 `@src/vertex/test/utils/renderWithProviders.tsx` around lines 14 - 17,
`ExtendedRenderOptions` currently still inherits `wrapper`, and
`renderWithProviders` lets the caller-supplied wrapper override the built-in
`Wrapper`, which can bypass the Redux and React Query providers. Update
`ExtendedRenderOptions` to exclude `wrapper` and keep `Wrapper` authoritative
inside `renderWithProviders` so tests always use the app-style provider setup.
src/vertex/test/mocks/nextAuth.ts-13-28 (1)

13-28: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Deep-merge user overrides here.

Right now a partial user override replaces the whole default user object. A call like createMockSession({ user: { privilege: "admin" } }) drops id, accessToken, and the rest of the defaults, which makes shared auth tests easy to misconfigure.

Suggested fix
-export const createMockSession = (overrides = {}) => ({
-  user: {
-    id: "test-user-id",
-    accessToken: "test-access-token",
-    userName: "testuser",
-    organization: "test-org",
-    privilege: "user",
-    firstName: "Test",
-    lastName: "User",
-    country: "UG",
-    timezone: "Africa/Kampala",
-    phoneNumber: "123456789",
-  },
-  expires: "2099-01-01T00:00:00.000Z",
-  accessToken: "test-access-token",
-  ...overrides,
-});
+export const createMockSession = (overrides: Record<string, any> = {}) => ({
+  user: {
+    id: "test-user-id",
+    accessToken: "test-access-token",
+    userName: "testuser",
+    organization: "test-org",
+    privilege: "user",
+    firstName: "Test",
+    lastName: "User",
+    country: "UG",
+    timezone: "Africa/Kampala",
+    phoneNumber: "123456789",
+    ...(overrides.user ?? {}),
+  },
+  expires: "2099-01-01T00:00:00.000Z",
+  accessToken: "test-access-token",
+  ...overrides,
+});
🤖 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 `@src/vertex/test/mocks/nextAuth.ts` around lines 13 - 28, The
createMockSession helper is shallow-merging overrides, so a partial user
override replaces the default user object instead of merging into it. Update
createMockSession in nextAuth.ts to deep-merge the nested user field by
combining the default user object with overrides.user while still allowing
top-level overrides like expires and accessToken to apply normally.
src/vertex/core/hooks/useRecentlyVisited.test.tsx-36-69 (1)

36-69: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Wait for the effect-driven rerender before asserting visitedPages.

Lines 43-49 and Lines 66-68 assert synchronously after renderHookWithProviders(...), but useRecentlyVisited fills visitedPages from useEffect after mount and then updates again once isLoaded flips true. That makes these checks timing-dependent and prone to flaky failures. Wrap the expectations in waitFor(...) so they run after the hook settles.

🤖 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 `@src/vertex/core/hooks/useRecentlyVisited.test.tsx` around lines 36 - 69, The
`useRecentlyVisited` tests are asserting `visitedPages` too early, before the
hook’s `useEffect`-driven state updates have completed. Update the specs in
`useRecentlyVisited.test.tsx` to wait for the hook to settle after
`renderHookWithProviders(...)`, especially around the `visitedPages` checks in
the two affected test cases. Use `waitFor(...)` around the expectations so the
assertions run after `useRecentlyVisited` finishes loading and rerendering.
src/vertex/components/shared/toast/ReusableToast.test.tsx-7-10 (1)

7-10: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert a toast result, not the render container. render() always attaches container to the document, so this test passes even if <Toaster /> renders nothing. Trigger a toast and assert the message appears instead.

🤖 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 `@src/vertex/components/shared/toast/ReusableToast.test.tsx` around lines 7 -
10, The Toaster test currently only asserts that render() returned a container,
which does not verify any toast behavior. Update ReusableToast.test.tsx to
trigger an actual toast through the shared toast API used by the Toaster
component, then assert the expected toast message is rendered. Keep the test
focused on verifying visible toast output rather than the render container in
the Toaster component test.
src/vertex/components/ui/dialog.test.tsx-47-55 (1)

47-55: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The close path is never asserted.

After Line 54 the test exits immediately, so it still passes if the dialog never closes. Add a post-click assertion that the dialog is removed.

Suggested fix
-import { render, screen } from "`@testing-library/react`";
+import { render, screen, waitFor } from "`@testing-library/react`";
@@
     expect(screen.getByText("Dialog Title")).toBeInTheDocument();
     expect(screen.getByText("Dialog Description")).toBeInTheDocument();

     await userEvent.click(screen.getByRole("button", { name: "Close" }));
+    await waitFor(() =>
+      expect(screen.queryByRole("dialog")).not.toBeInTheDocument()
+    );
   });
🤖 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 `@src/vertex/components/ui/dialog.test.tsx` around lines 47 - 55, The dialog
test in dialog.test.tsx only verifies opening and never checks the close
behavior, so update the dialog interaction test around the “Open Dialog” and
“Close” clicks to assert the dialog is removed after closing. Use the existing
dialog query with the “dialog” role and add a post-click expectation after the
Close action so the test fails if the dialog remains visible.
src/vertex/components/ui/dropdown-menu.test.tsx-24-27 (1)

24-27: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Restore these JSDOM shims after the test.

These assignments mutate global browser APIs for the rest of the worker, so later suites can pass or fail depending on execution order. Please scope them with setup/teardown and restore the originals once this spec finishes.

🤖 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 `@src/vertex/components/ui/dropdown-menu.test.tsx` around lines 24 - 27, The
JSDOM shims in dropdown-menu.test.tsx are mutating global browser APIs for the
whole worker, so move them into test setup/teardown and restore the original
values after the spec runs. Update the dropdown menu test suite to capture the
existing PointerEvent, scrollIntoView, hasPointerCapture, and
releasePointerCapture implementations before overriding them, apply the mocks in
the suite setup, and cleanly restore them in teardown so later tests are
unaffected.
src/vertex/components/ui/multi-select.test.tsx-10-17 (1)

10-17: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Make the PointerEvent shim accept an optional init object.

new PointerEvent(type) is valid, but this mock requires props and dereferences it immediately. Default it to {} so tests don’t fail on an argument shape the browser allows.

Suggested fix
 class MockPointerEvent extends Event {
   button: number;
   ctrlKey: boolean;
   pointerType: string;
 
-  constructor(type: string, props: PointerEventInit) {
+  constructor(type: string, props: PointerEventInit = {}) {
     super(type, props);
-    this.button = props.button || 0;
-    this.ctrlKey = props.ctrlKey || false;
-    this.pointerType = props.pointerType || "mouse";
+    this.button = props.button ?? 0;
+    this.ctrlKey = props.ctrlKey ?? false;
+    this.pointerType = props.pointerType ?? "mouse";
   }
 }
🤖 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 `@src/vertex/components/ui/multi-select.test.tsx` around lines 10 - 17, The
PointerEvent shim in MockPointerEvent is too strict because its constructor
requires a props object and immediately reads from it, but native PointerEvent
allows new PointerEvent(type) with no init. Update the MockPointerEvent
constructor to accept an optional init object by defaulting the parameter to an
empty object, and keep the existing field assignments for button, ctrlKey, and
pointerType using that fallback so the multi-select tests don’t break on valid
browser-like usage.
src/vertex/components/ui/stepper.test.tsx-6-22 (1)

6-22: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The test never proves index affects rendering.

Right now it only checks that child text exists, so it would still pass if Stepper ignored index completely. Please add at least one assertion that changes with the active step 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 `@src/vertex/components/ui/stepper.test.tsx` around lines 6 - 22, The Stepper
test only verifies that the child content renders and does not confirm that the
active step changes with the index prop. Update the test in stepper.test.tsx
around Stepper and Step so it asserts a state that depends on index, such as the
active/current step styling or aria state for the step at index 1 versus the
others, using the rendered Stepper output to prove the prop affects rendering.
src/vertex/components/ui/select-field.test.tsx-20-23 (1)

20-23: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert the emitted value, not just that a callback happened.

toHaveBeenCalled() will still pass if SelectField sends the wrong payload shape or wrong selected value. Since this component’s contract is event.target.value, please assert the first call includes "1" so the test actually protects the onChange API.

Possible tightening
-    expect(handleChange).toHaveBeenCalled();
+    expect(handleChange).toHaveBeenCalledWith(
+      expect.objectContaining({
+        target: expect.objectContaining({ value: "1" }),
+      })
+    );
🤖 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 `@src/vertex/components/ui/select-field.test.tsx` around lines 20 - 23, The
SelectField test only checks that the change handler was called, which can miss
an incorrect payload shape or value; update the assertion in the test around the
userEvent.click flow to verify the first onChange call receives the expected
event.target.value of "1". Use the existing handleChange mock in
src/vertex/components/ui/select-field.test.tsx and tighten the expectation so it
validates the SelectField contract instead of just invocation.
src/vertex/components/ui/sonner.test.tsx-10-12 (1)

10-12: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

This assertion doesn't verify the Toaster rendered anything.

render() always gives you a container attached to the document, so this test still passes if Toaster returns null. Please assert for the rendered toaster node itself (for example the .toaster element wired by src/vertex/components/ui/sonner.tsx).

Possible tightening
   it("renders without crashing", () => {
     const { container } = render(<Toaster />);
-    expect(container).toBeInTheDocument();
+    expect(container.querySelector(".toaster")).toBeInTheDocument();
   });
🤖 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 `@src/vertex/components/ui/sonner.test.tsx` around lines 10 - 12, The current
test only checks the container from render(), so it can pass even if Toaster
renders nothing. Update the Toaster test in sonner.test.tsx to assert on the
actual toaster node produced by the Toaster component from sonner.tsx, such as
the .toaster element or another unique rendered selector, instead of checking
container presence.
🧹 Nitpick comments (6)
src/vertex/components/shared/table/ReusableTable.test.tsx (1)

23-31: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Type the test fixture instead of casting columns to never.
That cast sidesteps the ReusableTable column contract and can let this test stay green even if the public API breaks. Use a typed TableColumn<{ id: number; name: string }> fixture (or satisfies) here instead.

🤖 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 `@src/vertex/components/shared/table/ReusableTable.test.tsx` around lines 23 -
31, The test fixture in ReusableTable.test.tsx is bypassing the column contract
by casting columns to never, which can hide API breakage. Replace the cast with
a properly typed TableColumn fixture for the { id: number; name: string } shape,
or use satisfies to validate the columns object against ReusableTable’s expected
column type while keeping the test data aligned.
src/vertex/components/ui/combobox.test.tsx (1)

6-27: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Restore these DOM shims after the test.

Lines 18-27 mutate window and HTMLElement.prototype for the whole worker, so later UI tests can become order-dependent. Save the originals and restore them in teardown, or move the shims into shared test setup.

🤖 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 `@src/vertex/components/ui/combobox.test.tsx` around lines 6 - 27, The DOM
shims added in the combobox test setup mutate global browser APIs for the whole
worker, which can make later tests order-dependent. In the combobox test file,
save the original values for PointerEvent, scrollIntoView, hasPointerCapture,
releasePointerCapture, and ResizeObserver before overriding them, then restore
them in teardown (for example in afterEach/afterAll); alternatively, move these
shims into a shared test setup so they are applied consistently across tests.
src/vertex/components/ui/banner.test.tsx (1)

7-10: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Cover the wrapper-specific severity contract.

These assertions only prove shared Banner behavior. If SuccessBanner or InfoBanner forwarded the wrong severity, both tests would still pass. Add one expectation that distinguishes each wrapper from a plain Banner.

Also applies to: 13-18

🤖 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 `@src/vertex/components/ui/banner.test.tsx` around lines 7 - 10, The wrapper
tests for SuccessBanner and InfoBanner only verify shared Banner rendering, so
they miss the severity contract on each wrapper. Update the tests around
SuccessBanner and InfoBanner to assert the forwarded severity differs from a
plain Banner by checking the rendered severity-specific behavior or prop-driven
output. Use the wrapper component names SuccessBanner and InfoBanner, and the
shared Banner component, to add one distinguishing expectation per test that
would fail if the wrapper passed the wrong severity.
src/vertex/components/ui/progress.test.tsx (1)

6-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the Progress output, not the render container.

container always exists after render(), so this spec won't catch a broken value mapping. A DOM assertion tied to the rendered progress state would give this test real signal.

🤖 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 `@src/vertex/components/ui/progress.test.tsx` around lines 6 - 8, The current
`Progress` test only checks that `render()` returns a container, which won’t
validate the component’s `value` behavior. Update the spec in
`progress.test.tsx` to assert the rendered `Progress` output itself, using the
`Progress` component and its state/value mapping rather than `container`, so the
test fails if the displayed progress is incorrect.
src/vertex/components/ui/scroll-area.test.tsx (1)

5-9: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Scope the ResizeObserver shim to the test lifecycle.

This mutates a global at module load and never restores it, so later tests can inherit the stub accidentally. Prefer a per-test/per-suite stub with cleanup (vi.stubGlobal or save/restore the original) to keep the test worker isolated.

🤖 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 `@src/vertex/components/ui/scroll-area.test.tsx` around lines 5 - 9, The
`ResizeObserver` shim is being assigned to `window` at module load in
`scroll-area.test.tsx`, which leaves a global stub behind for other tests. Move
this setup into the test lifecycle around the affected suite (for example in the
same test file near the `ResizeObserver` usage) and restore the original global
afterward, or use `vi.stubGlobal` with cleanup in `afterEach`/`afterAll` so the
worker stays isolated.
src/vertex/components/ui/select.test.tsx (1)

25-28: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Restore these DOM shims after the test.

These prototype/global patches leak beyond this file and can mask failures in other Radix tests. Please scope them with setup/teardown rather than assigning them once at module load.

🤖 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 `@src/vertex/components/ui/select.test.tsx` around lines 25 - 28, The DOM shims
in the select test are being applied at module load and leak into other tests;
move the window.PointerEvent and HTMLElement.prototype patches into test
setup/teardown so they are scoped per test. Use the select test’s existing
fixture hooks (for example around the select component tests) to save the
original values before patching and restore them after each test, ensuring the
global/prototype changes do not persist beyond this file.
🤖 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 `@src/vertex/app/changelog.md`:
- Line 24: Update the changelog entry in the Core UI Components section to avoid
the unverifiable “full coverage” claim; in the changelog markdown, revise the
wording near the Core UI Components bullet so it accurately reflects the work as
comprehensive tests for 30+ shadcn/radix UI components rather than exhaustive
coverage.
- Around line 39-52: The changelog entry is inconsistent with the Vitest setup
path referenced by vitest.config.ts. Update src/vertex/app/changelog.md so the
new setup file path matches the actual setup file used by setupFiles in
vitest.config.ts, or adjust the config reference if the intended file is
src/vertex/test/setup.ts. Use the vitest.config.ts setupFiles setting and the
changelog’s new file list as the symbols to reconcile.

In `@src/vertex/components/ui/date-picker.test.tsx`:
- Around line 6-21: Scope the JSDOM shims in date-picker.test.tsx so they do not
leak across the worker: the MockPointerEvent assignment and the HTMLElement
prototype overrides should be saved/restored around the test lifecycle. Update
the test setup near MockPointerEvent and the
window.PointerEvent/scrollIntoView/hasPointerCapture/releasePointerCapture
patches to capture the originals and restore them in teardown (or extract them
into a helper with explicit cleanup). Ensure the cleanup runs after the test
suite so later tests see the real globals.

In `@src/vertex/components/ui/ErrorBoundary.test.tsx`:
- Around line 11-24: The ErrorBoundary test leaves `consoleError` and the window
`"error"` listener active if an assertion fails, which can affect later tests.
Update the `ErrorBoundary.test.tsx` flow so the setup and teardown around
`vi.spyOn(console, "error")`, `window.addEventListener("error", preventError)`,
and `window.removeEventListener("error", preventError)` always run in guaranteed
cleanup, such as a `try/finally` or test hooks, while keeping the `render` and
assertion for `ThrowError` inside the protected body.

In `@src/vertex/components/ui/hcaptcha-widget.test.tsx`:
- Around line 12-15: The current test in HCaptchaWidget is only asserting on
Testing Library’s container, so it will pass even if the widget renders nothing.
Update the test around HCaptchaWidget to verify a concrete captcha render
instead, preferably by mocking the hCaptcha component and asserting it is
rendered with the expected props for the enabled/site-key path. Use the
HCaptchaWidget and the mocked hCaptcha component symbols to locate and replace
the ineffective container-based assertion.

In `@src/vertex/components/ui/popover.test.tsx`:
- Around line 2-21: The global DOM shims added in the popover test setup are not
being restored, so they leak into later tests. In the popover test suite,
capture the original values for window.PointerEvent and the patched
HTMLElement.prototype methods before overriding them, then restore them in an
afterEach or afterAll cleanup within the same test file. Keep the fix localized
to the popover test helpers so the behavior of Popover, PopoverContent, and
PopoverTrigger stays unchanged while preventing cross-test pollution.

In `@src/vertex/core/hooks/useContextAwareRouting.ts`:
- Around line 29-36: The base-route lookup in useContextAwareRouting is only
using the first path segment, so nested routes under multi-segment parents are
not matching the intended sidebar config. Update the route matching logic around
basePath/baseRoute to derive the correct configured parent for routes like
/admin/networks/requests/42 and /devices/my-devices/123, then use that key to
check sidebarConfig instead of falling back to true. Keep the fix localized to
the useContextAwareRouting hook and its routeToSidebarConfig lookup.

In `@src/vertex/core/services/network-service.test.ts`:
- Around line 66-120: The negative-path tests in
networkService.updateNetworkRequestStatus and
networkService.submitNetworkRequest only assert inside catch blocks, so they can
pass even if the promise resolves. Add an explicit failure path after each
awaited call (for example, in the try block or immediately after the await) so
the test fails when the request unexpectedly succeeds, while keeping the
existing error assertions for the catch path.

In `@src/vertex/core/utils/platform.test.ts`:
- Around line 19-28: The test for getMacArchitecture mutates global.window and
only restores it after the await/assertion, so a failure can leave the global
deleted and break later cleanup. Update this test case to wrap the deletion and
assertion in a try/finally block so global.window is always restored, even if
getMacArchitecture or expect throws.

In `@src/vertex/core/utils/secureApiProxyClient.test.ts`:
- Around line 82-96: Prime the cached auth state in secureApiProxyClient.test.ts
before exercising getResponseError(), since this test currently verifies 401
invalidation without first storing a token. Use the existing hasValidToken and
interceptors.getResponseError symbols to set up a valid token/session state
before calling the interceptor, then assert that the 401 path clears it by
checking hasValidToken() becomes false after the auth-token-expired event is
dispatched.

In `@src/vertex/lib/api-routing.test.ts`:
- Around line 32-42: Isolate the resolveApiOrigin precedence tests from ambient
environment variables so the cases don’t inherit host values like API_BASE_URL
or NEXT_PUBLIC_*. Update the envCases loop in api-routing.test.ts to clear the
routing-related keys before applying each test env, or temporarily replace
process.env with only the vars under test, so resolveApiOrigin() is validated
against just the intended precedence inputs.

---

Outside diff comments:
In `@src/vertex/components/shared/table/ReusableTable.tsx`:
- Around line 1475-1479: The scrollbar suppression rule is leaking globally
because the plain style block makes .scrollbar-hide apply outside ReusableTable.
Update the style usage in ReusableTable to be component-scoped again by
switching back to style jsx, keeping the scrollbar-hiding rule local to this
table only. Use the existing ReusableTable style block and the .scrollbar-hide
selector as the place to fix.

---

Minor comments:
In `@src/vertex/app/changelog.md`:
- Around line 15-16: Update the changelog entry in changelog.md to avoid
implying a migration: the phrase in the “Vitest & React Testing Library” bullet
should not say “Replaced legacy test runners.” Instead, revise it to reflect
that Vitest and React Testing Library were added alongside the existing test
infrastructure. Keep the “CI/CD Pipeline” bullet unchanged unless needed for
wording consistency.

In `@src/vertex/components/shared/toast/ReusableToast.test.tsx`:
- Around line 7-10: The Toaster test currently only asserts that render()
returned a container, which does not verify any toast behavior. Update
ReusableToast.test.tsx to trigger an actual toast through the shared toast API
used by the Toaster component, then assert the expected toast message is
rendered. Keep the test focused on verifying visible toast output rather than
the render container in the Toaster component test.

In `@src/vertex/components/ui/dialog.test.tsx`:
- Around line 47-55: The dialog test in dialog.test.tsx only verifies opening
and never checks the close behavior, so update the dialog interaction test
around the “Open Dialog” and “Close” clicks to assert the dialog is removed
after closing. Use the existing dialog query with the “dialog” role and add a
post-click expectation after the Close action so the test fails if the dialog
remains visible.

In `@src/vertex/components/ui/dropdown-menu.test.tsx`:
- Around line 24-27: The JSDOM shims in dropdown-menu.test.tsx are mutating
global browser APIs for the whole worker, so move them into test setup/teardown
and restore the original values after the spec runs. Update the dropdown menu
test suite to capture the existing PointerEvent, scrollIntoView,
hasPointerCapture, and releasePointerCapture implementations before overriding
them, apply the mocks in the suite setup, and cleanly restore them in teardown
so later tests are unaffected.

In `@src/vertex/components/ui/multi-select.test.tsx`:
- Around line 10-17: The PointerEvent shim in MockPointerEvent is too strict
because its constructor requires a props object and immediately reads from it,
but native PointerEvent allows new PointerEvent(type) with no init. Update the
MockPointerEvent constructor to accept an optional init object by defaulting the
parameter to an empty object, and keep the existing field assignments for
button, ctrlKey, and pointerType using that fallback so the multi-select tests
don’t break on valid browser-like usage.

In `@src/vertex/components/ui/select-field.test.tsx`:
- Around line 20-23: The SelectField test only checks that the change handler
was called, which can miss an incorrect payload shape or value; update the
assertion in the test around the userEvent.click flow to verify the first
onChange call receives the expected event.target.value of "1". Use the existing
handleChange mock in src/vertex/components/ui/select-field.test.tsx and tighten
the expectation so it validates the SelectField contract instead of just
invocation.

In `@src/vertex/components/ui/sonner.test.tsx`:
- Around line 10-12: The current test only checks the container from render(),
so it can pass even if Toaster renders nothing. Update the Toaster test in
sonner.test.tsx to assert on the actual toaster node produced by the Toaster
component from sonner.tsx, such as the .toaster element or another unique
rendered selector, instead of checking container presence.

In `@src/vertex/components/ui/stepper.test.tsx`:
- Around line 6-22: The Stepper test only verifies that the child content
renders and does not confirm that the active step changes with the index prop.
Update the test in stepper.test.tsx around Stepper and Step so it asserts a
state that depends on index, such as the active/current step styling or aria
state for the step at index 1 versus the others, using the rendered Stepper
output to prove the prop affects rendering.

In `@src/vertex/core/hooks/useRecentlyVisited.test.tsx`:
- Around line 36-69: The `useRecentlyVisited` tests are asserting `visitedPages`
too early, before the hook’s `useEffect`-driven state updates have completed.
Update the specs in `useRecentlyVisited.test.tsx` to wait for the hook to settle
after `renderHookWithProviders(...)`, especially around the `visitedPages`
checks in the two affected test cases. Use `waitFor(...)` around the
expectations so the assertions run after `useRecentlyVisited` finishes loading
and rerendering.

In `@src/vertex/test/mocks/nextAuth.ts`:
- Around line 13-28: The createMockSession helper is shallow-merging overrides,
so a partial user override replaces the default user object instead of merging
into it. Update createMockSession in nextAuth.ts to deep-merge the nested user
field by combining the default user object with overrides.user while still
allowing top-level overrides like expires and accessToken to apply normally.

In `@src/vertex/test/utils/renderHookWithProviders.tsx`:
- Around line 8-14: The renderHookWithProviders helper is letting a
caller-supplied renderOptions.wrapper override the internal provider wrapper,
which removes the Redux and Query providers. Update renderHookWithProviders so
wrapper cannot be replaced from the public options, or explicitly compose any
external wrapper with the existing Wrapper used for providers. Keep the fix
centered on renderHookWithProviders and the Wrapper/renderOptions spread so the
providers are always preserved.

In `@src/vertex/test/utils/renderWithProviders.tsx`:
- Around line 14-17: `ExtendedRenderOptions` currently still inherits `wrapper`,
and `renderWithProviders` lets the caller-supplied wrapper override the built-in
`Wrapper`, which can bypass the Redux and React Query providers. Update
`ExtendedRenderOptions` to exclude `wrapper` and keep `Wrapper` authoritative
inside `renderWithProviders` so tests always use the app-style provider setup.

---

Nitpick comments:
In `@src/vertex/components/shared/table/ReusableTable.test.tsx`:
- Around line 23-31: The test fixture in ReusableTable.test.tsx is bypassing the
column contract by casting columns to never, which can hide API breakage.
Replace the cast with a properly typed TableColumn fixture for the { id: number;
name: string } shape, or use satisfies to validate the columns object against
ReusableTable’s expected column type while keeping the test data aligned.

In `@src/vertex/components/ui/banner.test.tsx`:
- Around line 7-10: The wrapper tests for SuccessBanner and InfoBanner only
verify shared Banner rendering, so they miss the severity contract on each
wrapper. Update the tests around SuccessBanner and InfoBanner to assert the
forwarded severity differs from a plain Banner by checking the rendered
severity-specific behavior or prop-driven output. Use the wrapper component
names SuccessBanner and InfoBanner, and the shared Banner component, to add one
distinguishing expectation per test that would fail if the wrapper passed the
wrong severity.

In `@src/vertex/components/ui/combobox.test.tsx`:
- Around line 6-27: The DOM shims added in the combobox test setup mutate global
browser APIs for the whole worker, which can make later tests order-dependent.
In the combobox test file, save the original values for PointerEvent,
scrollIntoView, hasPointerCapture, releasePointerCapture, and ResizeObserver
before overriding them, then restore them in teardown (for example in
afterEach/afterAll); alternatively, move these shims into a shared test setup so
they are applied consistently across tests.

In `@src/vertex/components/ui/progress.test.tsx`:
- Around line 6-8: The current `Progress` test only checks that `render()`
returns a container, which won’t validate the component’s `value` behavior.
Update the spec in `progress.test.tsx` to assert the rendered `Progress` output
itself, using the `Progress` component and its state/value mapping rather than
`container`, so the test fails if the displayed progress is incorrect.

In `@src/vertex/components/ui/scroll-area.test.tsx`:
- Around line 5-9: The `ResizeObserver` shim is being assigned to `window` at
module load in `scroll-area.test.tsx`, which leaves a global stub behind for
other tests. Move this setup into the test lifecycle around the affected suite
(for example in the same test file near the `ResizeObserver` usage) and restore
the original global afterward, or use `vi.stubGlobal` with cleanup in
`afterEach`/`afterAll` so the worker stays isolated.

In `@src/vertex/components/ui/select.test.tsx`:
- Around line 25-28: The DOM shims in the select test are being applied at
module load and leak into other tests; move the window.PointerEvent and
HTMLElement.prototype patches into test setup/teardown so they are scoped per
test. Use the select test’s existing fixture hooks (for example around the
select component tests) to save the original values before patching and restore
them after each test, ensuring the global/prototype changes do not persist
beyond this file.
🪄 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: 2b16e457-a666-4f85-9fe9-2b08223dfe8b

📥 Commits

Reviewing files that changed from the base of the PR and between 8f7cc33 and e203f33.

📒 Files selected for processing (87)
  • src/vertex/app/changelog.md
  • src/vertex/components/shared/button/ReusableButton.test.tsx
  • src/vertex/components/shared/card/CardWrapper.test.tsx
  • src/vertex/components/shared/fileupload/ReusableFileUpload.test.tsx
  • src/vertex/components/shared/inputfield/ReusableInputField.test.tsx
  • src/vertex/components/shared/select/ReusableSelectInput.test.tsx
  • src/vertex/components/shared/table/ReusableTable.test.tsx
  • src/vertex/components/shared/table/ReusableTable.tsx
  • src/vertex/components/shared/toast/ReusableToast.test.tsx
  • src/vertex/components/ui/ErrorBoundary.test.tsx
  • src/vertex/components/ui/accordion.test.tsx
  • src/vertex/components/ui/alert-dialog.test.tsx
  • src/vertex/components/ui/alert.test.tsx
  • src/vertex/components/ui/avatar.test.tsx
  • src/vertex/components/ui/badge.test.tsx
  • src/vertex/components/ui/banner.test.tsx
  • src/vertex/components/ui/button.test.tsx
  • src/vertex/components/ui/calendar.test.tsx
  • src/vertex/components/ui/card.test.tsx
  • src/vertex/components/ui/chart.test.tsx
  • src/vertex/components/ui/checkbox.test.tsx
  • src/vertex/components/ui/collapsible.test.tsx
  • src/vertex/components/ui/combobox.test.tsx
  • src/vertex/components/ui/command.test.tsx
  • src/vertex/components/ui/custom-dialog.test.tsx
  • src/vertex/components/ui/date-picker.test.tsx
  • src/vertex/components/ui/dialog.test.tsx
  • src/vertex/components/ui/dropdown-menu.test.tsx
  • src/vertex/components/ui/empty-state.test.tsx
  • src/vertex/components/ui/forbidden-error.test.tsx
  • src/vertex/components/ui/forbidden-page.test.tsx
  • src/vertex/components/ui/form.test.tsx
  • src/vertex/components/ui/hcaptcha-widget.test.tsx
  • src/vertex/components/ui/hover-card.test.tsx
  • src/vertex/components/ui/input.test.tsx
  • src/vertex/components/ui/label.test.tsx
  • src/vertex/components/ui/multi-select.test.tsx
  • src/vertex/components/ui/pagination.test.tsx
  • src/vertex/components/ui/permission-tooltip.test.tsx
  • src/vertex/components/ui/popover.test.tsx
  • src/vertex/components/ui/progress.test.tsx
  • src/vertex/components/ui/scroll-area.test.tsx
  • src/vertex/components/ui/select-field.test.tsx
  • src/vertex/components/ui/select.test.tsx
  • src/vertex/components/ui/separator.test.tsx
  • src/vertex/components/ui/sheet.test.tsx
  • src/vertex/components/ui/skeleton.test.tsx
  • src/vertex/components/ui/sonner.test.tsx
  • src/vertex/components/ui/stepper.test.tsx
  • src/vertex/components/ui/switch.test.tsx
  • src/vertex/components/ui/table.test.tsx
  • src/vertex/components/ui/tabs.test.tsx
  • src/vertex/components/ui/textarea.test.tsx
  • src/vertex/components/ui/toast.test.tsx
  • src/vertex/components/ui/toaster.test.tsx
  • src/vertex/components/ui/tooltip.test.tsx
  • src/vertex/core/config/proxyConfig.test.ts
  • src/vertex/core/config/vertex-config.test.ts
  • src/vertex/core/hooks/useBannerWithDelay.test.tsx
  • src/vertex/core/hooks/useClipboard.test.tsx
  • src/vertex/core/hooks/useCohorts.test.tsx
  • src/vertex/core/hooks/useContextAwareRouting.test.ts
  • src/vertex/core/hooks/useContextAwareRouting.ts
  • src/vertex/core/hooks/useDevices.test.tsx
  • src/vertex/core/hooks/useGroups.test.tsx
  • src/vertex/core/hooks/usePermissions.test.tsx
  • src/vertex/core/hooks/useRecentlyVisited.test.tsx
  • src/vertex/core/hooks/useRoles.test.tsx
  • src/vertex/core/hooks/useServerSideTableState.test.tsx
  • src/vertex/core/hooks/useSites.test.tsx
  • src/vertex/core/hooks/useUserContext.test.tsx
  • src/vertex/core/hooks/useWindow.test.tsx
  • src/vertex/core/services/network-service.test.ts
  • src/vertex/core/services/onboardingService.test.ts
  • src/vertex/core/utils/platform.test.ts
  • src/vertex/core/utils/proxyClient.test.ts
  • src/vertex/core/utils/secureApiProxyClient.test.ts
  • src/vertex/lib/api-routing.test.ts
  • src/vertex/lib/utils.test.ts
  • src/vertex/test/factories/apiResponseFactory.ts
  • src/vertex/test/factories/deviceFactory.ts
  • src/vertex/test/factories/organizationFactory.ts
  • src/vertex/test/factories/userFactory.ts
  • src/vertex/test/mocks/nextAuth.ts
  • src/vertex/test/mocks/queryClient.ts
  • src/vertex/test/utils/renderHookWithProviders.tsx
  • src/vertex/test/utils/renderWithProviders.tsx

Comment thread src/vertex/app/changelog.md Outdated
Comment thread src/vertex/app/changelog.md
Comment thread src/vertex/components/ui/date-picker.test.tsx Outdated
Comment thread src/vertex/components/ui/ErrorBoundary.test.tsx Outdated
Comment thread src/vertex/components/ui/hcaptcha-widget.test.tsx Outdated
Comment thread src/vertex/core/hooks/useContextAwareRouting.ts Outdated
Comment thread src/vertex/core/services/network-service.test.ts
Comment thread src/vertex/core/utils/platform.test.ts
Comment thread src/vertex/core/utils/secureApiProxyClient.test.ts
Comment thread src/vertex/lib/api-routing.test.ts
Codebmk added 10 commits June 28, 2026 17:12
Extract repeated JSDOM/window mock setup into a new test utility (src/vertex/test/utils/domMocks.ts) exposing setupPointerEventMock and setupResizeObserverMock. Replace inline MockPointerEvent/ResizeObserver and HTMLElement overrides across multiple UI tests (chart, combobox, date-picker, dialog, dropdown-menu, multi-select, popover, select) with imports and calls to the new utilities. The helpers install mocks in beforeAll and restore originals in afterAll to keep tests isolated and reduce duplication.
Wrap render and assertions in a try/finally block so window error listener removal and console.error mock restoration always run. This prevents leaking global state and makes the ErrorBoundary test more robust if render or assertions throw.
@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@Baalmart
Baalmart merged commit 7b984e4 into staging Jun 28, 2026
28 checks passed
@Baalmart
Baalmart deleted the unit-testing-setup branch June 28, 2026 18:08
@Baalmart Baalmart mentioned this pull request Jun 28, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants