Migrate auth hooks to AuthContext and update tests for compatibility
- Refactored `useIsAuthenticated` and `useCurrentUser` to use `useAuth` from `AuthContext` instead of `useAuthStore`. - Updated test setups to inject `AuthProvider` with mocked store hooks for improved test isolation and consistency. - Replaced legacy `useAuthStore` mocks with `AuthContext`-compatible implementations in affected tests.
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
|||||||
} from '../client';
|
} from '../client';
|
||||||
import { useAuthStore } from '@/lib/stores/authStore';
|
import { useAuthStore } from '@/lib/stores/authStore';
|
||||||
import type { User } from '@/lib/stores/authStore';
|
import type { User } from '@/lib/stores/authStore';
|
||||||
|
import { useAuth } from '@/lib/auth/AuthContext';
|
||||||
import { parseAPIError, getGeneralError } from '../errors';
|
import { parseAPIError, getGeneralError } from '../errors';
|
||||||
import { isTokenWithUser } from '../types';
|
import { isTokenWithUser } from '../types';
|
||||||
import config from '@/config/app.config';
|
import config from '@/config/app.config';
|
||||||
@@ -481,7 +482,7 @@ export function usePasswordChange(onSuccess?: (message: string) => void) {
|
|||||||
* @returns boolean indicating authentication status
|
* @returns boolean indicating authentication status
|
||||||
*/
|
*/
|
||||||
export function useIsAuthenticated(): boolean {
|
export function useIsAuthenticated(): boolean {
|
||||||
return useAuthStore((state) => state.isAuthenticated);
|
return useAuth((state) => state.isAuthenticated);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -489,7 +490,7 @@ export function useIsAuthenticated(): boolean {
|
|||||||
* @returns Current user or null
|
* @returns Current user or null
|
||||||
*/
|
*/
|
||||||
export function useCurrentUser(): User | null {
|
export function useCurrentUser(): User | null {
|
||||||
return useAuthStore((state) => state.user);
|
return useAuth((state) => state.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,12 +6,40 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
import ProfileSettingsPage from '@/app/(authenticated)/settings/profile/page';
|
import ProfileSettingsPage from '@/app/(authenticated)/settings/profile/page';
|
||||||
|
import { AuthProvider } from '@/lib/auth/AuthContext';
|
||||||
import { useAuthStore } from '@/lib/stores/authStore';
|
import { useAuthStore } from '@/lib/stores/authStore';
|
||||||
|
|
||||||
// Mock authStore
|
// Mock authStore
|
||||||
jest.mock('@/lib/stores/authStore');
|
jest.mock('@/lib/stores/authStore');
|
||||||
const mockUseAuthStore = useAuthStore as jest.MockedFunction<typeof useAuthStore>;
|
const mockUseAuthStore = useAuthStore as jest.MockedFunction<typeof useAuthStore>;
|
||||||
|
|
||||||
|
// Mock store hook for AuthProvider
|
||||||
|
const mockStoreHook = ((selector?: (state: any) => any) => {
|
||||||
|
const state = {
|
||||||
|
isAuthenticated: true,
|
||||||
|
user: {
|
||||||
|
id: '1',
|
||||||
|
email: 'test@example.com',
|
||||||
|
first_name: 'Test',
|
||||||
|
last_name: 'User',
|
||||||
|
is_active: true,
|
||||||
|
is_superuser: false,
|
||||||
|
created_at: '2024-01-01T00:00:00Z',
|
||||||
|
},
|
||||||
|
accessToken: 'token',
|
||||||
|
refreshToken: 'refresh',
|
||||||
|
isLoading: false,
|
||||||
|
tokenExpiresAt: null,
|
||||||
|
setAuth: jest.fn(),
|
||||||
|
setTokens: jest.fn(),
|
||||||
|
setUser: jest.fn(),
|
||||||
|
clearAuth: jest.fn(),
|
||||||
|
loadAuthFromStorage: jest.fn(),
|
||||||
|
isTokenExpired: jest.fn(() => false),
|
||||||
|
};
|
||||||
|
return selector ? selector(state) : state;
|
||||||
|
}) as any;
|
||||||
|
|
||||||
describe('ProfileSettingsPage', () => {
|
describe('ProfileSettingsPage', () => {
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
@@ -44,7 +72,9 @@ describe('ProfileSettingsPage', () => {
|
|||||||
const renderWithProvider = (component: React.ReactElement) => {
|
const renderWithProvider = (component: React.ReactElement) => {
|
||||||
return render(
|
return render(
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
{component}
|
<AuthProvider store={mockStoreHook}>
|
||||||
|
{component}
|
||||||
|
</AuthProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,28 +11,29 @@ import {
|
|||||||
useCurrentUser,
|
useCurrentUser,
|
||||||
useIsAdmin,
|
useIsAdmin,
|
||||||
} from '@/lib/api/hooks/useAuth';
|
} from '@/lib/api/hooks/useAuth';
|
||||||
|
import { AuthProvider } from '@/lib/auth/AuthContext';
|
||||||
|
|
||||||
// Mock auth store
|
// Mock auth state (Context-injected)
|
||||||
let mockAuthState: {
|
let mockAuthState: any = {
|
||||||
isAuthenticated: boolean;
|
|
||||||
user: any;
|
|
||||||
accessToken: string | null;
|
|
||||||
refreshToken: string | null;
|
|
||||||
} = {
|
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
user: null,
|
user: null,
|
||||||
accessToken: null,
|
accessToken: null,
|
||||||
refreshToken: null,
|
refreshToken: null,
|
||||||
|
isLoading: false,
|
||||||
|
tokenExpiresAt: null,
|
||||||
|
// Action stubs (unused in these tests)
|
||||||
|
setAuth: jest.fn(),
|
||||||
|
setTokens: jest.fn(),
|
||||||
|
setUser: jest.fn(),
|
||||||
|
clearAuth: jest.fn(),
|
||||||
|
loadAuthFromStorage: jest.fn(),
|
||||||
|
isTokenExpired: jest.fn(() => false),
|
||||||
};
|
};
|
||||||
|
|
||||||
jest.mock('@/lib/stores/authStore', () => ({
|
// Mock store hook compatible with AuthContext (Zustand-like hook)
|
||||||
useAuthStore: (selector?: (state: any) => any) => {
|
const mockStoreHook = ((selector?: (state: any) => any) => {
|
||||||
if (selector) {
|
return selector ? selector(mockAuthState) : mockAuthState;
|
||||||
return selector(mockAuthState);
|
}) as any;
|
||||||
}
|
|
||||||
return mockAuthState;
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock router
|
// Mock router
|
||||||
jest.mock('next/navigation', () => ({
|
jest.mock('next/navigation', () => ({
|
||||||
@@ -51,7 +52,9 @@ const createWrapper = () => {
|
|||||||
|
|
||||||
return ({ children }: { children: React.ReactNode }) => (
|
return ({ children }: { children: React.ReactNode }) => (
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
{children}
|
<AuthProvider store={mockStoreHook}>
|
||||||
|
{children}
|
||||||
|
</AuthProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user