Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade roc-package-web-app to use Koa@2 #30

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"env": {
"jest": true
},

"extends": "airbnb",

"parser": "babel-eslint",
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ lib
build
package-lock.json
yarn.lock
.idea
coverage/
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
"eslint-plugin-import": "^1.16.0",
"eslint-plugin-jsx-a11y": "2.2.1",
"eslint-plugin-react": "6.2.0",
"jest": "^22.0.0",
"roc": "^1.0.0-rc.23",
"roc-plugin-repo": "0.0.25",
"roc-plugin-repo": "0.1.6",
"roc-plugin-repo-roc": "0.0.1"
}
}
26 changes: 13 additions & 13 deletions packages/roc-package-web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@
"dependencies": {
"config": "~1.16.0",
"debug": "~2.2.0",
"koa": "~1.1.1",
"koa-accesslog": "~0.0.2",
"koa-add-trailing-slashes": "~1.1.0",
"koa-compressor": "~1.0.3",
"koa": "~2.4.1",
"koa-add-trailing-slashes": "~2.0.1",
"koa-compress": "~2.0.0",
"koa-conditional-get": "~1.0.3",
"koa-errors": "~1.0.1",
"koa-etag": "~2.0.0",
"koa-favicon": "~1.2.0",
"koa-helmet": "~0.3.0",
"koa-logger": "~1.3.0",
"koa-lowercase-path": "~1.0.0",
"koa-normalize-path": "~1.0.0",
"koa-remove-trailing-slashes": "~1.0.0",
"koa-static": "~2.0.0",
"koa-error": "~3.1.1",
"koa-etag": "~3.0.0",
"koa-favicon": "~2.0.0",
"koa-helmet": "~3.3.0",
"koa-logger": "~3.1.0",
"koa-lowercase-path": "~2.0.0",
"koa-normalize-path": "~2.0.0",
"koa-remove-trailing-slashes": "~2.0.0",
"koa-static": "~4.0.2",
"lodash": "4.13.1",
"moment": "~2.20.1",
"roc": "^1.0.0-rc.23",
"roc-package-webpack-node": "^1.0.0",
"roc-package-webpack-web": "^1.0.0"
Expand Down
8 changes: 4 additions & 4 deletions packages/roc-package-web-app/src/app/createServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import http from 'http';
import https from 'https';

import debug from 'debug';
import koa from 'koa';
import Koa from 'koa';
import serve from 'koa-static';
import addTrailingSlash from 'koa-add-trailing-slashes';
import normalizePath from 'koa-normalize-path';
import lowercasePath from 'koa-lowercase-path';
import removeTrailingSlash from 'koa-remove-trailing-slashes';
import { merge, getSettings, getAbsolutePath } from 'roc';

import basepathSupport from './basepathSupport';
import basepathSupport from './middlewares/basepathSupport';

/**
* Creates a server instance.
Expand Down Expand Up @@ -41,15 +41,15 @@ export default function createServer(options = {}, beforeUserMiddlewares = [], {
const logger = debug('roc:server');
logger.log = console.info.bind(console);

const server = koa();
const server = new Koa();
const runtimeSettings = merge(getSettings('runtime'), options);

// Add support for rocPath
server.use(basepathSupport(rocPath));

if (useDefaultKoaMiddlewares) {
// eslint-disable-next-line
const middlewares = require('./middlewares').default(runtimeSettings, { dev, dist });
const middlewares = require('./defaultKoaMiddlewares').default(runtimeSettings, { dev, dist });
middlewares.forEach((middleware) => server.use(middleware));
}

Expand Down
202 changes: 202 additions & 0 deletions packages/roc-package-web-app/src/app/createServer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import { readFileSync as readFileSyncMock } from 'fs';
import { createServer as createHttpServerMock } from 'http';
import { createServer as createHttpsServerMock } from 'https';

import Koa from 'koa';
import serveMiddlewareMock from 'koa-static';
import removeTrailingSlashMiddlewareMock from 'koa-remove-trailing-slashes';
import normalizePathMiddlewareMock from 'koa-normalize-path';
import lowercasePathMiddlewareMock from 'koa-lowercase-path';
import addTrailingSlashMiddlewareMock from 'koa-add-trailing-slashes';

import basepathMiddlewareMock from './middlewares/basepathSupport';
import createServer from './createServer';

jest.mock('roc', () => ({
getSettings: () => {},
merge: (_, a) => a,
getAbsolutePath: a => a,
}));
jest.mock('./middlewares/basepathSupport', () => jest.fn(() => function basepath() {}));
jest.mock('koa-remove-trailing-slashes', () => jest.fn(() => function removeTrailingSlash() {}));
jest.mock('koa-static', () => jest.fn(() => function serve() {}));
jest.mock('koa-normalize-path', () => jest.fn(() => function normalizePath() {}));
jest.mock('koa-lowercase-path', () => jest.fn(() => function lowercasePath() {}));
jest.mock('koa-add-trailing-slashes', () => jest.fn(() => function addTrailingSlash() {}));
jest.mock('fs');
jest.mock('http', () => ({
createServer: jest.fn(() => ({
listen: jest.fn(() => 'http'),
})),
}));
jest.mock('https', () => ({
createServer: jest.fn(() => ({
listen: jest.fn(() => 'https'),
})),
}));


describe('createServer', () => {
let options;
let beforeUserMiddlewares;
let params;

beforeEach(() => {
options = {
koa: {
staticServe: {
maxage: 42,
},
normalize: {
enabled: false,
defer: false,
},
lowercase: {
enabled: false,
defer: false,
},
trailingSlashes: {
enabled: false,
defer: false,
},
},
serve: '/static',
port: 4000,
https: {
port: 4001,
key: '/pathtokey',
cert: '/pathtocert',
},
};
beforeUserMiddlewares = [];
params = {
useDefaultKoaMiddlewares: false,
hasKoaMiddlewares: false,
koaMiddlewares: {
default: () => [],
},
dev: false,
dist: false,
rocPath: '/rocPath',
};
});

afterEach(() => {
basepathMiddlewareMock.mockClear();
removeTrailingSlashMiddlewareMock.mockClear();
serveMiddlewareMock.mockClear();
});

it('should return object with Koa server and start function', () => {
const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server).toBeInstanceOf(Koa);
expect(result.start).toBeInstanceOf(Function);
});

it('should add predefined set of middlewares to the Koa instance', () => {
const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toEqual(3);
expect(result.server.middleware.map(f => f.name))
.toEqual(['basepath', 'removeTrailingSlash', 'serve']);
expect(basepathMiddlewareMock).toHaveBeenCalledWith(params.rocPath);
expect(removeTrailingSlashMiddlewareMock).toHaveBeenCalled();
expect(serveMiddlewareMock).toHaveBeenCalledWith(options.serve, expect.anything());
});

it('should add defaultKoaMiddlewares to Koa instance if proper param is set to true', () => {
params.useDefaultKoaMiddlewares = true;

const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toEqual(6);
expect(result.server.middleware.map(f => f.name))
.toEqual(['basepath', 'middleware', 'etag', 'logger', 'removeTrailingSlash', 'serve']);
});

it('should include beforeUserMiddleware to Koa instance', () => {
beforeUserMiddlewares = [
function middlewareOne() {},
function middlewareTwo() {},
];

const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toEqual(5);
expect(result.server.middleware.map(f => f.name))
.toEqual(['basepath', 'middlewareOne', 'middlewareTwo', 'removeTrailingSlash', 'serve']);
});

it('should include koaMiddlewares to Koa instance', () => {
const koaMiddlewaresMock = jest.fn(() => [
function koaMiddlewareOne() {},
function koaMiddlewareTwo() {},
]);
params.hasKoaMiddlewares = true;
params.koaMiddlewares.default = koaMiddlewaresMock;

const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toEqual(5);
expect(result.server.middleware.map(f => f.name))
.toEqual(['basepath', 'koaMiddlewareOne', 'koaMiddlewareTwo', 'removeTrailingSlash', 'serve']);
expect(koaMiddlewaresMock).toHaveBeenCalledWith(options, { server: expect.anything() });
});

it('should call serve for each path defined in options', () => {
const pathsToServe = ['/assets', '/static', '/kappa'];
options.serve = pathsToServe;

const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toEqual(5);
expect(result.server.middleware.map(f => f.name))
.toEqual(['basepath', 'removeTrailingSlash', 'serve', 'serve', 'serve']);
expect(serveMiddlewareMock).toHaveBeenCalledTimes(3);
expect(serveMiddlewareMock).toHaveBeenCalledWith(pathsToServe[0], expect.anything());
expect(serveMiddlewareMock).toHaveBeenCalledWith(pathsToServe[1], expect.anything());
expect(serveMiddlewareMock).toHaveBeenCalledWith(pathsToServe[2], expect.anything());
});

it('should include normalizePath to Koa instance when proper option is set to true', () => {
options.koa.normalize.enabled = true;

const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toBe(4);
expect(result.server.middleware.map(f => f.name)).toContain('normalizePath');
expect(normalizePathMiddlewareMock).toHaveBeenCalledWith({ defer: options.koa.normalize.defer });
});

it('should include normalizePath to Koa instance when proper option is set to true', () => {
options.koa.lowercase.enabled = true;

const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toBe(4);
expect(result.server.middleware.map(f => f.name)).toContain('lowercasePath');
expect(lowercasePathMiddlewareMock).toHaveBeenCalledWith({ defer: options.koa.lowercase.defer });
});

it('should include koa-trailing-slashes instead of koa-remove-trailing-slash when proper option is set', () => {
options.koa.trailingSlashes.enabled = true;

const result = createServer(options, beforeUserMiddlewares, params);

expect(result.server.middleware.length).toBe(3);
expect(result.server.middleware.map(f => f.name)).toContain('addTrailingSlash');
expect(addTrailingSlashMiddlewareMock).toHaveBeenCalledWith({ defer: options.koa.trailingSlashes.defer });
});

it('should return servers after calling start function', () => {
const result = createServer(options, beforeUserMiddlewares, params).start();

expect(result).toEqual({ http: expect.anything(), https: expect.anything() });
expect(readFileSyncMock).toHaveBeenCalledTimes(2);
expect(readFileSyncMock).toHaveBeenCalledWith(options.https.key);
expect(readFileSyncMock).toHaveBeenCalledWith(options.https.cert);
expect(createHttpServerMock).toHaveBeenCalled();
expect(createHttpsServerMock).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import koaErrors from 'koa-errors';
import helmet from 'koa-helmet';
import koaError from 'koa-error';
import koaHelmet from 'koa-helmet';
import koaEtag from 'koa-etag';
import koaCompressor from 'koa-compressor';
import koaCompress from 'koa-compress';
import koaFavicon from 'koa-favicon';
import koaAccesslog from 'koa-accesslog';
import koaLogger from 'koa-logger';

import accesslog from './middlewares/accesslog';

/**
* Returns the middlewares to be used.
*
Expand All @@ -16,17 +17,17 @@ export default function middlewares(config, { dev, dist }) {
const middlewaresList = [];

if (dev) {
middlewaresList.push(koaErrors());
middlewaresList.push(koaError());
}

// Security headers
middlewaresList.push(helmet());
middlewaresList.push(koaHelmet());

middlewaresList.push(koaEtag());

// We only enable gzip in dist
if (dist) {
middlewaresList.push(koaCompressor());
middlewaresList.push(koaCompress());
}

const favicon = config.favicon;
Expand All @@ -35,7 +36,7 @@ export default function middlewares(config, { dev, dist }) {
}

if (dist) {
middlewaresList.push(koaAccesslog());
middlewaresList.push(accesslog());
} else {
middlewaresList.push(koaLogger());
}
Expand Down
Loading