Files
smartserve/test/test.ts
2025-11-29 15:24:00 +00:00

209 lines
5.4 KiB
TypeScript

import { expect, tap } from '@git.zone/tstest/tapbundle';
import {
SmartServe,
Route,
Get,
Post,
Guard,
Transform,
Intercept,
HttpError,
type IRequestContext,
} from '../ts/index.js';
// Test controller
@Route('/api')
class TestController {
@Get('/hello')
hello() {
return { message: 'Hello World' };
}
@Get('/users/:id')
getUser(ctx: IRequestContext) {
return { id: ctx.params.id, name: 'Test User' };
}
@Post('/echo')
echo(ctx: IRequestContext<{ text: string }>) {
return { echo: ctx.body?.text };
}
}
// Controller with guards
const isAuthenticated = (ctx: IRequestContext) => {
return ctx.headers.has('Authorization');
};
@Route('/protected')
@Guard(isAuthenticated)
class ProtectedController {
@Get('/data')
getData() {
return { secret: 'protected data' };
}
}
// Controller with transforms
const wrapResponse = <T>(data: T) => ({ success: true, data, timestamp: Date.now() });
@Route('/wrapped')
@Transform(wrapResponse)
class WrappedController {
@Get('/info')
getInfo() {
return { version: '1.0.0' };
}
}
tap.test('SmartServe should create server instance', async () => {
const server = new SmartServe({ port: 3456 });
expect(server).toBeInstanceOf(SmartServe);
expect(server.isRunning()).toBeFalse();
});
tap.test('SmartServe should register controllers', async () => {
const server = new SmartServe({ port: 3457 });
server.register(TestController);
server.register(ProtectedController);
server.register(WrappedController);
expect(server).toBeInstanceOf(SmartServe);
});
tap.test('SmartServe should start and stop', async () => {
const server = new SmartServe({ port: 3458 });
server.register(TestController);
const instance = await server.start();
expect(instance.port).toEqual(3458);
expect(instance.runtime).toEqual('node');
expect(server.isRunning()).toBeTrue();
await server.stop();
expect(server.isRunning()).toBeFalse();
});
tap.test('SmartServe should handle GET request', async () => {
const server = new SmartServe({ port: 3459 });
server.register(TestController);
await server.start();
try {
const response = await fetch('http://localhost:3459/api/hello');
const data = await response.json();
expect(response.status).toEqual(200);
expect(data.message).toEqual('Hello World');
} finally {
await server.stop();
}
});
tap.test('SmartServe should handle path parameters', async () => {
const server = new SmartServe({ port: 3460 });
server.register(TestController);
await server.start();
try {
const response = await fetch('http://localhost:3460/api/users/123');
const data = await response.json();
expect(response.status).toEqual(200);
expect(data.id).toEqual('123');
expect(data.name).toEqual('Test User');
} finally {
await server.stop();
}
});
tap.test('SmartServe should handle POST with body', async () => {
const server = new SmartServe({ port: 3461 });
server.register(TestController);
await server.start();
try {
const response = await fetch('http://localhost:3461/api/echo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'Hello!' }),
});
const data = await response.json();
expect(response.status).toEqual(200);
expect(data.echo).toEqual('Hello!');
} finally {
await server.stop();
}
});
tap.test('SmartServe should enforce guards', async () => {
const server = new SmartServe({ port: 3462 });
server.register(ProtectedController);
await server.start();
try {
// Without auth header - should be forbidden
const response1 = await fetch('http://localhost:3462/protected/data');
expect(response1.status).toEqual(403);
// With auth header - should succeed
const response2 = await fetch('http://localhost:3462/protected/data', {
headers: { Authorization: 'Bearer token123' },
});
const data = await response2.json();
expect(response2.status).toEqual(200);
expect(data.secret).toEqual('protected data');
} finally {
await server.stop();
}
});
tap.test('SmartServe should apply transforms', async () => {
const server = new SmartServe({ port: 3463 });
server.register(WrappedController);
await server.start();
try {
const response = await fetch('http://localhost:3463/wrapped/info');
const data = await response.json();
expect(response.status).toEqual(200);
expect(data.success).toBeTrue();
expect(data.data.version).toEqual('1.0.0');
expect(data.timestamp).toBeTypeofNumber();
} finally {
await server.stop();
}
});
tap.test('SmartServe should return 404 for unknown routes', async () => {
const server = new SmartServe({ port: 3464 });
server.register(TestController);
await server.start();
try {
const response = await fetch('http://localhost:3464/unknown/route');
expect(response.status).toEqual(404);
} finally {
await server.stop();
}
});
tap.test('HttpError should create proper responses', async () => {
const error = HttpError.notFound('Resource not found', { id: '123' });
expect(error.status).toEqual(404);
expect(error.message).toEqual('Resource not found');
expect(error.details).toEqual({ id: '123' });
const response = error.toResponse();
expect(response.status).toEqual(404);
const body = await response.json();
expect(body.error).toEqual('Resource not found');
expect(body.details.id).toEqual('123');
});
export default tap.start();