expria-frontend/src/features/dashboard/hooks/__tests__/useUpgradeSuccessHandler.test.tsx
Hermann_Kitio bda7feb196 feat(billing): useStripeCheckout hook + post-redirect upgrade success
- useStripeCheckout: mutation + redirect full-page, pendingPriceType exposed
- PricingPage migré vers useStripeCheckout (suppression useMutation inline)
- useUpgradeSuccessHandler: détecte ?upgrade=success, invalide plan cache, clean URL
- UpgradeSuccessBanner: callout success dans DashboardPage
- Tests: 203 → 212 verts (+9)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 05:19:18 +03:00

88 lines
3.1 KiB
TypeScript

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<typeof vi.fn>
let queryClient: QueryClient
function wrapper({ children }: { children: ReactNode }) {
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}
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')
})
})