All checks were successful
continuous-integration/drone/push Build is passing
144 lines
5.4 KiB
TypeScript
144 lines
5.4 KiB
TypeScript
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');
|
|
});
|
|
});
|