miter
Version:
A typescript web framework based on ExpressJs based loosely on SailsJs
502 lines • 31.1 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const sinon = require("sinon");
const sinonChai = require("sinon-chai");
chai_1.use(sinonChai);
const chaiAsPromised = require("chai-as-promised");
chai_1.use(chaiAsPromised);
const reflector_1 = require("../reflector");
const injector_1 = require("../../core/injector");
const router_1 = require("../../metadata/server/router");
const logger_core_1 = require("../../services/logger-core");
const error_handler_1 = require("../../services/error-handler");
const router_service_1 = require("../../services/router.service");
const fake_router_service_1 = require("../../services/test/fake-router.service");
const transaction_service_1 = require("../../services/transaction.service");
const fake_transaction_service_1 = require("../../services/test/fake-transaction.service");
const test_policies_1 = require("./test-policies");
const test_controllers_1 = require("./test-controllers");
const fake_request_1 = require("./fake-request");
const fake_response_1 = require("./fake-response");
describe('RouterReflector', () => {
let injector;
let routerReflector;
let errorHandler;
beforeEach(() => {
let loggerCore = new logger_core_1.LoggerCore('abc', 'error', false);
injector = new injector_1.Injector(loggerCore);
let routerMeta = new router_1.RouterMetadata({
controllers: [
test_controllers_1.EmptyController,
test_controllers_1.EmptyControllerRoot
]
});
injector.provide({ provide: router_1.RouterMetadata, useValue: routerMeta });
injector.provide({ provide: router_service_1.RouterService, useClass: fake_router_service_1.FakeRouterService });
injector.provide({ provide: transaction_service_1.TransactionService, useClass: fake_transaction_service_1.FakeTransactionService });
routerReflector = injector.resolveInjectable(reflector_1.RouterReflector);
errorHandler = injector.resolveInjectable(error_handler_1.ErrorHandler);
});
describe('.reflectRoutes', () => {
it('should default to an empty array if parentControllers has a falsey value', () => {
let stub = sinon.stub(routerReflector, 'reflectControllerRoutes');
routerReflector.reflectRoutes([test_controllers_1.EmptyController]);
chai_1.expect(routerReflector.reflectControllerRoutes).to.have.been.calledWith([], test_controllers_1.EmptyController);
});
it('should invoke reflectControllerRoutes once for each controller', () => {
let stub = sinon.stub(routerReflector, 'reflectControllerRoutes');
routerReflector.reflectRoutes([test_controllers_1.EmptyController, test_controllers_1.EmptyControllerRoot]);
chai_1.expect(routerReflector.reflectControllerRoutes).to.have.been.calledTwice;
});
});
describe('.reflectControllerRoutes', () => {
it('should throw an error if the same controller is reflected twice', () => {
routerReflector.reflectControllerRoutes([], test_controllers_1.EmptyController);
chai_1.expect(() => routerReflector.reflectControllerRoutes([], test_controllers_1.EmptyController)).to.throw(/twice/);
});
it('should dependency inject the controller', () => {
let stub = sinon.stub(injector, 'resolveInjectable');
routerReflector.reflectControllerRoutes([], test_controllers_1.EmptyController);
chai_1.expect(injector.resolveInjectable).to.have.been.calledWith(test_controllers_1.EmptyController);
});
it('should throw an error if a class without the Controller decorator is passed in', () => {
chai_1.expect(() => routerReflector.reflectControllerRoutes([], test_controllers_1.ControllerSansDecorator)).to.throw(/@Controller/);
});
it('should throw an error if any of the parent controllers do not have the Controller decorator', () => {
chai_1.expect(() => routerReflector.reflectControllerRoutes([test_controllers_1.ControllerSansDecorator], test_controllers_1.EmptyController)).to.throw(/failed to reflect parent/i);
});
it('should invoke reflectRouteMeta', () => {
let stub = sinon.stub(routerReflector, 'reflectRouteMeta').callThrough();
routerReflector.reflectControllerRoutes([], test_controllers_1.EmptyController);
chai_1.expect(routerReflector.reflectRouteMeta).to.have.been.calledWith(test_controllers_1.EmptyController.prototype);
});
it('should invoke addRoute once for each route', () => {
let inst = injector.resolveInjectable(test_controllers_1.SimpleController);
let stub = sinon.stub(routerReflector, 'addRoute');
routerReflector.reflectControllerRoutes([], test_controllers_1.SimpleController);
let subject = chai_1.expect(routerReflector.addRoute).to.have.been;
subject.calledThrice;
subject.calledWith([], inst, 'a', {}, { path: 'a', method: 'get' });
subject.calledWith([], inst, 'b', {}, { path: 'b', method: 'get' });
subject.calledWith([], inst, 'c', {}, { path: 'c', method: 'get' });
});
it(`should recursively invoke reflectRoutes for the controller's children`, () => {
let stub = sinon.spy(routerReflector, 'reflectRoutes');
routerReflector.reflectControllerRoutes([], test_controllers_1.SimpleControllerRoot);
let subject = chai_1.expect(routerReflector.reflectRoutes).to.have.been;
subject.calledTwice;
subject.calledWith([test_controllers_1.SimpleController], [test_controllers_1.SimpleControllerRoot]);
subject.calledWith([], [test_controllers_1.SimpleControllerRoot, test_controllers_1.SimpleController]);
});
});
describe('.reflectRouteMeta', () => {
let fn;
beforeEach(() => {
fn = routerReflector.reflectRouteMeta.bind(routerReflector);
});
it('should include all routes in a controller', () => {
let results = fn(test_controllers_1.SimpleController.prototype);
chai_1.expect(results).to.deep.eq([
['a', [{ path: 'a', method: 'get' }]],
['b', [{ path: 'b', method: 'get' }]],
['c', [{ path: 'c', method: 'get' }]]
]);
});
it('should include multiple routes if multiple route decorators are on a single method', () => {
let results = fn(test_controllers_1.MultiRouteController.prototype);
chai_1.expect(results).to.deep.eq([
['multi', [
{ path: 'a', method: 'get' },
{ path: 'b', method: 'get' },
{ path: 'x', method: 'post' }
]]
]);
});
it(`should not include methods that don't have a route decorator`, () => {
let results = fn(test_controllers_1.PhishingController.prototype);
chai_1.expect(results).to.deep.eq([]);
});
it('should include routes from ancestor controllers', () => {
let results = fn(test_controllers_1.SimpleChildController.prototype);
chai_1.expect(results).to.deep.eq([
['a', [{ path: 'a', method: 'get' }]],
['b', [{ path: 'b', method: 'get' }]],
['c', [{ path: 'c', method: 'get' }]],
['x', [{ path: 'x', method: 'get' }]],
['y', [{ path: 'y', method: 'get' }]],
['z', [{ path: 'z', method: 'get' }]]
]);
});
});
describe('.addRoute', () => {
let fn;
beforeEach(() => {
fn = routerReflector.addRoute.bind(routerReflector);
});
it('should throw an error if the route metadata has no method defined', () => {
let inst = injector.resolveInjectable(test_controllers_1.SimpleController);
let test = () => fn([], inst, 'a', {}, { path: 'x' });
chai_1.expect(test).to.throw(/no method set/i);
});
it('should invoke transformRoutePathPart with the route path if it exists on the controller instance', () => {
let inst = injector.resolveInjectable(test_controllers_1.ComplexController);
sinon.spy(inst, 'transformRoutePathPart');
routerReflector.reflectControllerRoutes([], test_controllers_1.ComplexController);
chai_1.expect(inst.transformRoutePathPart).to.have.been.calledWith('healthCheck', 'x');
chai_1.expect(inst.transformRoutePathPart).to.have.returned('healthCheckxxx');
});
it('should invoke transformRoutePath with the full route if it exists on the controller instance', () => {
let inst = injector.resolveInjectable(test_controllers_1.ComplexController);
sinon.spy(inst, 'transformRoutePath');
routerReflector.reflectControllerRoutes([], test_controllers_1.ComplexController);
chai_1.expect(inst.transformRoutePath).to.have.been.calledWith('healthCheck', '/api/healthCheckxxx');
chai_1.expect(inst.transformRoutePath).to.have.returned('/API/HEALTHCHECKXXX');
});
it('should invoke transformRoutePolicies with the full list of route policies if it exists on the controller instance', () => {
let inst = injector.resolveInjectable(test_controllers_1.ComplexController);
sinon.spy(inst, 'transformRoutePolicies');
routerReflector.reflectControllerRoutes([], test_controllers_1.ComplexController);
chai_1.expect(inst.transformRoutePolicies).to.have.been.calledWith('healthCheck', '/API/HEALTHCHECKXXX', [test_policies_1.Policy1, test_policies_1.Policy2]);
chai_1.expect(inst.transformRoutePolicies).to.have.returned([test_policies_1.Policy3, test_policies_1.Policy1, test_policies_1.Policy2]);
});
it('should invoke transformRoute if it exists on the controller instance', () => {
let inst = injector.resolveInjectable(test_controllers_1.SkipRouteController);
sinon.spy(inst, 'transformRoute');
routerReflector.reflectControllerRoutes([], test_controllers_1.SkipRouteController);
chai_1.expect(inst.transformRoute).to.have.been.calledWith({
routeFnName: 'healthCheck',
fullPath: '/health-check',
policyDescriptors: []
});
});
it('should not add a route if transformRoute returns false', () => {
let inst = injector.resolveInjectable(test_controllers_1.SkipRouteController);
let router = injector.resolveInjectable(router_service_1.RouterService);
sinon.stub(router.expressRouter, 'get');
routerReflector.reflectControllerRoutes([], test_controllers_1.SkipRouteController);
chai_1.expect(router.expressRouter.get).not.to.have.been.called;
});
it('should add a route if transformRoute returns true', () => {
let inst = injector.resolveInjectable(test_controllers_1.KeepRouteController);
let router = injector.resolveInjectable(router_service_1.RouterService);
sinon.stub(router.expressRouter, 'get');
routerReflector.reflectControllerRoutes([], test_controllers_1.KeepRouteController);
chai_1.expect(router.expressRouter.get).to.have.been.calledOnce;
});
it('should add a route if transformRoute returns a falsey value that is not false', () => {
let inst = injector.resolveInjectable(test_controllers_1.AmbivalentController);
let router = injector.resolveInjectable(router_service_1.RouterService);
sinon.stub(router.expressRouter, 'get');
routerReflector.reflectControllerRoutes([], test_controllers_1.AmbivalentController);
chai_1.expect(router.expressRouter.get).to.have.been.calledOnce;
});
it('should invoke resolvePolicies', () => {
sinon.stub(routerReflector, 'resolvePolicies');
routerReflector.reflectControllerRoutes([], test_controllers_1.ComplexController);
chai_1.expect(routerReflector.resolvePolicies).to.have.been.calledWith([test_policies_1.Policy3, test_policies_1.Policy1, test_policies_1.Policy2]);
});
it('should throw an error if the route handler is not defined on the controller', () => {
let inst = injector.resolveInjectable(test_controllers_1.EmptyController);
let test = () => fn([], inst, 'doSomething', {}, { method: 'get', path: 'x' });
chai_1.expect(test).to.throw(/no route handler/i);
});
it('should invoke the routing function on the express router with the full path and function', () => {
let inst = injector.resolveInjectable(test_controllers_1.SimpleController);
let router = injector.resolveInjectable(router_service_1.RouterService);
sinon.stub(router.expressRouter, 'get');
fn([], inst, 'a', {}, { method: 'get', path: 'x' });
chai_1.expect(router.expressRouter.get).to.have.been.calledWith('/x', sinon.match.func);
});
});
describe('.getControllerName', () => {
let fn;
beforeEach(() => {
fn = routerReflector.getControllerName.bind(routerReflector);
});
it('should throw an error if passed a falsey value', () => {
chai_1.expect(() => fn(null)).to.throw(/falsey controller/);
});
it('should extract the controller name from the name of the constructor', () => {
let empty = new test_controllers_1.EmptyController();
chai_1.expect(fn(empty)).to.eql('EmptyController');
});
});
describe('.getParentPolicyDescriptors', () => {
let fn;
beforeEach(() => {
fn = routerReflector.getParentPolicyDescriptors.bind(routerReflector);
});
it('should return an empty array if none of the anscestor controllers have policies', () => {
let result = fn([
{ policies: [] },
{},
{ policies: [] }
]);
chai_1.expect(result).to.deep.eq([]);
});
it('should return an array of all policies in the anscestor controllers', () => {
let result = fn([
{ policies: ['one', 'two'] },
{ policies: ['three'] },
{ policies: ['four', 'five'] }
]);
chai_1.expect(result).to.deep.eq(['one', 'two', 'three', 'four', 'five']);
});
});
describe('.resolvePolicies', () => {
let fn;
beforeEach(() => {
fn = routerReflector.resolvePolicies.bind(routerReflector);
});
it('should return an empty array if there are no policies', () => {
chai_1.expect(fn([])).to.be.deep.eq([]);
});
it('should dependency inject policies if policy constructors are passed in', () => {
let stub = sinon.spy(injector, 'resolveInjectable');
fn([test_policies_1.Policy1, test_policies_1.Policy2]);
let subject = chai_1.expect(injector.resolveInjectable).to.have.been;
subject.calledTwice;
subject.calledWith(test_policies_1.Policy1);
subject.calledWith(test_policies_1.Policy2);
});
it('should support callback-based function policies', () => __awaiter(this, void 0, void 0, function* () {
let policyFn = (req, res, next) => {
next(null, 'fish!');
};
let result = fn([policyFn]);
chai_1.expect(result[0][0]).to.be.undefined;
chai_1.expect(typeof result[0][1]).to.eql('function');
let resultPromise = result[0][1](fake_request_1.FakeRequest(), fake_response_1.FakeResponse());
chai_1.expect(resultPromise).to.be.an.instanceof(Promise);
chai_1.expect(yield resultPromise).to.eql('fish!');
}));
it('should return an array of policy constructor, policy instance tuples', () => __awaiter(this, void 0, void 0, function* () {
let results = fn([test_policies_1.Policy1, test_policies_1.Policy2, test_policies_1.Policy3]);
chai_1.expect(Array.isArray(results)).to.be.true;
chai_1.expect(results.length).to.eql(3);
chai_1.expect(results[0][0]).to.eql(test_policies_1.Policy1);
chai_1.expect(yield results[0][1](fake_request_1.FakeRequest(), fake_response_1.FakeResponse())).to.eql("one");
chai_1.expect(results[1][0]).to.eql(test_policies_1.Policy2);
chai_1.expect(yield results[1][1](fake_request_1.FakeRequest(), fake_response_1.FakeResponse())).to.eql("two");
chai_1.expect(results[2][0]).to.eql(test_policies_1.Policy3);
chai_1.expect(yield results[2][1](fake_request_1.FakeRequest(), fake_response_1.FakeResponse())).to.eql("three");
}));
});
describe('.createFullRouterFn', () => {
let fn;
let controller = {
route: (req, res) => __awaiter(this, void 0, void 0, function* () {
return yield controller.routeImpl(req, res);
}),
routeImpl: (req, res) => __awaiter(this, void 0, void 0, function* () {
res.status(200);
})
};
let stubs = {};
let boundRoute;
beforeEach(() => {
fn = routerReflector.createFullRouterFn.bind(routerReflector);
stubs.route = sinon.spy(controller, 'route');
boundRoute = controller.route.bind(controller);
controller.routeImpl = (req, res) => __awaiter(this, void 0, void 0, function* () {
res.status(200);
});
});
afterEach(() => {
stubs.route.restore();
});
it('should return a function', () => {
let result = fn([], boundRoute, 'tname', { path: 'fish' });
chai_1.expect(typeof result).to.eql('function');
});
describe('that function', () => {
it('should return a promise', () => {
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
let result = resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse());
chai_1.expect(result).to.be.an.instanceOf(Promise);
});
it('should run the route policies and handler with a new transaction', () => __awaiter(this, void 0, void 0, function* () {
let policyInst = injector.resolveInjectable(test_policies_1.Policy1);
sinon.spy(policyInst, 'handle');
let resultFn = fn([[test_policies_1.Policy1, policyInst.handle.bind(policyInst)]], boundRoute, 'tname', { path: 'fish' });
let result = yield resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse());
chai_1.expect(policyInst.handle).to.have.been.calledOnce;
}));
it('should call the handle function on each policy', () => __awaiter(this, void 0, void 0, function* () {
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
let result = yield resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse());
chai_1.expect(controller.route).to.have.been.calledOnce;
}));
it('should stop processing policies if one sets the status code', () => __awaiter(this, void 0, void 0, function* () {
let policyInst = injector.resolveInjectable(test_policies_1.EarlyReturnPolicy);
sinon.spy(policyInst, 'handle');
let policy1Inst = injector.resolveInjectable(test_policies_1.Policy1);
sinon.spy(policy1Inst, 'handle');
let resultFn = fn([
[test_policies_1.EarlyReturnPolicy, policyInst.handle.bind(policyInst)],
[test_policies_1.Policy1, policy1Inst.handle.bind(policy1Inst)]
], boundRoute, 'tname', { path: 'fish' });
let result = yield resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse());
chai_1.expect(policyInst.handle).to.have.been.calledOnce;
chai_1.expect(policy1Inst.handle).not.to.have.been.called;
chai_1.expect(controller.route).not.to.have.been.called;
}));
it(`should not catch errors thrown in route policies if the error handler fails`, () => __awaiter(this, void 0, void 0, function* () {
let policyInst = injector.resolveInjectable(test_policies_1.ThrowPolicy);
sinon.spy(policyInst, 'handle');
let resultFn = fn([[test_policies_1.ThrowPolicy, policyInst.handle.bind(policyInst)]], boundRoute, 'tname', { path: 'fish' });
yield chai_1.expect(resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse())).to.eventually.be.rejected;
chai_1.expect(policyInst.handle).to.have.been.calledOnce;
chai_1.expect(controller.route).not.to.have.been.called;
}));
it(`should catch errors thrown in route policies`, () => __awaiter(this, void 0, void 0, function* () {
let policyInst = injector.resolveInjectable(test_policies_1.ThrowPolicy);
sinon.spy(policyInst, 'handle');
sinon.stub(errorHandler, 'handleRouteError').returns(Promise.resolve(true));
let resultFn = fn([[test_policies_1.ThrowPolicy, policyInst.handle.bind(policyInst)]], boundRoute, 'tname', { path: 'fish' });
yield chai_1.expect(resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse())).not.to.eventually.be.rejected;
chai_1.expect(policyInst.handle).to.have.been.calledOnce;
chai_1.expect(controller.route).not.to.have.been.called;
}));
it(`should send an 'internal server error' status when a policy throws an error`, () => __awaiter(this, void 0, void 0, function* () {
let policyInst = injector.resolveInjectable(test_policies_1.ThrowPolicy);
let resultFn = fn([[test_policies_1.ThrowPolicy, policyInst.handle.bind(policyInst)]], boundRoute, 'tname', { path: 'fish' });
let res = fake_response_1.FakeResponse();
sinon.spy(res, 'status');
sinon.stub(errorHandler, 'handleRouteError').returns(Promise.resolve(true));
let result = yield resultFn(fake_request_1.FakeRequest(), res);
chai_1.expect(res.status).to.have.been.calledWith(500);
}));
it(`should send an 'internal server error' status when a policy throws an error even if the error handler fails`, () => __awaiter(this, void 0, void 0, function* () {
let policyInst = injector.resolveInjectable(test_policies_1.ThrowPolicy);
let resultFn = fn([[test_policies_1.ThrowPolicy, policyInst.handle.bind(policyInst)]], boundRoute, 'tname', { path: 'fish' });
let res = fake_response_1.FakeResponse();
sinon.spy(res, 'status');
let errored = false;
try {
yield resultFn(fake_request_1.FakeRequest(), res);
}
catch (e) {
errored = true;
}
chai_1.expect(errored).to.be.true;
chai_1.expect(res.status).to.have.been.calledWith(500);
}));
it(`should send a '404 not found' status if the handler does not send a response`, () => __awaiter(this, void 0, void 0, function* () {
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
let res = fake_response_1.FakeResponse();
sinon.spy(res, 'status');
controller.routeImpl = (req, res) => __awaiter(this, void 0, void 0, function* () { });
let result = yield resultFn(fake_request_1.FakeRequest(), res);
chai_1.expect(res.status).to.have.been.calledWith(404);
}));
it('should catch errors thrown in the route handler', () => __awaiter(this, void 0, void 0, function* () {
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
controller.routeImpl = (req, res) => __awaiter(this, void 0, void 0, function* () {
throw new Error(`Going up!`);
});
sinon.stub(errorHandler, 'handleRouteError').returns(Promise.resolve(true));
yield chai_1.expect(resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse())).not.to.eventually.be.rejected;
}));
it('should not catch errors thrown in the route handler if the error handler fails', () => __awaiter(this, void 0, void 0, function* () {
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
controller.routeImpl = (req, res) => __awaiter(this, void 0, void 0, function* () {
throw new Error(`Going up!`);
});
yield chai_1.expect(resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse())).to.eventually.be.rejected;
}));
it(`should send an 'internal server error' status when the handler throws an error`, () => __awaiter(this, void 0, void 0, function* () {
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
let res = fake_response_1.FakeResponse();
sinon.spy(res, 'status');
controller.routeImpl = (req, res) => __awaiter(this, void 0, void 0, function* () {
throw new Error(`Going up!`);
});
sinon.stub(errorHandler, 'handleRouteError').returns(Promise.resolve(true));
let result = yield resultFn(fake_request_1.FakeRequest(), res);
chai_1.expect(res.status).to.have.been.calledWith(500);
}));
it(`should send an 'internal server error' status when the handler throws an error even if the error handler fails`, () => __awaiter(this, void 0, void 0, function* () {
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
let res = fake_response_1.FakeResponse();
sinon.spy(res, 'status');
controller.routeImpl = (req, res) => __awaiter(this, void 0, void 0, function* () {
throw new Error(`Going up!`);
});
let errored = false;
try {
yield resultFn(fake_request_1.FakeRequest(), res);
}
catch (e) {
errored = true;
}
chai_1.expect(errored).to.be.true;
chai_1.expect(res.status).to.have.been.calledWith(500);
}));
it('should run all of the route interceptors before handling the route', () => __awaiter(this, void 0, void 0, function* () {
let handleOrder = [];
routerReflector.registerRouteInterceptor((req, res, next) => (handleOrder.push(0), next()));
routerReflector.registerRouteInterceptor((req, res, next) => (handleOrder.push(1), next()));
routerReflector.registerRouteInterceptor((req, res, next) => (handleOrder.push(2), next()));
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
let result = yield resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse());
chai_1.expect(handleOrder).to.eql([0, 1, 2]);
}));
it('should stop running route interceptors if one sends a response', () => __awaiter(this, void 0, void 0, function* () {
let handleOrder = [];
routerReflector.registerRouteInterceptor((req, res, next) => (handleOrder.push(0), next()));
routerReflector.registerRouteInterceptor((req, res, next) => (handleOrder.push(1), res.status(404).send('Blah'), next()));
routerReflector.registerRouteInterceptor((req, res, next) => (handleOrder.push(2), next()));
let resultFn = fn([], boundRoute, 'tname', { path: 'fish' });
let result = yield resultFn(fake_request_1.FakeRequest(), fake_response_1.FakeResponse());
chai_1.expect(handleOrder).to.eql([0, 1]);
}));
});
});
describe('.createPolicyResultsFn', () => {
let fn;
beforeEach(() => {
fn = routerReflector.createPolicyResultsFn.bind(routerReflector);
});
it('should return a function', () => {
chai_1.expect(typeof fn([], [])).to.eql('function');
});
describe('that function', () => {
let resultFn;
beforeEach(() => {
resultFn = fn([
[test_policies_1.Policy1, null],
[test_policies_1.Policy2, null],
[test_policies_1.Policy3, null]
], ["one", "two", "three"]);
});
it('should allow you to index the policies by number', () => {
chai_1.expect(resultFn(0)).to.eql('one');
chai_1.expect(resultFn(1)).to.eql('two');
chai_1.expect(resultFn(2)).to.eql('three');
});
it('should return undefined if an index is out of range', () => {
chai_1.expect(resultFn(-1)).to.be.undefined;
chai_1.expect(resultFn(3)).to.be.undefined;
});
it('should return the policy result if the policy constructor is passed in', () => {
chai_1.expect(resultFn(test_policies_1.Policy1)).to.eql("one");
chai_1.expect(resultFn(test_policies_1.Policy2)).to.eql("two");
chai_1.expect(resultFn(test_policies_1.Policy3)).to.eql("three");
});
it('should return undefined if an unused policy is passed in', () => {
chai_1.expect(resultFn(test_policies_1.UnusedPolicy)).to.be.undefined;
});
});
});
});
//# sourceMappingURL=reflector.spec.js.map