161 lines
4.9 KiB
TypeScript
161 lines
4.9 KiB
TypeScript
import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
|
|
import { HttpClient, HttpError } from '../src/index';
|
|
import { MockServer } from './mock-server';
|
|
|
|
/**
|
|
* Integration tests for HTTP client with real network scenarios
|
|
* These tests use external services and may be affected by network conditions
|
|
*/
|
|
|
|
let mockServer: MockServer;
|
|
let mockServerBaseUrl: string;
|
|
|
|
beforeAll(async () => {
|
|
mockServer = new MockServer();
|
|
await mockServer.start();
|
|
mockServerBaseUrl = mockServer.getBaseUrl();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await mockServer.stop();
|
|
});
|
|
|
|
describe('HTTP Integration Tests', () => {
|
|
let client: HttpClient;
|
|
|
|
beforeAll(() => {
|
|
client = new HttpClient({
|
|
timeout: 10000,
|
|
});
|
|
});
|
|
|
|
describe('Real-world scenarios', () => {
|
|
test('should handle JSON API responses', async () => {
|
|
try {
|
|
const response = await client.get('https://jsonplaceholder.typicode.com/posts/1');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.data).toHaveProperty('id');
|
|
expect(response.data).toHaveProperty('title');
|
|
expect(response.data).toHaveProperty('body');
|
|
} catch (error) {
|
|
console.warn('External API test skipped due to network issues:', (error as Error).message);
|
|
}
|
|
});
|
|
|
|
test('should handle large responses', async () => {
|
|
try {
|
|
const response = await client.get('https://jsonplaceholder.typicode.com/posts');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(Array.isArray(response.data)).toBe(true);
|
|
expect(response.data.length).toBeGreaterThan(0);
|
|
} catch (error) {
|
|
console.warn(
|
|
'Large response test skipped due to network issues:',
|
|
(error as Error).message
|
|
);
|
|
}
|
|
});
|
|
|
|
test('should handle POST with JSON data', async () => {
|
|
try {
|
|
const postData = {
|
|
title: 'Integration Test Post',
|
|
body: 'This is a test post from integration tests',
|
|
userId: 1,
|
|
};
|
|
|
|
const response = await client.post('https://jsonplaceholder.typicode.com/posts', postData);
|
|
|
|
expect(response.status).toBe(201);
|
|
expect(response.data).toHaveProperty('id');
|
|
expect(response.data.title).toBe(postData.title);
|
|
} catch (error) {
|
|
console.warn(
|
|
'POST integration test skipped due to network issues:',
|
|
(error as Error).message
|
|
);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('Error scenarios with mock server', () => {
|
|
test('should handle various HTTP status codes', async () => {
|
|
const successCodes = [200, 201];
|
|
const errorCodes = [400, 401, 403, 404, 500, 503];
|
|
|
|
// Test success codes
|
|
for (const statusCode of successCodes) {
|
|
const response = await client.get(`${mockServerBaseUrl}/status/${statusCode}`);
|
|
expect(response.status).toBe(statusCode);
|
|
}
|
|
|
|
// Test error codes (should throw HttpError)
|
|
for (const statusCode of errorCodes) {
|
|
await expect(client.get(`${mockServerBaseUrl}/status/${statusCode}`)).rejects.toThrow(
|
|
HttpError
|
|
);
|
|
}
|
|
});
|
|
|
|
test('should handle malformed responses gracefully', async () => {
|
|
// Mock server returns valid JSON, so this test verifies our client handles it properly
|
|
const response = await client.get(`${mockServerBaseUrl}/`);
|
|
expect(response.status).toBe(200);
|
|
expect(typeof response.data).toBe('object');
|
|
});
|
|
|
|
test('should handle concurrent requests', async () => {
|
|
const requests = Array.from({ length: 5 }, (_, i) =>
|
|
client.get(`${mockServerBaseUrl}/`, {
|
|
headers: { 'X-Request-ID': `req-${i}` },
|
|
})
|
|
);
|
|
|
|
const responses = await Promise.all(requests);
|
|
|
|
responses.forEach((response, index) => {
|
|
expect(response.status).toBe(200);
|
|
expect(response.data.headers).toHaveProperty('x-request-id', `req-${index}`);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Performance and reliability', () => {
|
|
test('should handle rapid sequential requests', async () => {
|
|
const startTime = Date.now();
|
|
const requests = [];
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
requests.push(client.get(`${mockServerBaseUrl}/`));
|
|
}
|
|
|
|
const responses = await Promise.all(requests);
|
|
const endTime = Date.now();
|
|
|
|
expect(responses).toHaveLength(10);
|
|
responses.forEach(response => {
|
|
expect(response.status).toBe(200);
|
|
});
|
|
|
|
console.log(`Completed 10 requests in ${endTime - startTime}ms`);
|
|
});
|
|
|
|
test('should maintain connection efficiency', async () => {
|
|
const clientWithKeepAlive = new HttpClient({
|
|
timeout: 5000,
|
|
});
|
|
|
|
const requests = Array.from({ length: 3 }, () =>
|
|
clientWithKeepAlive.get(`${mockServerBaseUrl}/`)
|
|
);
|
|
|
|
const responses = await Promise.all(requests);
|
|
|
|
responses.forEach(response => {
|
|
expect(response.status).toBe(200);
|
|
});
|
|
});
|
|
});
|
|
});
|