22import { type QueryClient , QueryClientProvider } from '@tanstack/react-query'
33import { useLocation , useSearch } from '@tanstack/react-router'
44import { act , createElement , type ReactNode } from 'react'
5+ import { toast } from 'sonner'
56import { afterEach , describe , expect , it , vi } from 'vitest'
67import { api , apiRequest } from '@/api'
78import { Loader } from '@/components/ui/Loader'
@@ -43,6 +44,10 @@ vi.mock('@/components/ui/Loader', () => ({ Loader: vi.fn(() => null) }))
4344
4445vi . mock ( '@/lib/logger' , ( ) => ( { logger : { warn : vi . fn ( ) , error : vi . fn ( ) } } ) )
4546
47+ vi . mock ( '@/i18n' , ( ) => ( { useIntl : ( ) => ( { t : ( _k : string , _v : unknown , d : string ) => d } ) } ) )
48+
49+ vi . mock ( 'sonner' , ( ) => ( { toast : { error : vi . fn ( ) } } ) )
50+
4651describe ( 'validateOAuthState' , ( ) => {
4752 afterEach ( ( ) => {
4853 clearOAuthState ( )
@@ -395,7 +400,7 @@ describe('useAuthContext', () => {
395400 await waitFor ( ( ) => {
396401 expect ( localStorage . getItem ( 'osm_token' ) ) . toBe ( 'jwt-token' )
397402 } )
398- expect ( api . user . callback ) . toHaveBeenCalledWith ( 'the-code' )
403+ expect ( api . user . callback ) . toHaveBeenCalledWith ( 'the-code' , 'matching-state' )
399404 expect ( api . user . refreshAuth ) . toHaveBeenCalled ( )
400405 expect ( window . location . href ) . toContain ( '/dashboard' )
401406 expect ( getStoredRedirectUrl ( ) ) . toBeNull ( )
@@ -476,9 +481,10 @@ describe('useAuthContext', () => {
476481 } )
477482 expect ( api . user . refreshAuth ) . toHaveBeenCalled ( )
478483 expect ( logger . error ) . not . toHaveBeenCalledWith ( 'OAuth callback error' , expect . anything ( ) )
484+ expect ( toast . error ) . not . toHaveBeenCalled ( )
479485 } )
480486
481- it ( 'logs the error and does not refresh auth when the callback fails for a non-security reason' , async ( ) => {
487+ it ( 'logs the error, tells the user, and does not refresh auth when the callback fails for a non-security reason' , async ( ) => {
482488 window . history . pushState ( { } , '' , '/?code=the-code&state=matching-state' )
483489 setOAuthState ( 'matching-state' )
484490 mockSearch ( { code : 'the-code' , state : 'matching-state' } )
@@ -495,6 +501,11 @@ describe('useAuthContext', () => {
495501 error : expect . any ( Error ) ,
496502 } )
497503 expect ( api . user . refreshAuth ) . not . toHaveBeenCalled ( )
504+ await waitFor ( ( ) => {
505+ expect ( toast . error ) . toHaveBeenCalledWith (
506+ 'Sign-in failed or expired. Please try signing in again.'
507+ )
508+ } )
498509 } )
499510 } )
500511} )
0 commit comments