**Authentication Refactor:** Remove authStore and its associated tests, transitioning to the new authentication model. Add dynamic loading for PasswordResetConfirmForm to optimize performance. Include a theme initialization script in layout.tsx to prevent FOUC.

This commit is contained in:
2025-11-02 14:00:05 +01:00
parent 92b7de352c
commit b181182c3b
22 changed files with 390 additions and 127 deletions

View File

@@ -29,7 +29,7 @@ let mockAuthState: {
user: null,
};
jest.mock('@/stores/authStore', () => ({
jest.mock('@/lib/stores/authStore', () => ({
useAuthStore: () => mockAuthState,
}));

View File

@@ -5,10 +5,10 @@
import { render, waitFor } from '@testing-library/react';
import { AuthInitializer } from '@/components/auth/AuthInitializer';
import { useAuthStore } from '@/stores/authStore';
import { useAuthStore } from '@/lib/stores/authStore';
// Mock the auth store
jest.mock('@/stores/authStore', () => ({
jest.mock('@/lib/stores/authStore', () => ({
useAuthStore: jest.fn(),
}));

View File

@@ -40,7 +40,7 @@ jest.mock('next/navigation', () => ({
}));
// Mock auth store
jest.mock('@/stores/authStore', () => ({
jest.mock('@/lib/stores/authStore', () => ({
useAuthStore: () => ({
isAuthenticated: false,
setAuth: jest.fn(),

View File

@@ -38,7 +38,7 @@ jest.mock('next/navigation', () => ({
}),
}));
jest.mock('@/stores/authStore', () => ({
jest.mock('@/lib/stores/authStore', () => ({
useAuthStore: () => ({
isAuthenticated: false,
setAuth: jest.fn(),

View File

@@ -6,13 +6,13 @@
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Header } from '@/components/layout/Header';
import { useAuthStore } from '@/stores/authStore';
import { useAuthStore } from '@/lib/stores/authStore';
import { useLogout } from '@/lib/api/hooks/useAuth';
import { usePathname } from 'next/navigation';
import type { User } from '@/stores/authStore';
import type { User } from '@/lib/stores/authStore';
// Mock dependencies
jest.mock('@/stores/authStore', () => ({
jest.mock('@/lib/stores/authStore', () => ({
useAuthStore: jest.fn(),
}));

View File

@@ -25,7 +25,7 @@ let mockAuthState: {
refreshToken: null,
};
jest.mock('@/stores/authStore', () => ({
jest.mock('@/lib/stores/authStore', () => ({
useAuthStore: (selector?: (state: any) => any) => {
if (selector) {
return selector(mockAuthState);

View File

@@ -2,7 +2,7 @@
* Tests for auth store
*/
import { useAuthStore, type User } from '@/stores/authStore';
import { useAuthStore, type User } from '@/lib/stores/authStore';
import * as storage from '@/lib/auth/storage';
// Mock storage module
@@ -386,73 +386,41 @@ describe('Auth Store', () => {
});
});
describe('loadAuthFromStorage', () => {
it('should load valid tokens from storage', async () => {
(storage.getTokens as jest.Mock).mockResolvedValue({
accessToken: 'valid.access.token',
refreshToken: 'valid.refresh.token',
});
describe('loadAuthFromStorage (deprecated)', () => {
it('should log deprecation warning', async () => {
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation();
await useAuthStore.getState().loadAuthFromStorage();
const state = useAuthStore.getState();
expect(state.accessToken).toBe('valid.access.token');
expect(state.refreshToken).toBe('valid.refresh.token');
expect(state.isAuthenticated).toBe(true);
expect(state.isLoading).toBe(false);
});
expect(consoleWarnSpy).toHaveBeenCalledWith(
'loadAuthFromStorage() is deprecated and no longer necessary'
);
it('should handle null tokens from storage', async () => {
(storage.getTokens as jest.Mock).mockResolvedValue(null);
await useAuthStore.getState().loadAuthFromStorage();
const state = useAuthStore.getState();
expect(state.isAuthenticated).toBe(false);
expect(state.isLoading).toBe(false);
});
it('should reject invalid token format from storage', async () => {
(storage.getTokens as jest.Mock).mockResolvedValue({
accessToken: 'invalid',
refreshToken: 'valid.refresh.token',
});
await useAuthStore.getState().loadAuthFromStorage();
const state = useAuthStore.getState();
expect(state.isAuthenticated).toBe(false);
expect(state.isLoading).toBe(false);
});
it('should handle storage errors gracefully', async () => {
(storage.getTokens as jest.Mock).mockRejectedValue(new Error('Storage error'));
await useAuthStore.getState().loadAuthFromStorage();
const state = useAuthStore.getState();
expect(state.isLoading).toBe(false);
consoleWarnSpy.mockRestore();
});
});
describe('initializeAuth', () => {
it('should call loadAuthFromStorage', async () => {
(storage.getTokens as jest.Mock).mockResolvedValue({
accessToken: 'valid.access.token',
refreshToken: 'valid.refresh.token',
});
describe('initializeAuth (deprecated)', () => {
it('should log deprecation warning', async () => {
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation();
const { initializeAuth } = await import('@/stores/authStore');
const { initializeAuth } = await import('@/lib/stores/authStore');
await initializeAuth();
expect(storage.getTokens).toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalledWith(
'initializeAuth() is deprecated and no longer necessary'
);
consoleWarnSpy.mockRestore();
});
it('should not throw even if loadAuthFromStorage fails', async () => {
(storage.getTokens as jest.Mock).mockRejectedValue(new Error('Storage error'));
it('should not throw', async () => {
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation();
const { initializeAuth } = await import('@/stores/authStore');
const { initializeAuth } = await import('@/lib/stores/authStore');
await expect(initializeAuth()).resolves.not.toThrow();
consoleWarnSpy.mockRestore();
});
});
});