import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { renderHook, act } from '@testing-library/react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import type { ReactNode } from 'react' import { PLAN_QUERY_KEY } from '@/entities/user/query-keys' import { useUpgradeSuccessHandler } from '../useUpgradeSuccessHandler' let invalidateSpy: ReturnType let queryClient: QueryClient function wrapper({ children }: { children: ReactNode }) { return {children} } function setLocation(search: string) { window.history.replaceState(null, '', `/dashboard${search}`) } beforeEach(() => { queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, }) invalidateSpy = vi.fn().mockResolvedValue(undefined) // Spy sur la méthode invalidateQueries pour vérifier la clé exacte. queryClient.invalidateQueries = invalidateSpy as unknown as typeof queryClient.invalidateQueries }) afterEach(() => { setLocation('') }) describe('useUpgradeSuccessHandler', () => { it('?upgrade=success → showSuccess=true, invalidate(PLAN_QUERY_KEY) appelé, URL nettoyée', () => { setLocation('?upgrade=success') const { result } = renderHook(() => useUpgradeSuccessHandler(), { wrapper }) expect(result.current.showSuccess).toBe(true) expect(invalidateSpy).toHaveBeenCalledTimes(1) expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: PLAN_QUERY_KEY }) // URL nettoyée : plus de `upgrade` dans la query string. expect(window.location.search).toBe('') }) it('absence de query param → showSuccess=false, invalidate non appelé', () => { setLocation('') const { result } = renderHook(() => useUpgradeSuccessHandler(), { wrapper }) expect(result.current.showSuccess).toBe(false) expect(invalidateSpy).not.toHaveBeenCalled() }) it("?upgrade=cancelled (autre valeur) → showSuccess=false, pas d'action", () => { setLocation('?upgrade=cancelled') const { result } = renderHook(() => useUpgradeSuccessHandler(), { wrapper }) expect(result.current.showSuccess).toBe(false) expect(invalidateSpy).not.toHaveBeenCalled() // URL conservée intacte (autre valeur, hors scope du nettoyage). expect(window.location.search).toBe('?upgrade=cancelled') }) it('dismiss() bascule showSuccess à false', () => { setLocation('?upgrade=success') const { result } = renderHook(() => useUpgradeSuccessHandler(), { wrapper }) expect(result.current.showSuccess).toBe(true) act(() => { result.current.dismiss() }) expect(result.current.showSuccess).toBe(false) }) it('conserve les autres query params (utm_*, etc.) lors du nettoyage', () => { setLocation('?upgrade=success&utm_source=email&ref=abc') renderHook(() => useUpgradeSuccessHandler(), { wrapper }) const params = new URLSearchParams(window.location.search) expect(params.has('upgrade')).toBe(false) expect(params.get('utm_source')).toBe('email') expect(params.get('ref')).toBe('abc') }) })