LearningSalesForceCommerceC.../storefront-reference-architecture/test/unit/modules/server/server.js

354 lines
12 KiB
JavaScript
Raw Normal View History

2021-12-21 10:57:31 -08:00
/* eslint "no-underscore-dangle": ["error", { "allow": ["__routes"] }] */
'use strict';
var Route = require('../../../../cartridges/modules/server/route');
var assert = require('chai').assert;
var middleware = require('../../../../cartridges/modules/server/middleware');
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
var sinon = require('sinon');
var render = {
template: sinon.spy(),
json: sinon.spy(),
xml: sinon.spy(),
applyRenderings: sinon.spy()
};
var server = null;
function request() {
return {
httpMethod: 'GET',
host: 'localhost',
path: 'test',
querystring: '',
locale: {
id: ''
},
https: false,
currentCustomer: {
raw: {},
profile: {},
addressBook: {},
wallet: {}
}
};
}
describe('server', function () {
// this function initializes fields in the response object
// which is created in the server.use method
var initResponse = function (response) {
response.cachePeriod = 0; // eslint-disable-line no-param-reassign
response.cachePeriodUnit = null; // eslint-disable-line no-param-reassign
response.personalized = false; // eslint-disable-line no-param-reassign
response.base = { // eslint-disable-line no-param-reassign
setExpires: function () {},
setVaryBy: function () {},
writer: {
print: function (message) { assert.equal(message, 'test'); }
}
};
response.json = function () {}; // eslint-disable-line no-param-reassign
response.isJson = true; // eslint-disable-line no-param-reassign
response.setViewData = function () { // eslint-disable-line no-param-reassign
return '';
};
response.renderings = [{ type: 'render', subType: 'json' }]; // eslint-disable-line no-param-reassign
return response;
};
beforeEach(function () {
server = proxyquire('../../../../cartridges/modules/server/server', {
'./render': render,
'./request': request,
'./response': require('../../../mocks/modules/responseMock'),
'dw/system/HookMgr': {
hasHook: function (/* extension */) {
return true;
},
callHook: function (/* extensionPoint, functionName , args */) {
}
}
});
});
it('should create a server with one route', function () {
server.use('test', function () {});
var exports = server.exports();
assert.equal(typeof exports.test, 'function');
});
it('should apply default page cache period value', function () {
var mockResp = null;
server.use('test', function (req, res, next) {
mockResp = initResponse(res);
res.cachePeriod = 24; // eslint-disable-line no-param-reassign
res.cachePeriodUnit = 'hours'; // eslint-disable-line no-param-reassign
next();
});
var exports = server.exports();
var route = exports.__routes.test;
var routeStartHit = false;
var routeCompleteHit = false;
route.once('route:Start', function () {
routeStartHit = true;
});
route.on('route:Complete', function () {
routeCompleteHit = true;
assert.equal(typeof mockResp.cachePeriod, 'number');
assert.equal(24, mockResp.cachePeriod);
assert.equal('hours', mockResp.cachePeriodUnit);
assert.equal(false, mockResp.personalized);
});
exports.test();
assert.isTrue(routeStartHit);
assert.isTrue(routeCompleteHit);
});
it('should apply default page cache period value', function () {
var mockResp = null;
server.use('test', function (req, res, next) {
mockResp = initResponse(res);
res.cachePeriod = 30; // eslint-disable-line no-param-reassign
res.cachePeriodUnit = 'minutes'; // eslint-disable-line no-param-reassign
res.personalized = true; // eslint-disable-line no-param-reassign
res.renderings = [{ type: 'render', subType: 'xml' }]; // eslint-disable-line no-param-reassign
next();
});
var exports = server.exports();
var route = exports.__routes.test;
var routeStartHit = false;
var routeCompleteHit = false;
route.once('route:Start', function () {
routeStartHit = true;
});
route.on('route:Complete', function () {
routeCompleteHit = true;
assert.equal(typeof mockResp.cachePeriod, 'number');
assert.equal(30, mockResp.cachePeriod);
assert.equal('minutes', mockResp.cachePeriodUnit);
assert.equal(true, mockResp.personalized);
});
exports.test();
assert.isTrue(routeStartHit);
assert.isTrue(routeCompleteHit);
});
it('should print', function () {
server.use('test', function (req, res, next) {
initResponse(res);
res.cachePeriod = 30; // eslint-disable-line no-param-reassign
res.cachePeriodUnit = 'minutes'; // eslint-disable-line no-param-reassign
res.personalized = true; // eslint-disable-line no-param-reassign
res.renderings = [{ type: 'print', message: 'test' }]; // eslint-disable-line no-param-reassign
next();
});
var exports = server.exports();
exports.test();
});
it('should create a server with a route of two steps', function () {
server.get('test', function () {});
var exports = server.exports();
assert.equal(exports.__routes.test.chain.length, 2);
});
it('should create a server with two routes', function () {
server.get('test', function () {}, function () {});
server.post('test2', function () {});
var exports = server.exports();
assert.equal(typeof exports.test, 'function');
assert.equal(typeof exports.test2, 'function');
assert.equal(exports.__routes.test.chain.length, 3);
assert.equal(exports.__routes.test2.chain.length, 2);
});
it('should extend existing chain with 2 more steps', function () {
server.get('test', function () {});
var exports = server.exports();
assert.equal(exports.__routes.test.chain.length, 2);
server.extend(exports);
server.append('test', function () {}, function () {});
assert.equal(exports.__routes.test.chain.length, 4);
});
it('The extended chain with append should be executed last.', function () {
server.get('test', function () {});
var exports = server.exports();
server.extend(exports);
server.append('test', function () {}, function () { return 'EXECUTED'; });
assert.equal(server.getRoute('test').chain[3](), 'EXECUTED');
});
it('The extended chain with prepend should be executed first.', function () {
server.get('test', function () {});
var exports = server.exports();
server.extend(exports);
server.prepend('test', function () { return 'EXECUTED'; });
assert.equal(server.getRoute('test').chain[0](), 'EXECUTED');
});
it('should replace existing route with a new one', function () {
var spy = sinon.spy();
var spy2 = sinon.spy();
server.get('test', spy);
var exports = server.exports();
server.extend(exports);
server.replace('test', spy2);
var newExports = server.exports();
newExports.test();
assert.isTrue(spy.notCalled);
assert.isTrue(spy2.called);
});
it('should throw when replacing non-existing route', function () {
var testFn = function () {
server.replace('blah', function () {});
};
assert.throws(testFn, 'Route with this name does not exist');
});
it('should throw when trying to create two routes with the same name', function () {
server.get('test', function () {});
assert.throws(function () { server.post('test', function () {}); });
});
it('should throw when route name is not provided', function () {
assert.throws(function () { server.get(function () {}); });
});
it('should throw when route chain contains non-functions', function () {
assert.throws(function () { server.get('test', {}); });
});
it('should throw when trying to append to non-existing route', function () {
server.get('test', function () {});
server.extend(server.exports());
assert.throws(function () { server.append('foo', function () {}); });
});
it('should throw when extending server without routes', function () {
assert.throws(function () { server.extend(server.exports()); });
});
it('should throw when extending server with an object', function () {
assert.throws(function () { server.extend({}); });
});
it('should throw when middleware doesn\'t match route', function () {
server.post('test', middleware.https, function (req, res, next) {
req.render('test', { name: 'value' }); next();
});
assert.throws(function () { server.exports().test(); });
});
it('should verify that whole route passes', function () {
server.get('test', middleware.http, function (req, res, next) {
res.render('test', { name: 'value' });
next();
});
var exports = server.exports();
exports.test();
var result = render.applyRenderings.called;
assert.isTrue(result);
});
it('should verify that all events are emitted', function (done) {
server.get('test', middleware.http, function (req, res, next) {
res.json({ name: 'value' });
next();
});
var exports = server.exports();
var route = exports.__routes.test;
var routeStartHit = false;
var routeStepHits = 0;
route.once('route:Start', function () {
routeStartHit = true;
});
route.on('route:Step', function () {
routeStepHits += 1;
});
route.on('route:Complete', function () {
assert.isTrue(routeStartHit);
assert.equal(routeStepHits, 2);
done();
});
exports.test();
});
it('should maintain events for exported route', function () {
var spy = sinon.spy();
var spy2 = sinon.spy();
server.get('test', spy);
var exports = server.exports();
var route = exports.__routes.test;
route.on('route:Start', spy2);
var exported = server.exports();
assert.equal(exported.__routes.test.listeners('route:Start').length, 1);
});
it('should correctly remove event after export', function () {
var spy = sinon.spy();
var spy2 = sinon.spy();
server.get('test', spy);
var exports = server.exports();
var route = exports.__routes.test;
route.on('route:Start', spy2);
var exported = server.exports();
exported.__routes.test.off('route:Start');
exported.test();
assert.isTrue(spy.called);
assert.isTrue(spy2.notCalled);
});
it('should verify that request is frozen', function (done) {
server.get('test', function (req) {
assert.isFrozen(req);
done();
});
server.exports().test();
});
it('should retrieve a route by name', function () {
server.get('test', function (req, res, next) {
res.json({ name: 'value' });
next();
});
var testRoute = server.getRoute('test');
assert.isNotNull(testRoute);
});
it('should return a route on get call', function () {
var route = server.get('test', function () {});
assert.isTrue(route instanceof Route);
});
it('should redirect if requested in BeforeComplete', function (done) {
server.get('test', function (req, res, next) {
this.on('route:BeforeComplete', function (r, response) {
response.base.redirect = function (text) { // eslint-disable-line no-param-reassign
assert.equal(text, 'test');
done();
};
response.redirect('test');
});
next();
});
var exports = server.exports();
exports.test();
});
});