Some checks failed
95 tests across 22 files covering all frontend modules: - API layer: client, auth - Components: BondDetails, Layout, PriceChart, ProtectedRoute, SearchBar, StockDetails - Context: AuthContext - Hooks: useAuth, useBond, useBondCandles, useSearch, useStock, useStockCandles, useStockDividends - Pages: BondPage, HomePage, LoginPage, ProfilePage, RegisterPage, StockPage Infrastructure: - vitest + @testing-library/react + MSW v2 with 13 API handlers - Co-located test files alongside source files - Test utilities: setup, server, factories, test-utils - BrowserRouter future flags for MemoryRouter test compatibility - Root test:frontend script for workspace-wide execution
69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest';
|
|
import { http, HttpResponse } from 'msw';
|
|
import { server } from '../test/server';
|
|
import { setAccessToken, getAccessToken } from './client';
|
|
import { login, register, refresh, logout, getMe, updateProfile } from './auth';
|
|
|
|
const API = '/api/v1';
|
|
|
|
beforeEach(() => {
|
|
setAccessToken(null);
|
|
});
|
|
|
|
describe('login', () => {
|
|
it('returns auth data and sets access token', async () => {
|
|
const result = await login('user@test.com', 'password');
|
|
expect(result.user.email).toBe('user@test.com');
|
|
expect(result.accessToken).toBe('mock-access-token');
|
|
expect(getAccessToken()).toBe('mock-access-token');
|
|
});
|
|
|
|
it('throws on invalid credentials', async () => {
|
|
server.use(
|
|
http.post(
|
|
`${API}/auth/login`,
|
|
() => new HttpResponse(null, { status: 401, statusText: 'Unauthorized' }),
|
|
),
|
|
);
|
|
await expect(login('wrong@test.com', 'wrong')).rejects.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('register', () => {
|
|
it('returns auth data and sets access token', async () => {
|
|
const result = await register('new@test.com', 'password', 'New User');
|
|
expect(result.user.email).toBe('user@test.com');
|
|
expect(getAccessToken()).toBe('mock-access-token');
|
|
});
|
|
});
|
|
|
|
describe('refresh', () => {
|
|
it('returns auth data and sets access token', async () => {
|
|
const result = await refresh();
|
|
expect(result.accessToken).toBe('mock-access-token');
|
|
expect(getAccessToken()).toBe('mock-access-token');
|
|
});
|
|
});
|
|
|
|
describe('logout', () => {
|
|
it('clears access token', async () => {
|
|
setAccessToken('test-token');
|
|
await logout();
|
|
expect(getAccessToken()).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('getMe', () => {
|
|
it('returns current user', async () => {
|
|
const result = await getMe();
|
|
expect(result.email).toBe('user@test.com');
|
|
});
|
|
});
|
|
|
|
describe('updateProfile', () => {
|
|
it('updates and returns user', async () => {
|
|
const result = await updateProfile({ name: 'Updated' });
|
|
expect(result.name).toBe('Updated');
|
|
});
|
|
});
|