78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
|
|
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||
|
|
import http from 'node:http';
|
||
|
|
import { ApiClient, ApiError } from '../src/api-client.js';
|
||
|
|
|
||
|
|
let server: http.Server;
|
||
|
|
let port: number;
|
||
|
|
|
||
|
|
beforeAll(async () => {
|
||
|
|
server = http.createServer((req, res) => {
|
||
|
|
if (req.url === '/api/v1/servers' && req.method === 'GET') {
|
||
|
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||
|
|
res.end(JSON.stringify([{ id: 'srv-1', name: 'slack' }]));
|
||
|
|
} else if (req.url === '/api/v1/servers/srv-1' && req.method === 'GET') {
|
||
|
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||
|
|
res.end(JSON.stringify({ id: 'srv-1', name: 'slack', transport: 'STDIO' }));
|
||
|
|
} else if (req.url === '/api/v1/servers' && req.method === 'POST') {
|
||
|
|
const chunks: Buffer[] = [];
|
||
|
|
req.on('data', (c: Buffer) => chunks.push(c));
|
||
|
|
req.on('end', () => {
|
||
|
|
const body = JSON.parse(Buffer.concat(chunks).toString());
|
||
|
|
res.writeHead(201, { 'Content-Type': 'application/json' });
|
||
|
|
res.end(JSON.stringify({ id: 'srv-new', ...body }));
|
||
|
|
});
|
||
|
|
} else if (req.url === '/api/v1/missing' && req.method === 'GET') {
|
||
|
|
res.writeHead(404, { 'Content-Type': 'application/json' });
|
||
|
|
res.end(JSON.stringify({ error: 'Not found' }));
|
||
|
|
} else {
|
||
|
|
res.writeHead(404);
|
||
|
|
res.end();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
await new Promise<void>((resolve) => {
|
||
|
|
server.listen(0, () => {
|
||
|
|
const addr = server.address();
|
||
|
|
if (addr && typeof addr === 'object') {
|
||
|
|
port = addr.port;
|
||
|
|
}
|
||
|
|
resolve();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
afterAll(() => {
|
||
|
|
server.close();
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('ApiClient', () => {
|
||
|
|
it('performs GET request for list', async () => {
|
||
|
|
const client = new ApiClient({ baseUrl: `http://localhost:${port}` });
|
||
|
|
const result = await client.get<Array<{ id: string; name: string }>>('/api/v1/servers');
|
||
|
|
expect(result).toEqual([{ id: 'srv-1', name: 'slack' }]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('performs GET request for single item', async () => {
|
||
|
|
const client = new ApiClient({ baseUrl: `http://localhost:${port}` });
|
||
|
|
const result = await client.get<{ id: string; name: string }>('/api/v1/servers/srv-1');
|
||
|
|
expect(result.name).toBe('slack');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('performs POST request', async () => {
|
||
|
|
const client = new ApiClient({ baseUrl: `http://localhost:${port}` });
|
||
|
|
const result = await client.post<{ id: string; name: string }>('/api/v1/servers', { name: 'github' });
|
||
|
|
expect(result.id).toBe('srv-new');
|
||
|
|
expect(result.name).toBe('github');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws ApiError on 404', async () => {
|
||
|
|
const client = new ApiClient({ baseUrl: `http://localhost:${port}` });
|
||
|
|
await expect(client.get('/api/v1/missing')).rejects.toThrow(ApiError);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws on connection error', async () => {
|
||
|
|
const client = new ApiClient({ baseUrl: 'http://localhost:1' });
|
||
|
|
await expect(client.get('/anything')).rejects.toThrow();
|
||
|
|
});
|
||
|
|
});
|