Browse Source

Covered serve module

master
Nicola Peduzzi 8 years ago
parent
commit
be51640b67
  1. 10
      lib/serve.js
  2. 1
      tests/compile.test.js
  3. 20
      tests/express.mock.js
  4. 1
      tests/run.test.js
  5. 272
      tests/serve.test.js
  6. 1
      tests/validate.test.js
  7. 1
      tests/webpack.mock.js

10
lib/serve.js

@ -14,7 +14,7 @@ module.exports = {
const app = this._newExpressApp(funcConfs); const app = this._newExpressApp(funcConfs);
const port = this._getPort(); const port = this._getPort();
app.listen(port, () => { app.listen(port, () =>
compiler.watch({}, (err, stats) => { compiler.watch({}, (err, stats) => {
if (err) { if (err) {
throw err; throw err;
@ -28,8 +28,8 @@ module.exports = {
); );
loadedModules.push(funcConf.moduleName); loadedModules.push(funcConf.moduleName);
} }
}); })
}); );
return BbPromise.resolve(); return BbPromise.resolve();
}, },
@ -39,11 +39,11 @@ module.exports = {
app.use(bodyParser.json({ limit: '5mb' })); app.use(bodyParser.json({ limit: '5mb' }));
app.use((req, res, next) => { app.use(function optionsHandler(req, res, next) {
if(req.method !== 'OPTIONS') { if(req.method !== 'OPTIONS') {
next(); next();
} else { } else {
res.status(200).end(); res.sendStatus(200);
} }
}); });

1
tests/compile.test.js

@ -19,6 +19,7 @@ describe('compile', () => {
webpackMock = makeWebpackMock(); webpackMock = makeWebpackMock();
mockery.registerMock('webpack', webpackMock); mockery.registerMock('webpack', webpackMock);
baseModule = require('../lib/compile'); baseModule = require('../lib/compile');
Object.freeze(baseModule);
}); });
after(() => { after(() => {

20
tests/express.mock.js

@ -0,0 +1,20 @@
const sinon = require('sinon');
const appMock = {
listen: sinon.spy(),
use: sinon.spy(),
get: sinon.spy(),
post: sinon.spy(),
};
const expressMock = sinon.stub().returns(appMock);
expressMock.appMock = appMock;
expressMock._resetSpies = () => {
expressMock.reset();
appMock.listen.reset();
appMock.use.reset();
appMock.get.reset();
appMock.post.reset();
};
module.exports = () => expressMock;

1
tests/run.test.js

@ -23,6 +23,7 @@ describe('run', () => {
mockery.registerMock('webpack', webpackMock); mockery.registerMock('webpack', webpackMock);
mockery.registerMock('./utils', utilsMock); mockery.registerMock('./utils', utilsMock);
baseModule = require('../lib/run'); baseModule = require('../lib/run');
Object.freeze(baseModule);
}); });
after(() => { after(() => {

272
tests/serve.test.js

@ -5,12 +5,13 @@ const sinon = require('sinon');
const mockery = require('mockery'); const mockery = require('mockery');
const Serverless = require('serverless'); const Serverless = require('serverless');
const makeWebpackMock = require('./webpack.mock'); const makeWebpackMock = require('./webpack.mock');
const makeUtilsMock = require('./utils.mock'); const makeExpressMock = require('./express.mock');
chai.use(require('sinon-chai')); chai.use(require('sinon-chai'));
const expect = chai.expect; const expect = chai.expect;
describe('serve', () => { describe('serve', () => {
let webpackMock; let webpackMock;
let expressMock;
let baseModule; let baseModule;
let module; let module;
let serverless; let serverless;
@ -18,8 +19,11 @@ describe('serve', () => {
before(() => { before(() => {
mockery.enable({ warnOnUnregistered: false }); mockery.enable({ warnOnUnregistered: false });
webpackMock = makeWebpackMock(); webpackMock = makeWebpackMock();
expressMock = makeExpressMock();
mockery.registerMock('webpack', webpackMock); mockery.registerMock('webpack', webpackMock);
mockery.registerMock('express', expressMock);
baseModule = require('../lib/serve'); baseModule = require('../lib/serve');
Object.freeze(baseModule);
}); });
after(() => { after(() => {
@ -29,8 +33,12 @@ describe('serve', () => {
beforeEach(() => { beforeEach(() => {
serverless = new Serverless(); serverless = new Serverless();
serverless.cli = { log: sinon.spy() }; serverless.cli = {
log: sinon.spy(),
consoleLog: sinon.spy(),
};
webpackMock._resetSpies(); webpackMock._resetSpies();
expressMock._resetSpies();
module = Object.assign({ module = Object.assign({
serverless, serverless,
options: {}, options: {},
@ -147,4 +155,264 @@ describe('serve', () => {
expect(port).to.equal(1234); expect(port).to.equal(1234);
}); });
}); });
describe('_getFuncConfig', () => {
const testFunctionsConfig = {
func1: {
handler: 'module1.func1handler',
events: [{
http: {
method: 'get',
path: 'func1path',
},
}],
},
func2: {
handler: 'module2.func2handler',
events: [{
http: {
method: 'POST',
path: 'func2path',
},
}, {
nonhttp: 'non-http',
}],
},
func3: {
handler: 'module2.func3handler',
events: [{
nonhttp: 'non-http',
}],
},
};
beforeEach(() => {
serverless.service.functions = testFunctionsConfig;
});
it('should return a list of normalized functions configurations', () => {
const res = module._getFuncConfigs();
expect(res).to.eql([
{
'events': [
{
'method': 'get',
'path': 'func1path',
}
],
'handler': 'module1.func1handler',
'handlerFunc': null,
'id': 'func1',
'moduleName': 'module1',
},
{
'events': [
{
'method': 'POST',
'path': 'func2path',
}
],
'handler': 'module2.func2handler',
'handlerFunc': null,
'id': 'func2',
'moduleName': 'module2',
},
]);
});
});
describe('_newExpressApp', () => {
it('should return an express app', () => {
const res = module._newExpressApp([]);
expect(res).to.equal(expressMock.appMock);
});
it('should add a body-parser to the app', () => {
const res = module._newExpressApp([]);
expect(res.use).to.have.been.calledWith(sinon.match(value => {
return typeof value === 'function' && value.name === 'jsonParser';
}));
});
describe('OPTIONS handler', () => {
let optionsHandler;
beforeEach(() => {
const res = module._newExpressApp([]);
const optionsHandlers = res.use.getCalls().filter(c =>
typeof c.args[0] === 'function' &&
c.args[0].name === 'optionsHandler'
);
optionsHandler = optionsHandlers.length ? optionsHandlers[0].args[0] : null;
});
it('should add an OPTIONS request handler', () => {
expect(optionsHandler).to.exist;
});
it('should continue for non OPTIONS requests', () => {
const req = { method: 'GET' };
const next = sinon.spy();
optionsHandler(req, {}, next);
expect(next).to.have.callCount(1);
});
it('should send status 200 for OPTIONS requests', () => {
const req = { method: 'OPTIONS' };
const res = { sendStatus: sinon.spy() };
const next = sinon.spy();
optionsHandler(req, res, next);
expect(res.sendStatus).to.have.been.calledWith(200);
expect(next).to.have.callCount(0);
});
});
it('should create express handlers for all functions http event', () => {
const testFuncsConfs = [
{
'events': [
{
'method': 'get',
'path': 'func1path',
'cors': true,
}
],
'handler': 'module1.func1handler',
'handlerFunc': null,
'id': 'func1',
'moduleName': 'module1',
},
{
'events': [
{
'method': 'POST',
'path': 'func2path/{testParam}',
}
],
'handler': 'module2.func2handler',
'handlerFunc': null,
'id': 'func2',
'moduleName': 'module2',
},
];
const testStage = 'test';
module.options.stage = testStage;
const testHandlerBase = 'testHandlerBase';
const testHandlerCors = 'testHandlerCors';
module._handlerBase = sinon.stub().returns(testHandlerBase);
module._handlerAddCors = sinon.stub().returns(testHandlerCors);
const app = module._newExpressApp(testFuncsConfs);
expect(app.get).to.have.callCount(1);
expect(app.get).to.have.been.calledWith(
'/test/func1path',
testHandlerCors
);
expect(module.serverless.cli.consoleLog).to.have.been.calledWith(
' GET - http://localhost:8000/test/func1path'
);
expect(app.post).to.have.callCount(1);
expect(app.post).to.have.been.calledWith(
'/test/func2path/:testParam',
testHandlerBase
);
expect(module.serverless.cli.consoleLog).to.have.been.calledWith(
' POST - http://localhost:8000/test/func2path/{testParam}'
);
});
});
describe('serve method', () => {
let serve;
let listenerCb;
beforeEach(() => {
serve = module.serve();
listenerCb = expressMock.appMock.listen.firstCall.args[1];
});
it('should start an express app listener', () => {
expect(expressMock.appMock.listen).to.have.callCount(1);
});
it('should start a webpack watcher', () => {
listenerCb.bind(module)();
expect(webpackMock.compilerMock.watch).to.have.callCount(1);
});
it('should throw if compiler fails', () => {
listenerCb.bind(module)();
const compileCb = webpackMock.compilerMock.watch.firstCall.args[1];
const testError = 'testError';
expect(compileCb.bind(module, testError)).to.throw(testError);
});
it('should reload all function handlers on compilation', () => {
const testFuncsConfs = [
{
'events': [
{
'method': 'get',
'path': 'func1path',
'cors': true,
}
],
'handler': 'module1.func1handler',
'handlerFunc': null,
'id': 'func1',
'moduleName': 'module1',
},
{
'events': [
{
'method': 'POST',
'path': 'func2path/{testParam}',
}
],
'handler': 'module2.func2handler',
'handlerFunc': null,
'id': 'func2',
'moduleName': 'module2',
},
{
'events': [
{
'method': 'GET',
'path': 'func3path',
}
],
'handler': 'module2.func2handler',
'handlerFunc': null,
'id': 'func3',
'moduleName': 'module2',
},
];
module._getFuncConfigs = sinon.stub().returns(testFuncsConfs);
module.loadHandler = sinon.spy();
expressMock._resetSpies();
webpackMock._resetSpies();
serve = module.serve();
listenerCb = expressMock.appMock.listen.firstCall.args[1];
listenerCb.bind(module)();
const compileCb = webpackMock.compilerMock.watch.firstCall.args[1];
const testStats = {};
module.loadHandler.reset();
compileCb.bind(module)(null, testStats);
expect(module.loadHandler).to.have.callCount(3);
expect(module.loadHandler).to.have.been.calledWith(
testStats,
'func1',
true
);
expect(module.loadHandler).to.have.been.calledWith(
testStats,
'func2',
true
);
expect(module.loadHandler).to.have.been.calledWith(
testStats,
'func3',
false
);
});
});
}); });

1
tests/validate.test.js

@ -20,6 +20,7 @@ describe('validate', () => {
fsExtraMock = makeFsExtraMock(); fsExtraMock = makeFsExtraMock();
mockery.registerMock('fs-extra', fsExtraMock); mockery.registerMock('fs-extra', fsExtraMock);
baseModule = require('../lib/validate'); baseModule = require('../lib/validate');
Object.freeze(baseModule);
}); });
after(() => { after(() => {

1
tests/webpack.mock.js

@ -27,6 +27,7 @@ webpackMock.compilerMock = compilerMock;
webpackMock._resetSpies = () => { webpackMock._resetSpies = () => {
webpackMock.reset(); webpackMock.reset();
compilerMock.run.reset(); compilerMock.run.reset();
compilerMock.watch.reset();
Object.assign(statsMock, statsMockBase()); Object.assign(statsMock, statsMockBase());
}; };

Loading…
Cancel
Save