mirror of
https://dev.azure.com/tstanciu94/PhantomMind/_git/Bitip
synced 2025-10-13 01:52:19 +03:00
- Changed main entry point from `index.js` to `server.js` in package.json. - Created a new `app.ts` file to encapsulate Express app configuration. - Removed old `index.ts` file and moved server logic to `server.ts`. - Updated nodemon configurations to point to the new `server.ts`. - Added new middleware for API key authentication with public endpoint support. - Modified validators to accept any string for IPs, allowing handlers to determine validity. - Added integration tests for batch lookup and health endpoints. - Implemented unit tests for error handling and validation middleware. - Updated `tsup` and `vitest` configurations to reflect new entry points and testing setup.
126 lines
3.7 KiB
TypeScript
126 lines
3.7 KiB
TypeScript
// Copyright (c) 2025 Tudor Stanciu
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
apiRequest,
|
|
TEST_API_KEY,
|
|
VALID_IPV4,
|
|
VALID_IPV6,
|
|
PRIVATE_IP,
|
|
INVALID_IP,
|
|
} from '../setup';
|
|
|
|
describe('Batch Lookup Endpoint', () => {
|
|
describe('POST /api/lookup/batch', () => {
|
|
it('should return results for valid IPs', async () => {
|
|
const response = await (
|
|
await apiRequest()
|
|
)
|
|
.post('/api/lookup/batch')
|
|
.set('X-API-Key', TEST_API_KEY)
|
|
.send({ ips: [VALID_IPV4, VALID_IPV6] })
|
|
.expect(200);
|
|
|
|
expect(response.body).toHaveProperty('succeeded');
|
|
expect(response.body).toHaveProperty('failed');
|
|
expect(Array.isArray(response.body.succeeded)).toBe(true);
|
|
expect(Array.isArray(response.body.failed)).toBe(true);
|
|
expect(response.body.succeeded.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should separate succeeded and failed results', async () => {
|
|
const response = await (
|
|
await apiRequest()
|
|
)
|
|
.post('/api/lookup/batch')
|
|
.set('X-API-Key', TEST_API_KEY)
|
|
.send({ ips: [VALID_IPV4, INVALID_IP] })
|
|
.expect(200);
|
|
|
|
expect(response.body.succeeded.length).toBeGreaterThan(0);
|
|
expect(response.body.failed.length).toBeGreaterThan(0);
|
|
expect(response.body.succeeded[0]).toHaveProperty('ip', VALID_IPV4);
|
|
expect(response.body.failed[0]).toHaveProperty('ip', INVALID_IP);
|
|
expect(response.body.failed[0]).toHaveProperty('error');
|
|
});
|
|
|
|
it('should filter out private IPs', async () => {
|
|
const response = await (
|
|
await apiRequest()
|
|
)
|
|
.post('/api/lookup/batch')
|
|
.set('X-API-Key', TEST_API_KEY)
|
|
.send({ ips: [VALID_IPV4, PRIVATE_IP] })
|
|
.expect(200);
|
|
|
|
const privateIpError = response.body.failed.find(
|
|
(f: any) => f.ip === PRIVATE_IP
|
|
);
|
|
expect(privateIpError).toBeDefined();
|
|
expect(privateIpError.error).toContain('Private IP');
|
|
});
|
|
|
|
it('should return all failures for invalid IPs', async () => {
|
|
const response = await (
|
|
await apiRequest()
|
|
)
|
|
.post('/api/lookup/batch')
|
|
.set('X-API-Key', TEST_API_KEY)
|
|
.send({ ips: ['invalid-1', 'invalid-2'] })
|
|
.expect(200);
|
|
|
|
expect(response.body.succeeded.length).toBe(0);
|
|
expect(response.body.failed.length).toBe(2);
|
|
});
|
|
|
|
it('should return 400 when ips array is missing', async () => {
|
|
const response = await apiRequest()
|
|
.post('/api/lookup/batch')
|
|
.set('X-API-Key', TEST_API_KEY)
|
|
.send({})
|
|
.expect(400);
|
|
|
|
expect(response.body).toHaveProperty('error', 'Bad Request');
|
|
});
|
|
|
|
it('should return 400 when ips array is empty', async () => {
|
|
const response = await apiRequest()
|
|
.post('/api/lookup/batch')
|
|
.set('X-API-Key', TEST_API_KEY)
|
|
.send({ ips: [] })
|
|
.expect(400);
|
|
|
|
expect(response.body).toHaveProperty('error', 'Bad Request');
|
|
});
|
|
|
|
it('should handle IPv4 and IPv6 mix', async () => {
|
|
const response = await (
|
|
await apiRequest()
|
|
)
|
|
.post('/api/lookup/batch')
|
|
.set('X-API-Key', TEST_API_KEY)
|
|
.send({ ips: [VALID_IPV4, VALID_IPV6] })
|
|
.expect(200);
|
|
|
|
expect(response.body.succeeded.length).toBe(2);
|
|
const ipv4Result = response.body.succeeded.find(
|
|
(r: any) => r.ip === VALID_IPV4
|
|
);
|
|
const ipv6Result = response.body.succeeded.find(
|
|
(r: any) => r.ip === VALID_IPV6
|
|
);
|
|
expect(ipv4Result).toBeDefined();
|
|
expect(ipv6Result).toBeDefined();
|
|
});
|
|
|
|
it('should reject request without API key', async () => {
|
|
await (
|
|
await apiRequest()
|
|
)
|
|
.post('/api/lookup/batch')
|
|
.send({ ips: [VALID_IPV4] })
|
|
.expect(401);
|
|
});
|
|
});
|
|
});
|