Barazo default frontend
barazo.forum
1/**
2 * Tests for useRequireAuth hook.
3 */
4
5import { describe, it, expect, vi, beforeEach } from 'vitest'
6import { renderHook, act } from '@testing-library/react'
7import { useRequireAuth } from './use-require-auth'
8import { useAuth } from '@/hooks/use-auth'
9
10const mockToast = vi.fn()
11
12vi.mock('@/hooks/use-auth', () => ({
13 useAuth: vi.fn(),
14}))
15
16vi.mock('@/hooks/use-toast', () => ({
17 useToast: () => ({
18 toast: mockToast,
19 dismiss: vi.fn(),
20 }),
21}))
22
23const mockedUseAuth = vi.mocked(useAuth)
24
25beforeEach(() => {
26 vi.clearAllMocks()
27 // Default: logged out
28 mockedUseAuth.mockReturnValue({
29 user: null,
30 isAuthenticated: false,
31 isLoading: false,
32 crossPostScopesGranted: false,
33 getAccessToken: vi.fn(() => null),
34 login: vi.fn(),
35 logout: vi.fn(),
36 setSessionFromCallback: vi.fn(),
37 requestCrossPostAuth: vi.fn(),
38 authFetch: vi.fn(),
39 })
40})
41
42describe('useRequireAuth', () => {
43 it('shows login toast when not authenticated', () => {
44 const { result } = renderHook(() => useRequireAuth())
45 const action = vi.fn()
46
47 act(() => {
48 result.current.requireAuth(action)
49 })
50
51 expect(action).not.toHaveBeenCalled()
52 expect(mockToast).toHaveBeenCalledWith(
53 expect.objectContaining({
54 title: 'Login required',
55 description: 'You need to log in before you can perform this action.',
56 })
57 )
58 })
59
60 it('includes login action in toast', () => {
61 const { result } = renderHook(() => useRequireAuth())
62
63 act(() => {
64 result.current.requireAuth(vi.fn())
65 })
66
67 expect(mockToast.mock.calls[0]).toBeDefined()
68 const toastArg = mockToast.mock.calls[0]![0] as {
69 action?: { label: string; altText: string; onClick: () => void }
70 }
71 expect(toastArg.action).toBeDefined()
72 expect(toastArg.action?.label).toBe('Log in')
73 })
74
75 it('executes action when authenticated', () => {
76 mockedUseAuth.mockReturnValue({
77 user: {
78 did: 'did:plc:test',
79 handle: 'test.bsky.social',
80 displayName: null,
81 avatarUrl: null,
82 role: 'user' as const,
83 },
84 isAuthenticated: true,
85 isLoading: false,
86 crossPostScopesGranted: false,
87 getAccessToken: vi.fn(() => 'mock-token'),
88 login: vi.fn(),
89 logout: vi.fn(),
90 setSessionFromCallback: vi.fn(),
91 requestCrossPostAuth: vi.fn(),
92 authFetch: vi.fn(),
93 })
94
95 const { result } = renderHook(() => useRequireAuth())
96 const action = vi.fn()
97
98 act(() => {
99 result.current.requireAuth(action)
100 })
101
102 expect(action).toHaveBeenCalled()
103 expect(mockToast).not.toHaveBeenCalled()
104 })
105
106 it('exposes isAuthenticated from auth context', () => {
107 const { result } = renderHook(() => useRequireAuth())
108 expect(result.current.isAuthenticated).toBe(false)
109 })
110})