import { renderHook } from '@/__tests__/utils/test-helpers' import { useAuth } from './use-auth' import { AuthContext } from '@/components/auth/auth-provider' import React from 'react' describe('useAuth Hook', () => { it('should throw error when used outside AuthProvider', () => { // Suppress console.error for this test const consoleErrorSpy = jest .spyOn(console, 'error') .mockImplementation(() => {}) expect(() => { renderHook(() => useAuth()) }).toThrow('useAuth must be used within an AuthProvider') consoleErrorSpy.mockRestore() }) it('should return auth context when used within AuthProvider', () => { const mockAuthContext = { user: { id: 1, name: 'Test User', email: 'test@example.com', created_at: '', updated_at: '' }, token: 'test-token', isAuthenticated: true, isLoading: false, login: jest.fn(), register: jest.fn(), logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current).toEqual(mockAuthContext) }) it('should have user property when authenticated', () => { const mockUser = { id: 1, name: 'Test User', email: 'test@example.com', created_at: '2024-01-01', updated_at: '2024-01-01', } const mockAuthContext = { user: mockUser, token: 'test-token', isAuthenticated: true, isLoading: false, login: jest.fn(), register: jest.fn(), logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.user).toBe(mockUser) expect(result.current.user?.email).toBe('test@example.com') }) it('should have null user when not authenticated', () => { const mockAuthContext = { user: null, token: null, isAuthenticated: false, isLoading: false, login: jest.fn(), register: jest.fn(), logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.user).toBeNull() expect(result.current.isAuthenticated).toBe(false) }) it('should provide login function', () => { const mockLogin = jest.fn() const mockAuthContext = { user: null, token: null, isAuthenticated: false, isLoading: false, login: mockLogin, register: jest.fn(), logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.login).toBe(mockLogin) }) it('should provide register function', () => { const mockRegister = jest.fn() const mockAuthContext = { user: null, token: null, isAuthenticated: false, isLoading: false, login: jest.fn(), register: mockRegister, logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.register).toBe(mockRegister) }) it('should provide logout function', () => { const mockLogout = jest.fn() const mockAuthContext = { user: { id: 1, name: 'Test', email: 'test@example.com', created_at: '', updated_at: '' }, token: 'test-token', isAuthenticated: true, isLoading: false, login: jest.fn(), register: jest.fn(), logout: mockLogout, } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.logout).toBe(mockLogout) }) it('should report loading state during initialization', () => { const mockAuthContext = { user: null, token: null, isAuthenticated: false, isLoading: true, login: jest.fn(), register: jest.fn(), logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.isLoading).toBe(true) }) it('should report loading complete', () => { const mockAuthContext = { user: null, token: null, isAuthenticated: false, isLoading: false, login: jest.fn(), register: jest.fn(), logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.isLoading).toBe(false) }) it('should have token property when authenticated', () => { const testToken = 'jwt-token-xyz' const mockAuthContext = { user: { id: 1, name: 'Test', email: 'test@example.com', created_at: '', updated_at: '' }, token: testToken, isAuthenticated: true, isLoading: false, login: jest.fn(), register: jest.fn(), logout: jest.fn(), } const wrapper = ({ children }: { children: React.ReactNode }) => { return React.createElement( AuthContext.Provider, { value: mockAuthContext }, children ) } const { result } = renderHook(() => useAuth(), { wrapper }) expect(result.current.token).toBe(testToken) }) })