learning_ai_notes/mobile/src/store/auth-store.test.ts
saravanakumardb1 dd62d3bf5c test(web+mobile): Playwright E2E scaffold + 23 mobile store tests [C4, B7]
- web: playwright.config.ts + e2e/navigation.spec.ts (7 navigation tests, scaffolded)
- web: exclude e2e/ from tsconfig (playwright not yet installed as dep)
- mobile: notes-store.test.ts (7 tests: hydrate, openNote, saveDraft, updateNote)
- mobile: workspace-store.test.ts (5 tests: hydrate, preserve/reset active, set/clear)
- mobile: inbox-store.test.ts (5 tests: hydrate, approve, reject, unknown id guards)
- mobile: auth-store.test.ts (6 tests: bootstrap, signIn, signOut, failure paths)
- Total: 76 backend, 14 web, 23 mobile = 113 tests
2026-03-19 08:51:36 -07:00

81 lines
2.7 KiB
TypeScript

import { describe, expect, it, vi, beforeEach } from 'vitest';
const isAuthenticatedMock = vi.fn();
const getMeMock = vi.fn();
const loginMock = vi.fn();
const clearTokensMock = vi.fn();
vi.mock('../api/auth', () => ({
getAuthClient: () => ({
isAuthenticated: isAuthenticatedMock,
getMe: getMeMock,
login: loginMock,
clearTokens: clearTokensMock,
getAccessToken: vi.fn(() => null),
}),
}));
import { useAuthStore } from './auth-store';
function resetStore() {
useAuthStore.setState({
isAuthenticated: false,
isLoading: false,
email: null,
});
}
describe('useAuthStore', () => {
beforeEach(() => {
vi.clearAllMocks();
resetStore();
});
it('bootstrap sets authenticated when token exists', async () => {
isAuthenticatedMock.mockReturnValue(true);
getMeMock.mockResolvedValueOnce({ email: 'test@example.com' });
await useAuthStore.getState().bootstrap();
expect(useAuthStore.getState().isAuthenticated).toBe(true);
expect(useAuthStore.getState().email).toBe('test@example.com');
});
it('bootstrap sets unauthenticated when no token', async () => {
isAuthenticatedMock.mockReturnValue(false);
await useAuthStore.getState().bootstrap();
expect(useAuthStore.getState().isAuthenticated).toBe(false);
expect(useAuthStore.getState().email).toBeNull();
});
it('bootstrap clears tokens on getMe failure', async () => {
isAuthenticatedMock.mockReturnValue(true);
getMeMock.mockRejectedValueOnce(new Error('expired'));
await useAuthStore.getState().bootstrap();
expect(clearTokensMock).toHaveBeenCalled();
expect(useAuthStore.getState().isAuthenticated).toBe(false);
});
it('signIn sets authenticated on success', async () => {
loginMock.mockResolvedValueOnce(undefined);
const ok = await useAuthStore.getState().signIn('test@example.com', 'pass');
expect(ok).toBe(true);
expect(useAuthStore.getState().isAuthenticated).toBe(true);
expect(useAuthStore.getState().email).toBe('test@example.com');
});
it('signIn returns false on failure', async () => {
loginMock.mockRejectedValueOnce(new Error('bad credentials'));
const ok = await useAuthStore.getState().signIn('bad@example.com', 'wrong');
expect(ok).toBe(false);
expect(useAuthStore.getState().isAuthenticated).toBe(false);
expect(clearTokensMock).toHaveBeenCalled();
});
it('signOut clears state', () => {
useAuthStore.setState({ isAuthenticated: true, email: 'test@example.com' });
useAuthStore.getState().signOut();
expect(useAuthStore.getState().isAuthenticated).toBe(false);
expect(useAuthStore.getState().email).toBeNull();
expect(clearTokensMock).toHaveBeenCalled();
});
});