Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions packages/core/lib/rest/http-server/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,7 @@ export class Response {
/**
* Set the status code of the response
*/
if (!this.statusCode && method === 'POST') {
res.status(HttpStatus.CREATED);
} else if (this.statusCode) {
res.status(this.statusCode);
} else {
res.status(HttpStatus.OK);
}
res.status(this.statusCode ?? (method === 'POST' ? HttpStatus.CREATED : HttpStatus.OK));

/**
* Set the headers
Expand Down
110 changes: 110 additions & 0 deletions packages/core/tests/unit/rest/http-server/response.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Response } from '../../../../lib/rest/http-server/response';
import { HttpStatus } from '../../../../lib/rest/http-server/status-codes';
import { StreamableFile } from '../../../../lib/rest/http-server/streamable-file';

describe('Response', () => {
let response: Response;

beforeEach(() => {
response = new Response();
});

describe('status', () => {
it('should set status code and return response instance', () => {
const result = response.status(HttpStatus.CREATED);
expect(result).toBe(response);
expect((response as any).statusCode).toBe(HttpStatus.CREATED);
});
});

describe('header', () => {
it('should set header and return response instance', () => {
const result = response.header('Content-Type', 'application/json');
expect(result).toBe(response);
expect((response as any).responseHeaders.get('Content-Type')).toBe('application/json');
});
});

describe('type', () => {
it('should set content type header for json', () => {
const result = response.type('json');
expect(result).toBe(response);
expect((response as any).responseHeaders.get('Content-Type')).toBe('application/json');
});

it('should set content type header for text', () => {
response.type('text');
expect((response as any).responseHeaders.get('Content-Type')).toBe('text/plain');
});
});

describe('body', () => {
it('should set json body and content type', () => {
const data = { message: 'test' };
response.body(data);
expect((response as any).bodyData).toBe(JSON.stringify(data));
expect((response as any).responseHeaders.get('Content-Type')).toBe('application/json');
});

it('should set plain body without transformation', () => {
response.body('plain text');
expect((response as any).bodyData).toBe('plain text');
});
});

describe('text', () => {
it('should set text body with correct content type', () => {
response.text('hello world');
expect((response as any).bodyData).toBe('hello world');
expect((response as any).responseHeaders.get('Content-Type')).toBe('text/plain');
});
});

describe('json', () => {
it('should set json body with correct content type', () => {
const data = { message: 'test' };
response.json(data);
expect((response as any).bodyData).toBe(JSON.stringify(data));
expect((response as any).responseHeaders.get('Content-Type')).toBe('application/json');
});
});

describe('html', () => {
it('should set html body with correct content type', () => {
response.html('<p>unit test</p>');
expect((response as any).bodyData).toBe('<p>unit test</p>');
expect((response as any).responseHeaders.get('Content-Type')).toBe('text/html');
});
});

describe('notFound', () => {
it('should set 404 status code', () => {
response.notFound();
expect((response as any).statusCode).toBe(HttpStatus.NOT_FOUND);
});
});

describe('redirect', () => {
it('should set redirect status and location header', () => {
const redirectUrl = '/unit-test';
response.redirect(redirectUrl);
expect((response as any).statusCode).toBe(HttpStatus.FOUND);
expect((response as any).responseHeaders.get('location')).toBe(redirectUrl);
});
});

describe('reply', () => {
it('should properly set status, headers and body', () => {
const mockReq = { method: 'GET' };

response
.status(HttpStatus.OK)
.header('Content-Type', 'application/json')
.json({ message: 'success' });

expect((response as any).statusCode).toBe(HttpStatus.OK);
expect((response as any).responseHeaders.get('Content-Type')).toBe('application/json');
expect((response as any).bodyData).toBe(JSON.stringify({ message: 'success' }));
});
});
});
122 changes: 122 additions & 0 deletions packages/core/tests/unit/rest/http-server/server.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { MiddlewareNext } from 'hyper-express';
import { IntentMiddleware } from '../../../../lib/rest';
import { HyperServer } from '../../../../lib/rest/http-server/server';
import { Request, Response } from '@intentjs/hyper-express';
import { ConfigService } from '../../../../lib/config';

jest.mock('../../../../lib/config', () => ({
ConfigService: {
get: (key: string) => ({})
}
}));

describe('HyperServer', () => {
let server: HyperServer;

beforeEach(() => {
server = new HyperServer();
});

describe('useGlobalMiddlewares', () => {
it('should register global middleware', async () => {
const mockMiddleware = async (req: Request, res: Response, next: MiddlewareNext) => {};

server.useGlobalMiddlewares([mockMiddleware as unknown as IntentMiddleware]);

expect(server.globalMiddlewares).toHaveLength(1);
expect(server.globalMiddlewares[0]).toBe(mockMiddleware);
});
});

describe('build', () => {
it('should register GET route', async () => {
const mockRoute = {
method: 'GET',
path: '/test',
httpHandler: jest.fn()
};

const routeMiddlewares = new Map();
routeMiddlewares.set('GET:/test', []);

server.useRouteMiddlewares(routeMiddlewares);
await server.build([mockRoute], {});

const routes = ((server as any).hyper).routes;

expect(routes).toMatchObject({
get: {
'/test': expect.objectContaining({
path: '/test',
method: 'GET',
})
},
post: {},
put: {},
del: {}
});
});

it('should register different HTTP method routes', async () => {
const mockRoutes = [
{
method: 'GET',
path: '/test',
httpHandler: jest.fn()
},
{
method: 'POST',
path: '/test',
httpHandler: jest.fn()
},
{
method: 'PUT',
path: '/test',
httpHandler: jest.fn()
},
{
method: 'DELETE',
path: '/test',
httpHandler: jest.fn()
}
];

const routeMiddlewares = new Map();
routeMiddlewares.set('GET:/test', []);
routeMiddlewares.set('POST:/test', []);
routeMiddlewares.set('PUT:/test', []);
routeMiddlewares.set('DELETE:/test', []);

server.useRouteMiddlewares(routeMiddlewares);
await server.build(mockRoutes, {});

const routes = ((server as any).hyper).routes;
expect(routes).toMatchObject({
get: {
'/test': expect.objectContaining({
path: '/test',
method: 'GET',
})
},
post: {
'/test': expect.objectContaining({
path: '/test',
method: 'POST',
})
},
put: {
'/test': expect.objectContaining({
path: '/test',
method: 'PUT',
})
},
del: {
'/test': expect.objectContaining({
path: '/test',
method: 'DELETE',
})
}
});
});
});
});