test(react-auth): add tests for updateUser, onInit, and onInit-null-fallback
This commit is contained in:
parent
1925370604
commit
062d87a93a
@ -277,6 +277,168 @@ describe('createAuthProvider', () => {
|
||||
expect(screen.getByTestId('email').textContent).toBe('mock@test.com');
|
||||
});
|
||||
|
||||
it('updateUser merges partial updates into user state', async () => {
|
||||
const apiResponse = {
|
||||
user: { email: 'test@example.com', name: 'Original', role: 'user' },
|
||||
accessToken: 'at-1',
|
||||
refreshToken: 'rt-1',
|
||||
};
|
||||
mockFetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => apiResponse,
|
||||
headers: new Headers({ 'content-type': 'application/json' }),
|
||||
status: 200,
|
||||
});
|
||||
|
||||
const { AuthProvider, useAuth } = createTestAuth();
|
||||
let loginFn: (email: string, password: string) => Promise<boolean>;
|
||||
let updateUserFn: (updates: Partial<TestUser>) => void;
|
||||
|
||||
function Component() {
|
||||
const { login, updateUser, user } = useAuth();
|
||||
loginFn = login;
|
||||
updateUserFn = updateUser;
|
||||
return (
|
||||
<div>
|
||||
<span data-testid="name">{user?.name ?? 'none'}</span>
|
||||
<span data-testid="role">{user?.role ?? 'none'}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<Component />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await loginFn!('test@example.com', 'pass');
|
||||
});
|
||||
expect(screen.getByTestId('name').textContent).toBe('Original');
|
||||
|
||||
act(() => {
|
||||
updateUserFn!({ name: 'Updated' });
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('name').textContent).toBe('Updated');
|
||||
expect(screen.getByTestId('role').textContent).toBe('user');
|
||||
// Verify localStorage was updated too
|
||||
const storedUser = JSON.parse(store['test_auth_user']);
|
||||
expect(storedUser.name).toBe('Updated');
|
||||
expect(storedUser.role).toBe('user');
|
||||
});
|
||||
|
||||
it('updateUser is a no-op when no user is logged in', () => {
|
||||
const { AuthProvider, useAuth } = createTestAuth();
|
||||
let updateUserFn: (updates: Partial<TestUser>) => void;
|
||||
|
||||
function Component() {
|
||||
const { updateUser, user } = useAuth();
|
||||
updateUserFn = updateUser;
|
||||
return <span data-testid="user">{user ? 'yes' : 'no'}</span>;
|
||||
}
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<Component />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
act(() => {
|
||||
updateUserFn!({ name: 'Should not crash' });
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('user').textContent).toBe('no');
|
||||
});
|
||||
|
||||
it('onInit provides initial session from external source', () => {
|
||||
const initUser: TestUser = { email: 'sso@corp.com', name: 'SSO User', role: 'admin' };
|
||||
const { AuthProvider, useAuth } = createTestAuth({
|
||||
onInit: () => ({
|
||||
user: initUser,
|
||||
accessToken: 'sso-at',
|
||||
refreshToken: 'sso-rt',
|
||||
}),
|
||||
});
|
||||
|
||||
function Display() {
|
||||
const { user, isAuthenticated } = useAuth();
|
||||
return (
|
||||
<div>
|
||||
<span data-testid="auth">{String(isAuthenticated)}</span>
|
||||
<span data-testid="email">{user?.email ?? 'none'}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<Display />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('auth').textContent).toBe('true');
|
||||
expect(screen.getByTestId('email').textContent).toBe('sso@corp.com');
|
||||
// Verify tokens were saved
|
||||
expect(store['test_access_token']).toBe('sso-at');
|
||||
expect(store['test_refresh_token']).toBe('sso-rt');
|
||||
});
|
||||
|
||||
it('onInit returning null falls through to localStorage', () => {
|
||||
store['test_auth_user'] = JSON.stringify({
|
||||
email: 'stored@local.com',
|
||||
name: 'Local',
|
||||
role: 'user',
|
||||
});
|
||||
|
||||
const { AuthProvider, useAuth } = createTestAuth({
|
||||
onInit: () => null,
|
||||
});
|
||||
|
||||
function Display() {
|
||||
const { user } = useAuth();
|
||||
return <span data-testid="email">{user?.email ?? 'none'}</span>;
|
||||
}
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<Display />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('email').textContent).toBe('stored@local.com');
|
||||
});
|
||||
|
||||
it('onInit takes priority over localStorage when it returns a session', () => {
|
||||
store['test_auth_user'] = JSON.stringify({
|
||||
email: 'stored@local.com',
|
||||
name: 'Local',
|
||||
role: 'user',
|
||||
});
|
||||
|
||||
const { AuthProvider, useAuth } = createTestAuth({
|
||||
onInit: () => ({
|
||||
user: { email: 'init@override.com', name: 'Init', role: 'admin' },
|
||||
accessToken: 'init-at',
|
||||
refreshToken: 'init-rt',
|
||||
}),
|
||||
});
|
||||
|
||||
function Display() {
|
||||
const { user } = useAuth();
|
||||
return <span data-testid="email">{user?.email ?? 'none'}</span>;
|
||||
}
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<Display />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('email').textContent).toBe('init@override.com');
|
||||
});
|
||||
|
||||
it('uses correct storage prefix for keys', () => {
|
||||
const storedUser: TestUser = { email: 'x@y.com', name: 'X', role: 'viewer' };
|
||||
store['custom_auth_user'] = JSON.stringify(storedUser);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user