@dbs-portal/core-api
Version:
HTTP client and API utilities for DBS Portal
221 lines • 10.3 kB
JavaScript
/**
* Example MSW integration tests
*/
import { describe, it, expect, afterEach, afterAll } from 'vitest';
import { http, HttpResponse } from 'msw';
import { setupMSWTesting, mockHelpers, testFactories, testAssertions } from './test-utils';
import { createApiClient } from '../../client/factory';
import { createApiUrl, MSW_HEADERS } from './msw-utils';
describe('MSW Integration Examples', () => {
const msw = setupMSWTesting();
afterEach(() => {
msw.cleanup();
});
afterAll(() => {
msw.teardown();
});
describe('Basic API Mocking', () => {
it('should mock a simple GET request', async () => {
// Add custom handler for this test
msw.addHandlers(http.get(createApiUrl('/api/test'), () => {
return HttpResponse.json(mockHelpers.success({ message: 'Hello from mock!' }));
}));
const client = createApiClient({
baseURL: 'http://localhost:3000',
headers: MSW_HEADERS
});
const response = await client.get('/api/test');
expect(testAssertions.isSuccessResponse(response.data)).toBe(true);
expect(response.data.data.message).toBe('Hello from mock!');
});
it('should mock a POST request with validation', async () => {
msw.addHandlers(http.post(createApiUrl('/api/users'), async ({ request }) => {
const body = await request.json();
if (!body.email) {
return HttpResponse.json(mockHelpers.validationError([
{ field: 'email', message: 'Email is required' }
]), { status: 422 });
}
const user = testFactories.user({ email: body.email });
return HttpResponse.json(mockHelpers.success(user), { status: 201 });
}));
const client = createApiClient({
baseURL: 'http://localhost:3000',
headers: MSW_HEADERS
});
// Test validation error
try {
await client.post('/api/users', {});
}
catch (error) {
expect(error.response.status).toBe(422);
expect(testAssertions.isErrorResponse(error.response.data)).toBe(true);
}
// Test successful creation
const response = await client.post('/api/users', { email: 'test@example.com' });
expect(response.status).toBe(201);
expect(testAssertions.isSuccessResponse(response.data)).toBe(true);
expect(response.data.data.email).toBe('test@example.com');
});
});
describe('Authentication Mocking', () => {
it('should mock login flow', async () => {
const client = createApiClient({
baseURL: 'http://localhost:3000',
headers: MSW_HEADERS
});
// Test login
const loginResponse = await client.post('/api/auth/login', {
email: 'test@example.com',
password: 'password123'
});
expect(testAssertions.isSuccessResponse(loginResponse.data)).toBe(true);
expect(loginResponse.data.data.tokens.accessToken).toBeDefined();
expect(loginResponse.data.data.user.email).toBe('test@example.com');
// Test authenticated request
const token = loginResponse.data.data.tokens.accessToken;
const meResponse = await client.get('/api/auth/me', {
headers: { Authorization: `Bearer ${token}` }
});
expect(testAssertions.isSuccessResponse(meResponse.data)).toBe(true);
expect(meResponse.data.data.email).toBe('test@example.com');
});
it('should handle invalid credentials', async () => {
const client = createApiClient({
baseURL: 'http://localhost:3000',
headers: MSW_HEADERS
});
try {
await client.post('/api/auth/login', {
email: 'wrong@example.com',
password: 'wrongpassword'
});
}
catch (error) {
expect(error.response.status).toBe(400);
expect(testAssertions.isErrorResponse(error.response.data)).toBe(true);
expect(error.response.data.errors[0].code).toBe('INVALID_CREDENTIALS');
}
});
});
describe('CRUD Operations', () => {
it('should mock CRUD operations for users', async () => {
// Add CRUD handlers for users
const users = [];
let nextId = 1;
msw.addHandlers(
// GET /api/users - List users
http.get(createApiUrl('/api/users'), ({ request }) => {
const url = new URL(request.url);
const page = Number.parseInt(url.searchParams.get('page') || '1', 10);
const pageSize = Number.parseInt(url.searchParams.get('pageSize') || '10', 10);
return HttpResponse.json(mockHelpers.paginated(users, page, pageSize));
}),
// POST /api/users - Create user
http.post(createApiUrl('/api/users'), async ({ request }) => {
const body = await request.json();
const user = testFactories.user({ ...body, id: `user_${nextId++}` });
users.push(user);
return HttpResponse.json(mockHelpers.success(user), { status: 201 });
}),
// GET /api/users/:id - Get user by ID
http.get(createApiUrl('/api/users/:id'), ({ params }) => {
const user = users.find(u => u.id === params['id']);
if (!user) {
return HttpResponse.json(mockHelpers.error('User not found', 'NOT_FOUND'), { status: 404 });
}
return HttpResponse.json(mockHelpers.success(user));
}),
// PUT /api/users/:id - Update user
http.put(createApiUrl('/api/users/:id'), async ({ params, request }) => {
const userIndex = users.findIndex(u => u.id === params['id']);
if (userIndex === -1) {
return HttpResponse.json(mockHelpers.error('User not found', 'NOT_FOUND'), { status: 404 });
}
const body = await request.json();
users[userIndex] = { ...users[userIndex], ...body, updatedAt: new Date().toISOString() };
return HttpResponse.json(mockHelpers.success(users[userIndex]));
}),
// DELETE /api/users/:id - Delete user
http.delete(createApiUrl('/api/users/:id'), ({ params }) => {
const userIndex = users.findIndex(u => u.id === params['id']);
if (userIndex === -1) {
return HttpResponse.json(mockHelpers.error('User not found', 'NOT_FOUND'), { status: 404 });
}
users.splice(userIndex, 1);
return HttpResponse.json(mockHelpers.success(null), { status: 204 });
}));
const client = createApiClient({
baseURL: 'http://localhost:3000',
headers: MSW_HEADERS
});
// Test create
const createResponse = await client.post('/api/users', {
email: 'new@example.com',
firstName: 'New',
lastName: 'User'
});
expect(createResponse.status).toBe(201);
expect(testAssertions.isSuccessResponse(createResponse.data)).toBe(true);
const userId = createResponse.data.data.id;
// Test get by ID
const getResponse = await client.get(`/api/users/${userId}`);
expect(testAssertions.isSuccessResponse(getResponse.data)).toBe(true);
expect(getResponse.data.data.email).toBe('new@example.com');
// Test list
const listResponse = await client.get('/api/users');
expect(testAssertions.isPaginatedResponse(listResponse.data)).toBe(true);
expect(listResponse.data.data.items).toHaveLength(1);
// Test update
const updateResponse = await client.put(`/api/users/${userId}`, {
firstName: 'Updated'
});
expect(testAssertions.isSuccessResponse(updateResponse.data)).toBe(true);
expect(updateResponse.data.data.firstName).toBe('Updated');
// Test delete
const deleteResponse = await client.delete(`/api/users/${userId}`);
expect(deleteResponse.status).toBe(204);
// Verify deletion
try {
await client.get(`/api/users/${userId}`);
}
catch (error) {
expect(error.response.status).toBe(404);
}
});
});
describe('Error Simulation', () => {
it('should simulate network errors', async () => {
msw.addHandlers(http.get(createApiUrl('/api/network-error'), () => {
return HttpResponse.error();
}));
const client = createApiClient({
baseURL: 'http://localhost:3000',
headers: MSW_HEADERS
});
try {
await client.get('/api/network-error');
}
catch (error) {
expect(error.code).toBe('ERR_NETWORK');
}
});
it('should simulate server errors', async () => {
msw.addHandlers(http.get(createApiUrl('/api/server-error'), () => {
return HttpResponse.json(mockHelpers.error('Internal server error', 'INTERNAL_ERROR'), { status: 500 });
}));
const client = createApiClient({
baseURL: 'http://localhost:3000',
headers: MSW_HEADERS
});
try {
await client.get('/api/server-error');
}
catch (error) {
expect(error.response.status).toBe(500);
expect(testAssertions.isErrorResponse(error.response.data)).toBe(true);
}
});
});
});
//# sourceMappingURL=example.test.js.map