Skip to content

Commit 0fb9147

Browse files
feat: new type for validations in route (#2)
* feat: new type for validations in route * feat: added testing fixtures
1 parent 32be2b5 commit 0fb9147

File tree

7 files changed

+8701
-13527
lines changed

7 files changed

+8701
-13527
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ typings/
5959

6060
# next.js build output
6161
.next
62+
63+
# npm
64+
package-lock.json
65+

lib/fixtureGenerator.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
'use strict';
2+
3+
const serviceFake = (req, res) => res.json({ done: 'done' });
4+
5+
const { expect } = require('chai');
6+
const sinon = require('sinon');
7+
8+
const _ = require('lodash');
9+
10+
const hasUserPrototype = (obj) => obj.constructor !== Object;
11+
12+
const createFixture = async (serviceManager) => {
13+
const { middlewares, controllers } = serviceManager;
14+
15+
return {
16+
start: () => {},
17+
stop: () => {},
18+
middlewares: _.mapValues(middlewares, (service) =>
19+
_.mapValues(service, (method) => {
20+
if (method.callback) {
21+
const callbackMock = sinon.stub().returns(sinon.stub().callsArg(2));
22+
callbackMock.callback = true;
23+
return callbackMock;
24+
}
25+
26+
const methodStub = sinon.stub().callsArg(2);
27+
methodStub.validations = _.mapValues(method.validations, () => sinon.stub().callsArg(2));
28+
29+
return [...Object.values(methodStub.validations), methodStub];
30+
})
31+
),
32+
controllers: Object.keys(controllers).reduce((result, key) => {
33+
const target = controllers[key];
34+
35+
if (hasUserPrototype(target)) {
36+
result[key] = Object.getOwnPropertyNames(Object.getPrototypeOf(target))
37+
.filter((_key) => _key !== 'constructor')
38+
.reduce((_result, _key) => {
39+
_result[_key] = sinon.stub().callsFake(serviceFake);
40+
return _result;
41+
}, {});
42+
} else {
43+
result[key] = Object.keys(target).reduce((_result, _key) => {
44+
const validations = _.mapValues(controllers[key][_key].validations, () => sinon.stub().callsArg(2));
45+
const controllerStub = sinon.stub().callsFake(serviceFake);
46+
controllerStub.validations = validations;
47+
_result[_key] = [...Object.values(validations), controllerStub];
48+
return _result;
49+
}, {});
50+
}
51+
52+
return result;
53+
}, {}),
54+
clients: { io: { bindEvents: () => {} }, socketio: { attach: () => {} } },
55+
services: { socket: null },
56+
};
57+
};
58+
59+
const checkFixture = (fixture, expected) => {
60+
const { middlewares, controllers } = fixture;
61+
62+
const validations = { middlewares: {}, controllers: {} };
63+
64+
Object.keys(controllers).forEach((controller) => {
65+
if (!(controller in expected.controllers)) expected.controllers[controller] = {};
66+
Object.keys(controllers[controller]).forEach((method) => {
67+
const expressMiddlewares = controllers[controller][method];
68+
const controllerMethod = expressMiddlewares[expressMiddlewares.length - 1];
69+
70+
if (controllerMethod.validations) {
71+
if (!validations.controllers[controller]) validations.controllers[controller] = {};
72+
73+
validations.controllers[controller][method] = _.mapValues(controllerMethod.validations, (stub) => stub.callCount);
74+
}
75+
76+
controllers[controller][method] = controllerMethod.callCount;
77+
if (!(method in expected.controllers[controller])) expected.controllers[controller][method] = 0;
78+
});
79+
});
80+
81+
Object.keys(middlewares).forEach((service) => {
82+
if (!(service in expected.middlewares)) expected.middlewares[service] = {};
83+
Object.keys(middlewares[service]).forEach((method) => {
84+
const expressMiddlewares = middlewares[service][method];
85+
const middlewareMethod = expressMiddlewares[expressMiddlewares.length - 1];
86+
87+
if (middlewareMethod.validations) {
88+
if (!validations.middlewares[service]) validations.middlewares[service] = {};
89+
90+
validations.middlewares[service][method] = _.mapValues(middlewareMethod.validations, (stub) => stub.callCount);
91+
}
92+
93+
if (middlewareMethod.callback) {
94+
middlewares[service][method] = middlewareMethod().callCount;
95+
} else {
96+
middlewares[service][method] = middlewareMethod.callCount;
97+
}
98+
if (!(method in expected.middlewares[service])) expected.middlewares[service][method] = 0;
99+
});
100+
});
101+
102+
// seed the expected object with zeros
103+
// middlewares or controllers
104+
Object.keys(validations).forEach((group) => {
105+
if (!(group in expected.validations)) expected.validations[group] = {};
106+
// class in a middleware or controller
107+
Object.keys(validations[group]).forEach((service) => {
108+
if (!(service in expected.validations[group])) expected.validations[group][service] = {};
109+
// method in a class
110+
Object.keys(validations[group][service]).forEach((method) => {
111+
if (!(method in expected.validations[group][service])) expected.validations[group][service][method] = {};
112+
// validation in a method
113+
Object.keys(validations[group][service][method]).forEach((validation) => {
114+
if (!(validation in expected.validations[group][service][method])) expected.validations[group][service][method][validation] = 0;
115+
});
116+
});
117+
});
118+
});
119+
120+
expect(controllers).to.deep.eql(expected.controllers);
121+
expect(middlewares).to.deep.eql(expected.middlewares);
122+
expect(validations).to.deep.eql(expected.validations);
123+
};
124+
125+
module.exports = {
126+
createFixture,
127+
checkFixture,
128+
};

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
module.exports = {
55
ExceptionHandler: require('./exceptionHandler'),
66
ResponseBuilder: require('./responseBuilder'),
7+
FixtureGenerator: require('./fixtureGenerator'),
78
};

lib/responseBuilder.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ module.exports = function ResponseBuilder() {
115115
self.route = (dataPromise, successCodeOverride, failureCodeOverride) => {
116116
if (dataPromise.validations && !dataPromise.validationsApplied) {
117117
dataPromise.validationsApplied = true;
118-
return [...self.route(dataPromise.validations), self.route(self.validationResult), self.route(dataPromise)];
118+
const expressMiddlewares = [...self.route(Object.values(dataPromise.validations)), self.route(self.validationResult), self.route(dataPromise)];
119+
expressMiddlewares.validations = dataPromise.validations;
120+
return expressMiddlewares;
119121
}
120122

121123
if (dataPromise.callback) {

0 commit comments

Comments
 (0)