This commit is contained in:
143
tests/auth/createAuthContext.test.tsx
Normal file
143
tests/auth/createAuthContext.test.tsx
Normal file
@@ -0,0 +1,143 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { createAuthContext } from '../../src/auth/createAuthContext';
|
||||
|
||||
type User = {
|
||||
id: string;
|
||||
username: string;
|
||||
};
|
||||
|
||||
const defaultAuth = createAuthContext<User>();
|
||||
|
||||
function createUser(username: string): User {
|
||||
return {
|
||||
id: `id-${username}`,
|
||||
username,
|
||||
};
|
||||
}
|
||||
|
||||
function AuthHarness() {
|
||||
const { authToken, refreshToken, currentUser, setSession, setCurrentUser, clearSession } =
|
||||
defaultAuth.useAuth();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span data-testid="auth-token">{authToken ?? 'none'}</span>
|
||||
<span data-testid="refresh-token">{refreshToken ?? 'none'}</span>
|
||||
<span data-testid="username">{currentUser?.username ?? 'none'}</span>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSession('auth-next', 'refresh-next', createUser('after-set'))}
|
||||
>
|
||||
set-session
|
||||
</button>
|
||||
<button type="button" onClick={() => setCurrentUser(createUser('patched'))}>
|
||||
set-user
|
||||
</button>
|
||||
<button type="button" onClick={clearSession}>
|
||||
clear
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
describe('createAuthContext', () => {
|
||||
it('throws when hook is used outside the provider', () => {
|
||||
function Invalid() {
|
||||
defaultAuth.useAuth();
|
||||
return null;
|
||||
}
|
||||
|
||||
expect(() => render(<Invalid />)).toThrow('useAuth must be used within AuthProvider');
|
||||
});
|
||||
|
||||
it('reads persisted tokens and cleans default legacy keys', () => {
|
||||
localStorage.setItem('authToken', 'auth-1');
|
||||
localStorage.setItem('refreshToken', 'refresh-1');
|
||||
localStorage.setItem('auth_token', 'legacy');
|
||||
localStorage.setItem('auth_user', 'legacy');
|
||||
localStorage.setItem('token', 'legacy');
|
||||
|
||||
render(
|
||||
<defaultAuth.AuthProvider>
|
||||
<AuthHarness />
|
||||
</defaultAuth.AuthProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('auth-token')).toHaveTextContent('auth-1');
|
||||
expect(screen.getByTestId('refresh-token')).toHaveTextContent('refresh-1');
|
||||
expect(localStorage.getItem('auth_token')).toBeNull();
|
||||
expect(localStorage.getItem('auth_user')).toBeNull();
|
||||
expect(localStorage.getItem('token')).toBeNull();
|
||||
});
|
||||
|
||||
it('supports session lifecycle updates', () => {
|
||||
render(
|
||||
<defaultAuth.AuthProvider>
|
||||
<AuthHarness />
|
||||
</defaultAuth.AuthProvider>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'set-session' }));
|
||||
expect(screen.getByTestId('auth-token')).toHaveTextContent('auth-next');
|
||||
expect(screen.getByTestId('refresh-token')).toHaveTextContent('refresh-next');
|
||||
expect(screen.getByTestId('username')).toHaveTextContent('after-set');
|
||||
expect(localStorage.getItem('authToken')).toBe('auth-next');
|
||||
expect(localStorage.getItem('refreshToken')).toBe('refresh-next');
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'set-user' }));
|
||||
expect(screen.getByTestId('username')).toHaveTextContent('patched');
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'clear' }));
|
||||
expect(screen.getByTestId('auth-token')).toHaveTextContent('none');
|
||||
expect(screen.getByTestId('refresh-token')).toHaveTextContent('none');
|
||||
expect(screen.getByTestId('username')).toHaveTextContent('none');
|
||||
expect(localStorage.getItem('authToken')).toBeNull();
|
||||
expect(localStorage.getItem('refreshToken')).toBeNull();
|
||||
});
|
||||
|
||||
it('supports custom token keys and legacy cleanup keys', () => {
|
||||
const customAuth = createAuthContext<User>({
|
||||
authTokenKey: 'custom-auth',
|
||||
refreshTokenKey: 'custom-refresh',
|
||||
legacyKeys: ['legacy-a', 'legacy-b'],
|
||||
});
|
||||
|
||||
function CustomHarness() {
|
||||
const { authToken, refreshToken, setSession } = customAuth.useAuth();
|
||||
return (
|
||||
<div>
|
||||
<span data-testid="custom-auth-token">{authToken ?? 'none'}</span>
|
||||
<span data-testid="custom-refresh-token">{refreshToken ?? 'none'}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSession('next-auth', 'next-refresh', createUser('custom'))}
|
||||
>
|
||||
set-custom-session
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
localStorage.setItem('custom-auth', 'auth-1');
|
||||
localStorage.setItem('custom-refresh', 'refresh-1');
|
||||
localStorage.setItem('legacy-a', 'legacy');
|
||||
localStorage.setItem('legacy-b', 'legacy');
|
||||
|
||||
render(
|
||||
<customAuth.AuthProvider>
|
||||
<CustomHarness />
|
||||
</customAuth.AuthProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('custom-auth-token')).toHaveTextContent('auth-1');
|
||||
expect(screen.getByTestId('custom-refresh-token')).toHaveTextContent('refresh-1');
|
||||
expect(localStorage.getItem('legacy-a')).toBeNull();
|
||||
expect(localStorage.getItem('legacy-b')).toBeNull();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'set-custom-session' }));
|
||||
expect(localStorage.getItem('custom-auth')).toBe('next-auth');
|
||||
expect(localStorage.getItem('custom-refresh')).toBe('next-refresh');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user