Testing
π’ Smarter AI π’
AI Voice+ Test Suite
Total: 815 tests across 90 frontend + 6 edge function test files
Last updated: 2026-02-19
Utility Functions (85 tests)
UI Components (9 tests)
Dashboard Components (164 tests)
Admin Components (92 tests)
Settings Components (67 tests)
Chat Components (6 tests)
Auth & Routing (29 tests)
Pages (112 tests)
Running Tests
# Run all tests
npm run test
# or
bun run test
# Run tests in watch mode
npm run test:watch
# Run specific test file
npm run test src/lib/utils.test.ts
# Run tests with coverage
npm run test -- --coverageTest Infrastructure
Test Runner
Vitest 3.2.4
DOM Library
React Testing Library 16.3.2
User Events
@testing-library/user-event 14.6.1
DOM Environment
jsdom 20.0.3
Config
vitest.config.ts
Setup File
src/test/setup.ts
Supabase Mock
src/test/mocks/supabase.ts
Browser API Mocks (in setup.ts)
matchMediaResizeObserverIntersectionObserverwindow.scrollTo
Test Files Summary
Utility Functions (97 tests)
src/lib/utils.test.ts β 8 tests
1
cn merges class names
Basic Tailwind class merging
2
cn handles empty inputs
Empty string handling
3
cn handles undefined
Undefined value handling
4
cn merges conflicting classes
Tailwind conflict resolution
5
cn handles conditional classes
Boolean conditional merging
6
cn handles array of classes
Array input support
7
cn handles multiple arguments
Multiple argument support
8
cn handles null values
Null value handling
src/lib/validations.test.ts β 27 tests
1
loginSchema accepts valid email and password
Valid login credentials
2
loginSchema rejects invalid email
Email format validation
3
loginSchema rejects short password
Minimum password length
4
loginSchema trims email whitespace
Whitespace trimming
5
loginSchema rejects email over 255 chars
Email length limit
6
signupSchema accepts valid signup data
Valid signup data
7
signupSchema rejects short name
Name length minimum
8
signupSchema rejects short password
Minimum 8 characters
9
signupSchema rejects password over 72 chars
Password max length
10
signupSchema rejects when terms not agreed
Terms requirement
11
signupSchema rejects short clinic name
Clinic name minimum
12
businessBasicsSchema validates correct data
Valid business data
13
businessBasicsSchema accepts all valid types
Business type enum
14
businessBasicsSchema rejects invalid type
Invalid type rejection
15
businessBasicsSchema allows empty optional fields
Optional fields
16
businessBasicsSchema validates website URL
URL validation
17
businessBasicsSchema rejects invalid URL
Invalid URL rejection
18
contactFormSchema accepts valid data
Valid contact form
19
contactFormSchema rejects missing name
Required name field
20
contactFormSchema rejects invalid email
Email format validation
21
contactFormSchema rejects short message
Minimum message length
22
contactFormSchema rejects name over 100 chars
Name length limit
23
contactFormSchema rejects message over 2000 chars
Message length limit
24
contactFormSchema accepts optional phone
Optional phone field
25
contactFormSchema accepts optional company
Optional company field
26
contactFormSchema rejects phone over 20 chars
Phone length limit
27
contactFormSchema rejects company over 100 chars
Company length limit
src/lib/phone-utils.test.ts β 20 tests
1
formatPhoneForDisplay formats US numbers
US phone formatting
2
formatPhoneForDisplay formats UK numbers
UK phone formatting
3
formatPhoneForDisplay returns original for invalid
Invalid number fallback
4
formatPhoneForDisplay handles empty string
Empty input handling
5
normalizePhoneNumber adds country code
Country code normalization
6
normalizePhoneNumber preserves existing code
Existing code preservation
7
normalizePhoneNumber handles plus prefix
Plus prefix handling
8
normalizePhoneNumber strips formatting
Format stripping
9
validatePhoneNumber accepts valid numbers
Valid number validation
10
validatePhoneNumber rejects too short
Minimum length check
11
validatePhoneNumber rejects too long
Maximum length check
12
validatePhoneNumber rejects empty
Empty value rejection
13
getCountryFromNumber detects US
US country detection
14
getCountryFromNumber detects UK
UK country detection
15
getCountryFromNumber detects Iceland
Iceland country detection
16
getCountryFromNumber returns null for unknown
Unknown number handling
17
formatInternational formats correctly
International format
18
isValidE164 accepts valid E.164
E.164 format validation
19
isValidE164 rejects invalid format
Invalid E.164 rejection
20
maskPhoneNumber masks digits
Phone number masking
src/lib/script-security.test.ts β 36 tests
1-3
Basic validation
Empty script, valid analytics, valid chat widget
4-8
Dangerous pattern detection
eval(), document.cookie, window.location redirect, innerHTML, Function constructor
9-12
Warning pattern detection
fetch requests, XMLHttpRequest, postMessage, localStorage access
13-16
Known safe patterns
Google Analytics downgrade, Crisp chat recognition, Intercom recognition, HubSpot recognition
17-23
Trusted URLs feature
Skip warnings for trusted URLs, always block eval() even with trusted URLs, always block new Function() even with trusted URLs, match domain variations, case-insensitive matching, handle multiple trusted URLs, handle invalid URLs
24-29
Multiple issues
Report all issues found, aggregate warnings correctly, handle combined errors and warnings, separate error from warning severities
30-32
Edge cases
Handle very large scripts, handle scripts with special characters, handle malformed HTML
33-36
Script size validation
Warn about very large scripts, accept normal-sized scripts
(Also includes sanitizeForDisplay 4 tests and isValidScriptFormat 4 tests)
src/lib/cloud-storage.test.ts β 7 tests
1
returns S3 result when edge function succeeds
Happy path S3 upload
2
falls back to Supabase when S3 returns error
Error fallback
3
falls back to Supabase when S3 invoke throws
Exception fallback
4
throws when both S3 and Supabase fail
Double failure error
5
passes custom fileName in FormData
Custom filename support
6
generates unique fallback filename when no fileName provided
Auto-generated names
7
falls back when S3 returns success:false
Soft failure fallback
src/lib/admin-data-archive.test.ts β 5 tests
1
archives CSV data and returns upload result
Happy path S3 archival
2
falls back to Supabase storage when S3 unavailable
Fallback behavior
3
constructs File with correct MIME type for CSV
CSV MIME type
4
constructs File with correct MIME type for JSON
JSON MIME type
5
uses correct folder path with date
Folder path construction
UI Components (30 tests)
src/components/CommandPalette.test.tsx β 11 tests
1
opens on Cmd+K
Keyboard shortcut activation
2
shows Navigation heading when not in admin mode
Default mode heading
3
shows App Items heading in admin mode
Admin mode heading
4
shows Superadmin Items group in admin mode
Admin-only group
5
does not show Superadmin Items when not in admin mode
Group hidden
6
renders unique superadmin items
Organizations, Webhooks, etc.
7
renders navigation items
Dashboard, Calendar, Call Logs
8
renders Agent Apps group
Voice Agents, Convo+, AgentOne
9
does not show AI Assistant Settings
Removed item verification
10
renders Settings group
Billing, Security
11
calls onAdminTab when superadmin item clicked
Tab callback
src/components/ConfettiOverlay.test.tsx β 5 tests
1
renders nothing when inactive
Inactive state
2
renders particles when active
Active state rendering
3
has pointer-events-none class
Non-interactive overlay
4
calls onComplete after timeout
3s auto-dismiss
5
cleans up when deactivated
Deactivation cleanup
src/components/HCaptchaRuntime.test.tsx β 5 tests
1
fetches sitekey from edge function and renders captcha
Runtime fetch + render
2
calls onNotConfigured when edge function returns no siteKey
No key callback
3
calls onNotConfigured when edge function throws
Error callback
4
renders nothing while loading
Loading state
5
calls onNotConfigured when edge function returns error
Error response callback
UI Components β shadcn (9 tests)
src/components/ui/button.test.tsx β 9 tests
1
renders with default props
Default button rendering
2
renders with different variants
Variant prop support
3
renders with different sizes
Size prop support
4
renders as child component
asChild prop (Slot)
5
applies custom className
Custom class merging
6
handles click events
Click handler
7
can be disabled
Disabled state
8
renders with icon
Icon content rendering
9
supports ref forwarding
Ref forwarding
Dashboard Components (164 tests)
src/components/dashboard/CallCard.test.tsx β 17 tests
1-4
Basic rendering
Phone number, duration, outcome badge, date/time
5-8
Outcome variants
appointment_booked, missed, transferred, voicemail styles
9-11
Edge cases
Unknown caller, zero duration, null values
12-14
Direction
Inbound icon, outbound icon, direction display
15-17
Interaction
Click handler, transcript indicator, recording indicator
src/components/dashboard/MetricCard.test.tsx β 8 tests
1
renders label and value
Basic rendering
2
renders with icon
Icon prop support
3
renders trend indicator
Trend display
4
handles string values
String value support
5
handles zero value
Zero value display
6
handles large numbers
Large number formatting
7
applies custom className
Custom class support
8
renders subtitle
Subtitle display
src/components/dashboard/EmptyState.test.tsx β 6 tests
1
renders title and description
Basic content
2
renders icon
Icon display
3
renders action button
CTA button
4
handles action click
Click handler
5
renders without action
No-action variant
6
applies custom className
Custom styling
src/components/dashboard/AgentTemplates.test.tsx β 8 tests
1
renders template categories
Category tabs
2
renders template cards
Template card display
3
handles template selection
Selection callback
4
shows template description
Description text
5
shows template icon
Icon rendering
6
filters by category
Category filtering
7
shows all templates by default
Default view
8
handles empty category
Empty category state
src/components/dashboard/AgentAppsDropdown.test.tsx β 5 tests
1
renders Apps+ button even when no custom apps configured
Always-visible button
2
renders dropdown when apps exist
Dropdown display
3
expands to show apps when clicked
Expand behavior
4
collapses when clicked again
Collapse behavior
5
renders external links with correct attributes
External link behavior
src/components/dashboard/QuickAddDropdown.test.tsx β 10 tests
1
renders the Add button
Button display
2
shows 7 menu items on click
All items visible
3
navigates with ?action=create for New Appointment
Calendar deep link
4
navigates with ?action=create for Create Agent
Agents deep link
5
navigates to convo/spaces with ?action=create
Convo deep link
6
navigates to agentone/workspaces with ?action=create
AgentOne deep link
7
navigates with ?action=create for Client
Clients deep link
8
has data-tour attribute on trigger button
Tour target attribute
9
navigates to settings billing for Resources
Billing shortcut
10
navigates to settings integrations for MCP Server
MCP shortcut
src/components/dashboard/BottomNav.test.tsx β 8 tests
1
renders bottom nav with 5 items
Nav item display
2
opens More sheet on click
Sheet opening
3
shows Affiliates Earn 30%! in More sheet
Affiliate link display
4
Affiliates link opens in new tab
New tab attributes
5
shows Data Chat button in More sheet
Data Chat display
6
shows Docs link in More sheet
Docs link display
7
highlights active nav item
Active state styling
8
shows all more menu items
Full menu rendering
src/components/dashboard/DashboardSidebar.test.tsx β 9 tests
1
renders primary nav items
Nav item display
2
renders More button
More button display
3
shows overflow items in More popover
Popover content
4
shows Affiliates Earn 30%! in More popover
Affiliate link display
5
Affiliates link opens in new tab
New tab attributes
6
renders Docs external link
Docs link display
7
renders Settings nav item
Settings display
8
renders Data Chat button
Data Chat display
9
highlights active route
Active state styling
src/components/dashboard/AnalyticsSavingsCards.test.tsx β 7 tests
1
renders all three cards
Card count
2
displays missed calls count
Missed calls metric
3
displays transferred calls count
Transferred calls metric
4
calculates estimated savings
Savings calculation
5
handles zero values
Zero state
6
handles large numbers
Large number display
7
shows proper labels
Label text
src/components/dashboard/AIAgentLearningSection.test.tsx β 8 tests
1
renders learning section title
Title display
2
renders section description
Description text
3
renders appointment booking accordion
Accordion content
4
renders transfer calls section
Transfer section
5
renders multilingual section
Multilingual support
6
displays card structure correctly
Card structure
7
renders scheduling description
Schedule text
8
shows built-in guardrails accordion item
Guardrails section present
src/components/dashboard/AgentSkills.test.tsx β 9 tests
1
renders the agent skills card with A2A label
Updated title with A2A
2
shows description text
Capability tagging description
3
displays the A2A explainer
Workflow explainer block
4
displays existing skills
Skill name rendering
5
shows primary badge for primary skill
Primary badge
6
shows proficiency level labels instead of percentages
7-level dropdown (NoviceβMaster)
7
has input for adding new skills
Add skill input
8
renders proficiency select dropdowns for each skill
Select dropdown per skill
9
renders the See Flow button for A2A diagram
A2A flow diagram link
src/components/dashboard/AgentEditorForm.test.tsx β 10 tests
1
shows loading spinner initially
Loading state
2
renders Agent Details card
Card display
3
renders Voice & Language card
Voice section
4
renders Greeting Message card
Greeting section
5
renders AI Behavior & Instructions card
Instructions section
6
renders Compliance & Verification card
Compliance section
7
renders Reset to Default button
Reset greeting action
8
renders Cancel button
Cancel display
9
Cancel button calls onCancel
Cancel handler
10
renders Create Agent button for new agent
Create action
src/components/dashboard/NotificationBell.test.tsx β 9 tests
1
renders the bell icon button
Bell button rendering
2
shows red dot indicator when unread notifications exist
Red dot (bg-destructive) display
3
user variant only shows /dashboard notifications
User context filtering
4
admin variant only shows /admin notifications
Admin context filtering
5
shows Clear all button when notifications exist
Clear all action
6
calls delete mutation when Dismiss is clicked
Dismiss mutation call
7
applies admin variant styling with white text
Admin variant styling
8
fires a sonner toast when realtime notification arrives for matching context
Context-aware realtime toast
9
does NOT fire toast for admin notification on user bell
Cross-context toast suppression
src/components/dashboard/UpgradeBanner.test.tsx β 13 tests
1
renders nothing for active subscription
No banner when active
2
renders nothing for superadmin even if expired
Superadmin bypass
3
renders nothing while loading
Loading state
4
shows expired trial banner
Trial expired display
5
shows canceled subscription banner
Canceled display
6
shows trial expiring soon banner when β€3 days
Trial warning
7
shows singular day text for 1 day remaining
Singular text
8
does not show trial expiring banner when >3 days
No early warning
9
shows minutes exhausted banner
Minutes limit
10
shows storage full banner
Storage full blocking
11
shows storage warning banner
Storage 90% warning
12
renders nothing when storage is normal
Normal storage
13
does not show storage banners for superadmin
Superadmin bypass
src/components/dashboard/TwoFactorBanner.test.tsx β 3 tests
1
renders when no 2FA factors exist
Banner display
2
navigates to security tab on Set Up 2FA click
Correct URL with ?tab=security
3
dismisses when X is clicked
Dismiss behavior
Admin Components (110 tests)
src/components/admin/AdminMaintenance.test.tsx β 11 tests
1
renders the maintenance notice heading
Heading display
2
shows Live badge when notice is enabled
Live status badge
3
populates message textarea from fetched data
Data hydration
4
populates button label and URL inputs
Button config fields
5
renders 8 gradient picker buttons
Gradient picker count
6
renders preview section with message in preview span
Preview rendering
7
renders Save Notice button
Save CTA
8
disables save when message is empty
Empty message guard
9
shows Disabled badge when notice is off
Disabled status badge
10
shows loading state initially
Loading state
11
renders enable toggle switch
Toggle switch
src/components/admin/AdminFAQs.test.tsx β 10 tests
1
renders FAQ list
List display
2
shows add FAQ button
Action button
3
opens create dialog
Dialog opening
4
displays FAQ categories
Category badges
5
shows publish status
Publish toggle
6
handles edit action
Edit flow
7
handles delete action
Delete flow
8
shows empty state
No FAQs state
9
displays sort order
Sort display
10
filters by category
Category filter
src/components/admin/AdminGDPRRequests.test.tsx β 11 tests
1
renders requests table
Table display
2
shows status badges
Status indication
3
handles approve action
Approve flow
4
handles reject action
Reject flow
5
shows request details
Detail display
6
filters by status
Status filtering
7
shows empty state
No requests state
8
displays timestamps
Time display
9
shows user information
User info display
10
handles download link
Download URL
11
shows request type
Request type display
src/components/admin/AdminTestimonials.test.tsx β 6 tests
1
renders testimonial list
List display
2
shows add button
Action button
3
displays author info
Author details
4
shows publish status
Publish toggle
5
handles edit
Edit flow
6
handles delete
Delete flow
src/components/admin/AdminAISettings.test.tsx β 5 tests
1
renders AI provider section
Provider display
2
shows model selection
Model dropdown
3
displays API key field
API key input
4
shows active status
Status toggle
5
handles save
Save flow
src/components/admin/AdminS3Buckets.test.tsx β 7 tests
1
renders bucket configuration
Config display
2
shows add bucket button
Action button
3
displays bucket details
Detail display
4
handles test connection
Connection test
5
shows active status
Status toggle
6
handles edit
Edit flow
7
handles delete
Delete flow
src/components/admin/AgentAppsMenuEditor.test.tsx β 10 tests
1
renders empty state when no apps configured
Empty state
2
renders apps when provided
Entry list
3
adds a new app when clicking Add App Link
Add flow
4
removes an app when clicking delete button
Remove flow
5
updates app name when input changes
Name editing
6
updates app href when input changes
URL editing
7
shows title and description
Component display
8
moves app up when clicking move up button
Move up reorder
9
moves app down when clicking move down button
Move down reorder
10
disables move up on first item and move down on last
Boundary guards
src/components/admin/LandingSectionEditor.test.tsx β 8 tests
1
renders the landing section edits card
Component display
2
renders Sign In Page accordion item
Signin section present
3
renders Sign Up Page accordion item
Signup section present
4
shows signin fields when expanded
Signin field display
5
shows signup fields when expanded
Signup field display
6
calls updateField for signin heading
Signin heading edit
7
calls updateField for signup features
Signup features edit
8
displays existing signin form data values
Pre-filled values
src/components/admin/CustomScriptsEditor.test.tsx β 18 tests
1-4
Rendering
All sections, head textarea, body textarea, trusted URLs
5-10
Trusted URLs
Display badges, add URL, remove URL, validate URL format, duplicate prevention, empty input handling
11-14
Script editing
Head script change, body script change, character count, preview
15-18
Validation
Security issues alert, error badge, warning badge, safe script indicator
src/components/CustomScriptInjector.test.tsx β 8 tests
1
renders without config
No-config state
2
injects head scripts
Head script injection
3
injects body scripts
Body script injection
4
injects both scripts
Combined injection
5
cleans up on unmount
Cleanup behavior
6
handles non-script elements
Meta tag injection
7
works without admin privileges
Public config verification
8
injects scripts on all viewports including mobile
All-viewport injection
src/components/admin/AdminWebhooks.test.tsx β 8 tests
1
renders Webhooks title
Title display
2
renders description text
Description display
3
renders Add Webhook button
Action button
4
displays webhook URL
URL display
5
shows Active badge
Status badge
6
shows event badges
Event tag display
7
shows empty state when no webhooks
Empty state
8
shows Create First Webhook button
Empty state CTA
src/components/admin/AdminDiscountCodes.test.tsx β 8 tests
1
renders Discount Codes title
Title display
2
renders Add Code button
Action button
3
renders Bulk Generate button
Bulk action
4
displays discount code
Code display
5
shows active badge
Status badge
6
shows empty state when no codes
Empty state
7
renders batch summary row after bulk generation
Batch summary
8
batch dropdown trigger is accessible via aria-label
Dropdown trigger
src/components/admin/AdminAnnouncements.test.tsx β 11 tests
1
renders the heading after loading
Heading display
2
renders the add button
Add button display
3
opens the create dialog
Dialog opening
4
shows category select in create dialog
Category dropdown
5
shows poll type picker when poll category selected
Poll type UI visibility
6
allows selecting a poll type
Poll type selection
7
shows poll type previews
Preview emoji display
8
does not show poll type picker for general category
Conditional UI
9
shows empty state when no announcements
Empty state
10
renders poll badge on poll announcements
Poll badge display
11
shows title and message fields in dialog
Form field display
Settings Components (87 tests)
src/components/settings/APIKeyManagement.test.tsx β 10 tests
1
renders the API Keys & MCP Server card
Card display
2
displays MCP server URL
URL input with copy button
3
shows quick setup instructions
Connection instructions
4
displays existing API keys
Key list rendering
5
shows key prefix badges
Prefix badge display
6
shows last used time for keys that have been used
Last used timestamp
7
shows empty state when no keys exist
Empty state display
8
shows create form when New Key is clicked
Create form toggle
9
renders revoke buttons for each key
Revoke action buttons
10
has a New Key button
New key CTA
src/components/settings/DeleteOrganization.test.tsx β 10 tests
1
renders danger zone card
Card display
2
shows warning text
Warning content
3
opens confirmation dialog
Dialog opening
4
requires name confirmation
Confirmation input
5
enables delete when confirmed
Enable button
6
disables delete when wrong text
Disable button
7
handles delete action
Delete flow
8
shows loading state
Loading display
9
handles cancel
Cancel flow
10
shows org name in dialog
Dynamic content
src/components/settings/ProfileSettings.test.tsx β 4 tests
1
renders profile sections
Section display
2
shows avatar upload
Avatar component
3
displays form fields
Form rendering
4
handles save
Save flow
src/components/settings/SecuritySettings.test.tsx β 4 tests
1
renders password and 2FA sections
Section display
2
opens password change dialog
Dialog opening
3
shows MFA status
MFA display
4
handles password update
Update flow
src/components/settings/MCPServersIntegration.test.tsx β 14 tests
1
renders integration card
Card display
2
shows add server button
Action button
3
opens add server dialog
Dialog opening
4
displays server list
Server list display
5
shows server details
Detail display
6
handles remove server
Remove flow
7
shows empty state
No servers state
8
validates URL input
URL validation
9
handles name input
Name validation
10
shows help accordion
Help section
11
displays external links
Documentation links
12
handles loading state
Loading display
13
shows description field
Description input
14
handles cancel
Cancel flow
src/components/settings/StorageUsageCard.test.tsx β 8 tests
1
shows loading skeleton initially
Loading state
2
renders storage title after loading
Title display
3
displays usage text with formatted bytes
Usage formatting
4
shows warning badge at 90% usage
Warning state
5
shows Full badge at 100% usage
Full state
6
shows no badge when usage is normal
Normal state
7
displays description text
Description display
8
handles API error gracefully
Error handling
src/components/settings/BusinessSettings.test.tsx β 6 tests
1
renders loading state initially
Loading spinner
2
renders accordion sections after loading
Info, Hours, Services accordions
3
renders basic information fields
Form field display
4
renders save status indicator
Auto-save indicator
5
renders timezone field
Timezone select
6
renders address grid with responsive classes
Responsive address layout
src/components/settings/BusinessHoursEditor.test.tsx β 5 tests
1
renders all 7 days of the week
Day label display
2
shows Closed text for days that are not open
Closed state
3
renders time inputs for open days
Time input display
4
renders switch toggles for each day
Toggle rendering
5
uses responsive layout classes
Mobile-first flex classes
src/components/settings/ServicesEditor.test.tsx β 6 tests
1
renders empty state when no services
Empty state display
2
renders service items when services exist
Service list
3
shows service name and duration labels
Label display
4
calls onChange when Add Service is clicked
Add interaction
5
renders delete button for each service
Delete action buttons
6
uses responsive grid classes
Mobile-first grid
src/components/settings/SSOSettings.test.tsx β 20 tests
1
renders SSO card title
Card title display
2
renders description text
Description display
3
renders callback URL section
Callback URL display
4
renders SSO Domain input
Domain input field
5
renders Issuer URL input
Issuer URL field
6
renders Client ID input
Client ID field
7
renders Client Secret input
Client Secret field
8
renders Enable SSO toggle label
Toggle label display
9
renders Enable SSO button for new setup
CTA button display
10
renders How to Use button
Guide button display
11
opens How to Use dialog when clicked
Dialog opening
12
shows all 5 steps in the guide
Step card rendering
13
shows XP counter in guide
Gamification XP display
14
shows progress bar in guide
Progress tracking
15
marks step as done when clicked
Step completion toggle
16
updates XP when step completed
XP increment
17
persists completed steps to localStorage
Persistence
18
shows pro tip in guide
Tip display
19
renders advanced endpoint section
Advanced section
20
shows loading state initially
Loading spinner
Chat Components (6 tests)
src/components/chat/ChatWithDataPopup.test.tsx β 6 tests
1
does not render when closed
Closed state
2
renders when open
Open state
3
shows input field
Input display
4
handles message submit
Submit flow
5
shows close button
Close button
6
handles close action
Close handler
AgentOne Dashboard (8 tests)
src/components/agent-one/AgentOneDashboardMetrics.test.tsx β 3 tests
1
renders skeleton loaders when orgId is null
Null orgId handling
2
renders all 6 metric labels when data loads
Label verification
3
renders zero values gracefully
Zero-value display
src/components/agent-one/AgentOneDashboardUsageChart.test.tsx β 3 tests
1
renders chart title
Title display
2
renders toggle buttons
Messages/Tokens toggle
3
shows empty state when no data
Empty data handling
src/components/agent-one/AgentOneDashboardRecentRuns.test.tsx β 2 tests
1
renders section title
Title display
2
shows empty state when no runs
Empty state
Hooks (25 tests)
src/hooks/useConfetti.test.ts β 8 tests
1
returns expected API shape
active, triggerConfetti, handleComplete
2
starts inactive
Initial false state
3
activates on triggerConfetti
Trigger activation
4
deactivates on handleComplete
Complete deactivation
5
allows multiple trigger-complete cycles
Re-trigger support
6
calling triggerConfetti twice stays active
Idempotent trigger
7
calling handleComplete when already inactive stays inactive
Idempotent complete
8
functions are stable references across renders
useCallback memoization
src/hooks/useTextToSpeech.test.ts β 17 tests
1
returns the expected API shape
speak, stop, isSpeaking, isLoading
2
starts with isSpeaking and isLoading as false
Initial state
3
calls speechSynthesis.speak
Speak invocation
4
cancels current speech before new text
Cancel before speak
5
truncates text to 500 characters
Guardrail enforcement
6
does not speak empty text
Empty input handling
7
enforces cooldown between requests
2s cooldown
8
allows speaking after cooldown expires
Cooldown reset
9
sets utterance rate to 0.95
Language learning clarity
10
sets correct locale from short code
Short code β BCP-47
11
passes through BCP-47 locale as-is
Direct locale pass
12
defaults to en-US when no lang
Fallback locale
13
stop cancels and resets state
Stop behavior
14
prefers non-local (cloud) voices
Cloud voice ranking
15
prefers neural/enhanced voices by name
Quality name scoring
16
matches voice to requested language
Language-matched selection
17
cleans up voiceschanged listener
Unmount cleanup
Auth & Routing (29 tests)
src/hooks/useAuth.test.tsx β 12 tests
1
throws error outside AuthProvider
Context guard
2
returns initial loading state
Initial state
3
returns null user when not authenticated
Unauthenticated state
4
returns user when session exists
Session restoration
5
calls signUp with correct parameters
Sign up flow
6
calls signIn with correct parameters
Sign in flow
7
detects MFA factors and returns mfaRequired
MFA detection
8
skips MFA when no verified factors exist
MFA skip for unverified
9
calls signOut
Sign out flow
10
returns error from signIn when authentication fails
Error handling
11
calls signInWithGoogle with OAuth provider
Google OAuth
12
clears stale session when getUser fails on mount
Stale session cleanup
src/components/ProtectedRoute.test.tsx β 5 tests
1
shows loading spinner
Loading state
2
redirects to login when unauthenticated
Redirect behavior
3
renders children when authenticated
Authenticated state
4
preserves return URL
URL preservation
5
handles auth state change
State transition
src/components/AdminRoute.test.tsx β 5 tests
1
shows loading spinner when staff is loading
Staff loading state
2
shows loading spinner when access is loading
Access loading state
3
renders children when admin staff and access allowed
Authorized access
4
shows 404 when user is not admin staff
Non-admin masking
5
shows 404 when access is blocked
Blocked device/IP masking
src/hooks/useAdminAccess.test.ts β 7 tests
1
returns loading while auth is loading
Initial loading state
2
returns blocked when not authenticated
Unauthenticated block
3
returns allowed when edge function allows
Authorized access
4
returns blocked when edge function denies
Access denied
5
returns blocked on edge function error
Error handling
6
returns blocked with server_error on throw
Server error handling
7
sends device fingerprint in request body
Fingerprint transmission
Pages (112 tests)
src/pages/ForgotPassword.test.tsx β 10 tests
1
renders form
Form display
2
shows email input
Email field
3
validates email
Email validation
4
calls edge function on submit
API call
5
shows success message
Success state
6
shows error message
Error state
7
disables button while loading
Loading state
8
shows hCaptcha
Captcha display
9
links to login
Navigation link
10
handles network error
Error handling
src/pages/ResetPassword.test.tsx β 12 tests
1-3
Without session
Shows expired message, links to forgot password, no form
4-8
With valid session
Renders form, shows password fields, validates match, validates strength, calls updateUser
9-12
Edge cases
Shows success message, handles API error, loading state, redirect after success
src/pages/Contact.test.tsx β 10 tests
1
renders the contact form
Form title, name, email, message fields
2
renders send message button
Submit button display
3
shows validation errors for empty required fields
Name required validation
4
shows validation error for short message
Minimum 10 chars validation
5
submits form and calls contact_requests insert
DB insert verification
6
calls crm-contact-form edge function on submit
CRM edge function with captchaToken
7
shows thank you screen after successful submission
Thank you state rendering
8
renders company and phone optional fields
Optional field display
9
has honeypot field hidden from view
Anti-spam honeypot
10
renders hCaptcha widget
hCaptcha integration
src/pages/Onboarding.test.tsx β 6 tests
1
renders step 1 form
First step display
2
allows navigation through steps
Step navigation
3
shows progress indicators
Progress display
4
disables continue when empty
Validation
5
enables continue when filled
Valid state
6
auto-detects country via geolocation
Country detection
src/pages/DashboardGDPR.test.tsx β 9 tests
1
renders page title
Title display
2
shows data export button
Action button
3
shows request history
History display
4
shows empty state
No requests state
5
handles export request
Request flow
6
shows status badges
Status display
7
shows download link
Download action
8
handles expired downloads
Expiry handling
9
shows request timestamps
Time display
src/pages/DashboardBrowserCalls.test.tsx β 5 tests
1
renders page title
Title display
2
renders export button
Export action
3
renders filter controls
Filter UI
4
renders quick stats cards
Stats display
5
has accessible filter dropdown
Filter accessibility
src/pages/DashboardAnnouncements.test.tsx β 10 tests
1
renders page title and subtitle
Title and description display
2
renders announcement titles after loading
Announcement list rendering
3
shows Read badge for dismissed announcements
Green read badge
4
shows Unread badge for non-dismissed announcements
Red unread badge
5
renders search input
Search field display
6
renders type filter dropdown
Type filter UI
7
renders status filter dropdown
Status filter UI
8
filters announcements by search text
Text search filtering
9
shows empty state when no announcements match
Empty filter state
10
displays type badge on each announcement
Type badge display
src/pages/DashboardConsents.test.tsx β 8 tests
1
renders the Consent Log title
Title display
2
renders description text
Description display
3
renders Consents Given metric
Given metric
4
renders Consents Declined metric
Declined metric
5
renders Consent Rate metric
Rate metric
6
renders search input
Search field
7
shows empty state when no consent records
Empty state
8
renders All Consent Records card title
Records card
src/pages/DashboardClients.test.tsx β 11 tests
1
renders the Clients title
Title display
2
renders description text
Description display
3
renders Add Client button
Add action
4
renders Export button
Export action
5
renders Total Clients metric
Clients metric
6
renders Active metric
Active metric
7
renders Total Appointments metric
Appointments metric
8
renders Total Calls metric
Calls metric
9
renders search input
Search field
10
shows empty state when no clients
Empty state
11
Export button is disabled when no clients
Disabled export
src/pages/DashboardConvo.test.tsx β 5 tests
1
renders page title
Title display
2
renders Spaces and Progress Tracking tabs
Tab display
3
defaults to spaces tab when no search param
Default tab
4
defaults to progress tab when tab=progress search param
URL param tab
5
shows description text
Description display
src/pages/DashboardClimateSaved.test.tsx β 11 tests
1
renders page title
Title display
2
renders description
Description display
3
renders COβ metric card
COβ card
4
renders Trees Equivalent card
Trees card
5
renders Energy Saved card
Energy card
6
renders Car Miles Avoided card
Car miles card
7
renders Green Milestone section
Milestone progress
8
renders How It's Calculated section
Calculation section
9
renders accordion items for formulas
Formula accordions
10
renders Climate Impact & Carbon Cash learning section
Learning section display
11
renders link to rewards page
Cross-page navigation
src/pages/DashboardRewards.test.tsx β 7 tests
1
shows loading spinner initially
Loading state
2
calls supabase for profiles
Data fetch
3
calls supabase for rewards_config
Config fetch
4
renders within a router context without crashing
Router context
5
shows Coming Soon when rewards inactive
Inactive state
6
renders How Rewards & Climate Connect section
Learning section display
7
renders link to climate dashboard
Cross-page navigation
src/pages/AffiliateDashboard.test.tsx β 8 tests
1
redirects to login when no token
Token guard redirect
2
renders dashboard with affiliate data
Data display
3
displays stats cards
Clicks, signups, earnings, commission
4
fires confetti on first login
First-login localStorage flag
5
does not fire confetti on subsequent logins
Repeat login guard
6
shows referral link with copy button
Copy link UI
7
shows approved status badge
Status badge display
8
shows empty referrals message
Empty referrals state
Edge Function Tests (Deno) (13 tests)
supabase/functions/send-email/index.test.ts β 10 tests
1
handles CORS preflight request
OPTIONS method returns 200
2
accepts request with authorization
Auth header accepted
3
rejects unknown email type
Unknown type returns 500
4
validates required fields for team-invitation
Team invitation fields
5
validates required fields for welcome email
Welcome email fields
6
validates required fields for verify-email
Verify email fields
7
validates required fields for password-reset
Password reset fields
8
validates required fields for missed-call-alert
Missed call alert fields
9
validates required fields for appointment-confirmation
Appointment confirmation fields
10
handles missing body gracefully
Empty body error handling
supabase/functions/request-password-reset/index.test.ts β 7 tests
1-3
CORS & validation
OPTIONS handling, missing email rejection, invalid email rejection
4-7
Functionality
Valid email acceptance, rate limiting, token generation, email sending
supabase/functions/appointment-reminders/index.test.ts β 3 tests
1
returns 200 on valid POST
Successful cron invocation
2
handles OPTIONS preflight
CORS preflight response
3
returns processed count
Response includes numeric processed count
Test Coverage by Category
Utility Functions
4
80
9.8%
UI Components
3
24
2.9%
Dashboard Components
16
164
20.1%
Admin Components
10
85
10.4%
Settings Components
9
87
10.7%
Hooks
2
25
3.1%
Chat Components
1
6
0.7%
Auth & Routing
4
29
3.6%
Pages
11
112
13.7%
AgentOne Dashboard
3
8
1.0%
Edge Functions (Deno)
4
25
3.1%
Total
67
815
100%
Writing New Tests
Conventions
Place test files alongside source files:
ComponentName.test.tsxUse
describeblocks grouped by feature/behaviorUse
vi.mock()for external dependenciesUse the shared Supabase mock from
src/test/mocks/supabase.ts
Example
Mocking Patterns
Last updated