Refactor useAuth hook, settings components, and docs for formatting and readability improvements

- Consolidated multi-line arguments into single lines where appropriate in `useAuth`.
- Improved spacing and readability in data processing across components (`ProfileSettingsForm`, `PasswordChangeForm`, `SessionCard`).
- Applied consistent table and markdown formatting in design system docs (e.g., `README.md`, `08-ai-guidelines.md`, `00-quick-start.md`).
- Updated code snippets to ensure adherence to Prettier rules and streamlined JSX structures.
This commit is contained in:
2025-11-10 11:03:45 +01:00
parent 464a6140c4
commit 96df7edf88
208 changed files with 4056 additions and 4556 deletions

View File

@@ -56,9 +56,7 @@ describe('API Error Handling', () => {
const errorsWithField: APIError[] = [
{ code: 'VAL_001', message: 'Invalid input', field: 'email' },
];
const errorsWithoutField: APIError[] = [
{ code: 'AUTH_001', message: 'Invalid credentials' },
];
const errorsWithoutField: APIError[] = [{ code: 'AUTH_001', message: 'Invalid credentials' }];
expect(isAPIErrorArray(errorsWithField)).toBe(true);
expect(isAPIErrorArray(errorsWithoutField)).toBe(true);
@@ -110,9 +108,7 @@ describe('API Error Handling', () => {
it('should handle strings', () => {
const result = parseAPIError('some error string');
expect(result).toEqual([
{ code: 'UNKNOWN', message: ERROR_MESSAGES['UNKNOWN'] },
]);
expect(result).toEqual([{ code: 'UNKNOWN', message: ERROR_MESSAGES['UNKNOWN'] }]);
});
});
@@ -448,9 +444,7 @@ describe('API Error Handling', () => {
response: {
status: 401,
data: {
errors: [
{ code: 'CUSTOM_ERROR', message: 'Custom structured error' },
],
errors: [{ code: 'CUSTOM_ERROR', message: 'Custom structured error' }],
},
statusText: 'Unauthorized',
headers: {},
@@ -461,9 +455,7 @@ describe('API Error Handling', () => {
const result = parseAPIError(axiosError);
// Should return structured error, not the 401 default
expect(result).toEqual([
{ code: 'CUSTOM_ERROR', message: 'Custom structured error' },
]);
expect(result).toEqual([{ code: 'CUSTOM_ERROR', message: 'Custom structured error' }]);
});
});
});
@@ -554,9 +546,7 @@ describe('API Error Handling', () => {
});
it('should use error code message if message is missing', () => {
const errors: APIError[] = [
{ code: 'VAL_002', message: '', field: 'email' },
];
const errors: APIError[] = [{ code: 'VAL_002', message: '', field: 'email' }];
const result = getFieldErrors(errors);
@@ -605,9 +595,7 @@ describe('API Error Handling', () => {
});
it('should use error code message if message is missing', () => {
const errors: APIError[] = [
{ code: 'AUTH_001', message: '' },
];
const errors: APIError[] = [{ code: 'AUTH_001', message: '' }];
const result = getGeneralError(errors);

View File

@@ -34,7 +34,9 @@ jest.mock('@/lib/api/client');
jest.mock('@/lib/auth/AuthContext');
const mockAdminListUsers = adminListUsers as jest.MockedFunction<typeof adminListUsers>;
const mockAdminListOrganizations = adminListOrganizations as jest.MockedFunction<typeof adminListOrganizations>;
const mockAdminListOrganizations = adminListOrganizations as jest.MockedFunction<
typeof adminListOrganizations
>;
const mockAdminListSessions = adminListSessions as jest.MockedFunction<typeof adminListSessions>;
const mockUseAuth = useAuth as jest.MockedFunction<typeof useAuth>;
@@ -53,19 +55,13 @@ describe('useAdmin hooks', () => {
});
const wrapper = ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
describe('useAdminStats', () => {
const mockUsersData = {
data: {
data: [
{ is_active: true },
{ is_active: true },
{ is_active: false },
],
data: [{ is_active: true }, { is_active: true }, { is_active: false }],
pagination: { total: 3, page: 1, limit: 10000 },
},
};
@@ -358,7 +354,7 @@ describe('useAdmin hooks', () => {
limit: 20,
search: 'admin',
is_active: true,
is_superuser: false
is_superuser: false,
},
throwOnError: false,
});
@@ -476,7 +472,15 @@ describe('useAdmin hooks', () => {
it('creates a user successfully', async () => {
const mockCreateUser = adminCreateUser as jest.MockedFunction<typeof adminCreateUser>;
mockCreateUser.mockResolvedValue({
data: { id: '1', email: 'newuser@example.com', first_name: 'New', last_name: 'User', is_active: true, is_superuser: false, created_at: '2025-01-01T00:00:00Z' },
data: {
id: '1',
email: 'newuser@example.com',
first_name: 'New',
last_name: 'User',
is_active: true,
is_superuser: false,
created_at: '2025-01-01T00:00:00Z',
},
} as any);
const { result } = renderHook(() => useCreateUser(), { wrapper });
@@ -524,7 +528,15 @@ describe('useAdmin hooks', () => {
it('updates a user successfully', async () => {
const mockUpdateUser = adminUpdateUser as jest.MockedFunction<typeof adminUpdateUser>;
mockUpdateUser.mockResolvedValue({
data: { id: '1', email: 'updated@example.com', first_name: 'Updated', last_name: 'User', is_active: true, is_superuser: false, created_at: '2025-01-01T00:00:00Z' },
data: {
id: '1',
email: 'updated@example.com',
first_name: 'Updated',
last_name: 'User',
is_active: true,
is_superuser: false,
created_at: '2025-01-01T00:00:00Z',
},
} as any);
const { result } = renderHook(() => useUpdateUser(), { wrapper });
@@ -618,7 +630,9 @@ describe('useAdmin hooks', () => {
describe('useDeactivateUser', () => {
it('deactivates a user successfully', async () => {
const mockDeactivateUser = adminDeactivateUser as jest.MockedFunction<typeof adminDeactivateUser>;
const mockDeactivateUser = adminDeactivateUser as jest.MockedFunction<
typeof adminDeactivateUser
>;
mockDeactivateUser.mockResolvedValue({ data: { success: true } } as any);
const { result } = renderHook(() => useDeactivateUser(), { wrapper });
@@ -634,7 +648,9 @@ describe('useAdmin hooks', () => {
});
it('handles deactivate error', async () => {
const mockDeactivateUser = adminDeactivateUser as jest.MockedFunction<typeof adminDeactivateUser>;
const mockDeactivateUser = adminDeactivateUser as jest.MockedFunction<
typeof adminDeactivateUser
>;
mockDeactivateUser.mockResolvedValue({ error: 'Deactivate failed' } as any);
const { result } = renderHook(() => useDeactivateUser(), { wrapper });

View File

@@ -6,11 +6,7 @@
import { renderHook } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
useIsAuthenticated,
useCurrentUser,
useIsAdmin,
} from '@/lib/api/hooks/useAuth';
import { useIsAuthenticated, useCurrentUser, useIsAdmin } from '@/lib/api/hooks/useAuth';
import { AuthProvider } from '@/lib/auth/AuthContext';
// Mock auth state (Context-injected)
@@ -52,9 +48,7 @@ const createWrapper = () => {
return ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>
<AuthProvider store={mockStoreHook}>
{children}
</AuthProvider>
<AuthProvider store={mockStoreHook}>{children}</AuthProvider>
</QueryClientProvider>
);
};

View File

@@ -59,9 +59,7 @@ describe('useSession hooks', () => {
});
const wrapper = ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
describe('useListSessions', () => {

View File

@@ -33,9 +33,7 @@ describe('useUser hooks', () => {
const wrapper = ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>
<AuthProvider>
{children}
</AuthProvider>
<AuthProvider>{children}</AuthProvider>
</QueryClientProvider>
);

View File

@@ -130,7 +130,9 @@ describe('Storage Module', () => {
};
// When setItem throws, isLocalStorageAvailable() returns false
await expect(saveTokens(tokens)).rejects.toThrow('localStorage not available - cannot save tokens');
await expect(saveTokens(tokens)).rejects.toThrow(
'localStorage not available - cannot save tokens'
);
Storage.prototype.setItem = originalSetItem;
});
@@ -171,7 +173,6 @@ describe('Storage Module', () => {
localStorage.removeItem = originalRemoveItem;
});
});
describe('Storage method handling', () => {

View File

@@ -51,11 +51,7 @@ describe('Auth Store', () => {
const invalidUser = createMockUser({ id: '' });
await expect(
useAuthStore.getState().setAuth(
invalidUser,
'valid.access.token',
'valid.refresh.token'
)
useAuthStore.getState().setAuth(invalidUser, 'valid.access.token', 'valid.refresh.token')
).rejects.toThrow('Invalid user object');
});
@@ -63,11 +59,7 @@ describe('Auth Store', () => {
const invalidUser = createMockUser({ id: ' ' });
await expect(
useAuthStore.getState().setAuth(
invalidUser,
'valid.access.token',
'valid.refresh.token'
)
useAuthStore.getState().setAuth(invalidUser, 'valid.access.token', 'valid.refresh.token')
).rejects.toThrow('Invalid user object');
});
@@ -75,11 +67,7 @@ describe('Auth Store', () => {
const invalidUser = createMockUser({ email: '' });
await expect(
useAuthStore.getState().setAuth(
invalidUser,
'valid.access.token',
'valid.refresh.token'
)
useAuthStore.getState().setAuth(invalidUser, 'valid.access.token', 'valid.refresh.token')
).rejects.toThrow('Invalid user object');
});
@@ -101,11 +89,9 @@ describe('Auth Store', () => {
(storage.saveTokens as jest.Mock).mockResolvedValue(undefined);
await expect(
useAuthStore.getState().setAuth(
validUser,
'header.payload.signature',
'header.payload.signature'
)
useAuthStore
.getState()
.setAuth(validUser, 'header.payload.signature', 'header.payload.signature')
).resolves.not.toThrow();
const state = useAuthStore.getState();
@@ -145,11 +131,9 @@ describe('Auth Store', () => {
(storage.saveTokens as jest.Mock).mockResolvedValue(undefined);
await expect(
useAuthStore.getState().setAuth(
validUser,
'header.payload.signature',
'header.payload.signature'
)
useAuthStore
.getState()
.setAuth(validUser, 'header.payload.signature', 'header.payload.signature')
).resolves.not.toThrow();
});
});
@@ -264,11 +248,9 @@ describe('Auth Store', () => {
// First set auth
const validUser = createMockUser();
await useAuthStore.getState().setAuth(
validUser,
'header.payload.signature',
'header.payload.signature'
);
await useAuthStore
.getState()
.setAuth(validUser, 'header.payload.signature', 'header.payload.signature');
expect(useAuthStore.getState().isAuthenticated).toBe(true);
@@ -298,20 +280,14 @@ describe('Auth Store', () => {
describe('setTokens', () => {
it('should update tokens while preserving user state', async () => {
// First set initial auth with user
await useAuthStore.getState().setAuth(
createMockUser({ id: 'user-1' }),
'old.access.token',
'old.refresh.token'
);
await useAuthStore
.getState()
.setAuth(createMockUser({ id: 'user-1' }), 'old.access.token', 'old.refresh.token');
const oldUser = useAuthStore.getState().user;
// Now update just the tokens
await useAuthStore.getState().setTokens(
'new.access.token',
'new.refresh.token',
900
);
await useAuthStore.getState().setTokens('new.access.token', 'new.refresh.token', 900);
const state = useAuthStore.getState();
expect(state.accessToken).toBe('new.access.token');
@@ -344,16 +320,18 @@ describe('Auth Store', () => {
describe('setUser', () => {
it('should update user while preserving auth state', async () => {
// First set initial auth
await useAuthStore.getState().setAuth(
createMockUser({ id: 'user-1' }),
'valid.access.token',
'valid.refresh.token'
);
await useAuthStore
.getState()
.setAuth(createMockUser({ id: 'user-1' }), 'valid.access.token', 'valid.refresh.token');
const oldToken = useAuthStore.getState().accessToken;
// Update just the user
const newUser = createMockUser({ id: 'user-1', email: 'updated@example.com', is_superuser: true });
const newUser = createMockUser({
id: 'user-1',
email: 'updated@example.com',
is_superuser: true,
});
useAuthStore.getState().setUser(newUser);
const state = useAuthStore.getState();
@@ -478,18 +456,11 @@ describe('Auth Store', () => {
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
await expect(
useAuthStore.getState().setAuth(
mockUser,
'valid.access.token',
'valid.refresh.token'
)
useAuthStore.getState().setAuth(mockUser, 'valid.access.token', 'valid.refresh.token')
).rejects.toThrow('Storage error');
// Verify error was logged before throwing
expect(consoleErrorSpy).toHaveBeenCalledWith(
'Failed to save auth state:',
expect.any(Error)
);
expect(consoleErrorSpy).toHaveBeenCalledWith('Failed to save auth state:', expect.any(Error));
consoleErrorSpy.mockRestore();
});