refactor: Separate middleware from Express.

This commit is contained in:
Ruben Verborgh
2020-11-29 23:24:29 +01:00
parent de079062be
commit 023ff80f48
18 changed files with 227 additions and 54 deletions

View File

@@ -42,7 +42,6 @@ describe('ExpressHttpServerFactory', (): void => {
});
afterEach(async(): Promise<void> => {
// Close server
server.close();
});
@@ -50,36 +49,6 @@ describe('ExpressHttpServerFactory', (): void => {
mock.mockReset();
});
it('sends server identification in the X-Powered-By header.', async(): Promise<void> => {
const res = await request(server).get('/');
expect(res.header).toEqual(expect.objectContaining({
'x-powered-by': 'Community Solid Server',
}));
});
it('returns CORS headers for an OPTIONS request.', async(): Promise<void> => {
const res = await request(server)
.options('/')
.set('Access-Control-Request-Headers', 'content-type')
.set('Access-Control-Request-Method', 'POST')
.set('Host', 'test.com')
.expect(204);
expect(res.header).toEqual(expect.objectContaining({
'access-control-allow-origin': '*',
'access-control-allow-headers': 'content-type',
}));
const corsMethods = res.header['access-control-allow-methods'].split(',')
.map((method: string): string => method.trim());
const allowedMethods = [ 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE' ];
expect(corsMethods).toEqual(expect.arrayContaining(allowedMethods));
expect(corsMethods).toHaveLength(allowedMethods.length);
});
it('specifies CORS origin header if an origin was supplied.', async(): Promise<void> => {
const res = await request(server).get('/').set('origin', 'test.com').expect(200);
expect(res.header).toEqual(expect.objectContaining({ 'access-control-allow-origin': 'test.com' }));
});
it('sends incoming requests to the handler.', async(): Promise<void> => {
await request(server).get('/').set('Host', 'test.com').expect(200);
expect(canHandleJest).toHaveBeenCalledTimes(1);

View File

@@ -0,0 +1,33 @@
import { createRequest, createResponse } from 'node-mocks-http';
import { CorsHandler } from '../../../../src/server/middleware/CorsHandler';
import { guardStream } from '../../../../src/util/GuardedStream';
describe('a CorsHandler', (): void => {
let handler: CorsHandler;
beforeAll(async(): Promise<void> => {
handler = new CorsHandler();
});
it('returns CORS headers.', async(): Promise<void> => {
const request = guardStream(createRequest());
const response = createResponse();
await handler.handleSafe({ request, response });
expect(response.getHeaders()).toEqual(expect.objectContaining({
'access-control-allow-origin': '*',
}));
});
it('echoes the origin when specified.', async(): Promise<void> => {
const request = guardStream(createRequest({
headers: {
origin: 'example.org',
},
}));
const response = createResponse();
await handler.handleSafe({ request, response });
expect(response.getHeaders()).toEqual(expect.objectContaining({
'access-control-allow-origin': 'example.org',
}));
});
});

View File

@@ -0,0 +1,20 @@
import { createRequest, createResponse } from 'node-mocks-http';
import { HeaderHandler } from '../../../../src/server/middleware/HeaderHandler';
import { guardStream } from '../../../../src/util/GuardedStream';
describe('a HeaderHandler', (): void => {
let handler: HeaderHandler;
beforeAll(async(): Promise<void> => {
handler = new HeaderHandler();
});
it('returns an X-Powered-By header.', async(): Promise<void> => {
const request = guardStream(createRequest());
const response = createResponse();
await handler.handleSafe({ request, response });
expect(response.getHeaders()).toEqual(expect.objectContaining({
'x-powered-by': 'Community Solid Server',
}));
});
});