UNPKG

10.1 kBJavaScriptView Raw
1'use strict';
2
3const expect = require('chai').expect;
4const Application = require('../lib/Application');
5const Method = require('../lib/Method');
6const Controller = require('../lib/Controller');
7
8const DEFAULT_SETTINGS = { adapter: 'express', env: 'development', 'x-powered-by': true };
9
10describe('class Application', function() {
11 let app;
12
13 beforeEach(function() {
14 app = new Application('test', {});
15 });
16
17 describe('constructor(name, settings)', function() {
18 [
19 ['name', 'test'],
20 ['beforeHooks', {}],
21 ['afterHooks', {}],
22 ['afterErrorHooks', {}],
23 ['settings', DEFAULT_SETTINGS],
24 ['methods', []],
25 ['mountedApps', []],
26 ['locals', { settings: DEFAULT_SETTINGS }],
27 ['mountPath', '/']
28 ].forEach(function(prop) {
29 it(`should have property '${prop[0]}' and corresponding value`, function() {
30 expect(app).to.have.property(prop[0]).deep.eq(prop[1]);
31 });
32 });
33
34 it('should be a valid instance of Application class', function() {
35 expect(app).to.be.an.instanceof(Application);
36 });
37 });
38
39 describe('setName(name)', function() {
40 it('should change app name', function() {
41 expect(app).to.have.a.property('name', 'test');
42 app.setName('app');
43 expect(app).to.have.a.property('name', 'app');
44 });
45 });
46
47 describe('getName()', function() {
48 it('should return app name', function() {
49 expect(app.getName()).to.eq(app.name);
50 });
51 });
52
53 describe('setMountPath(path)', function() {
54 it('should change app mount path', function() {
55 expect(app).to.have.property('mountPath', '/');
56 app.setMountPath('/my-app');
57 expect(app).to.have.property('mountPath', '/my-app');
58 });
59 });
60
61 describe('getMountPath()', function() {
62 it('should return app mount path', function() {
63 expect(app.getMountPath()).to.eq(app.mountPath);
64 });
65 });
66
67 describe('define()', function() {
68 let methodName, methodFn, methodSettings, method;
69
70 beforeEach(function() {
71 methodName = 'test';
72 methodFn = function() {};
73 methodSettings = {
74 description: 'method description',
75 params: [{ name: 'gender', type: 'string' }],
76 route: { path: 'test', verb: 'post' }
77 };
78 method = new Method(methodName, methodSettings, methodFn);
79 });
80
81 it('should add app as method parent', function() {
82 app.define(method);
83 expect(app.methods[0]).to.have.property('parent', app);
84 });
85
86 it('should define a new method and added to app', function() {
87 expect(app).to.have.deep.property('methods.length', 0);
88 app.define(methodName, methodSettings, methodFn);
89 expect(app).to.have.deep.property('methods.length', 1);
90 });
91
92 it('should add a method instance', function() {
93 expect(app).to.have.deep.property('methods.length', 0);
94 app.define(method);
95 expect(app).to.have.deep.property('methods.length', 1);
96 });
97 });
98
99 describe('plugin(pluginOrPlugins, options)', function() {
100 it('should accept plugin name for internal plugins', function() {
101 expect(function() {
102 app.plugin('evaluator', {});
103 }).to.not.throw(Error);
104 });
105
106 it('should invoke one plugin function with options', function() {
107 let pluginInvoked = false;
108 let plugin = function() {
109 pluginInvoked = true;
110 };
111 app.plugin(plugin, {});
112 expect(pluginInvoked).to.be.true;
113 });
114
115 it('should invoke multiple plugins with options', function() {
116 let pluginInvoked = 0;
117 let plugin = function() {
118 pluginInvoked++;
119 };
120 app.plugin([plugin, plugin, plugin], {});
121 expect(pluginInvoked).to.equal(3);
122 });
123 });
124
125 describe('clone()', function() {
126 let cloned;
127
128 beforeEach(function() {
129 app.parent = app;
130
131 app.define('test', {
132 description: 'test description',
133 params: [{ name: 'name', type: 'string' }]
134 }, function(ctx, next) {
135 next();
136 });
137
138 app.define('test1', {
139 description: 'test1 description',
140 params: [{ name: 'name', type: 'string' }]
141 }, function(ctx, next) {
142 next();
143 });
144
145 app.use(app);
146
147 cloned = app.clone();
148 });
149
150 [
151 'parent',
152 'mountPath',
153 'settings',
154 'beforeHooks',
155 'afterHooks',
156 'afterErrorHooks',
157 'locals',
158 'mountedApps',
159 'methods'
160 ].forEach(function() {
161
162 });
163
164 [
165 'parent',
166 'mountPath',
167 'settings',
168 'beforeHooks',
169 'afterHooks',
170 'afterErrorHooks',
171 'locals'
172 ].forEach(function(prop) {
173 it(`should return a cloned app with same ${prop} value`, function() {
174 expect(cloned).to.have.property(prop).to.be.deep.eq(app[prop]);
175 });
176 });
177
178 [
179 'settings',
180 'beforeHooks',
181 'afterHooks',
182 'afterErrorHooks',
183 'locals'
184 ].forEach(function(prop) {
185 it(`should return a cloned app without the same ${prop} reference`, function() {
186 expect(cloned).to.have.property(prop).not.to.be.equal(app[prop]);
187 });
188 });
189
190 it('should have all sub apps mounted', function() {
191 expect(cloned.mountedApps).to.have.property('length').eq(app.mountedApps.length);
192 cloned.mountedApps.forEach(function(mountedApp, i) {
193 let originalMountedApp = app.mountedApps[i];
194 expect(mountedApp).not.eq(originalMountedApp);
195 expect(mountedApp).to.have.property('parent').eq(cloned);
196 expect(mountedApp).to.have.property('name').eq(originalMountedApp.name);
197 });
198 });
199
200 it('should have all methods added', function() {
201 expect(cloned.methods).to.have.property('length').eq(app.methods.length);
202 cloned.methods.forEach(function(method, i) {
203 let originalMethod = app.methods[i];
204 expect(method).not.eq(originalMethod);
205 expect(method).to.have.property('parent').eq(cloned);
206 expect(method).to.have.property('name').eq(originalMethod.name);
207 });
208 });
209 });
210
211 describe('use(fn, options)', function() {
212 it('should be able to use an express or socketio middleware', function() {
213 app.use(function() {});
214 expect(app.methods.length).to.eq(1);
215 });
216
217 it('should be able to use an app', function() {
218 let subApp = new Application('sub');
219 app.use(subApp);
220 expect(app.mountedApps).to.have.a.property('length').to.eq(1);
221 expect(app.mountedApps[0]).to.have.a.property('parent').to.eq(app);
222 });
223
224 it('should be able to use a controller', function() {
225 class UsersCtrl extends Controller {
226 constructor() {
227 super();
228
229 this.beforeAction('signInRequired', { expect: 'signIn' });
230 this.afterAction('insight');
231 this.afterErrorAction('recordError');
232 }
233
234 initConfig() {
235 return { list: {}, signIn: {} };
236 }
237
238 signInRequired() {}
239 insight() {}
240 recordError() {}
241
242 list() {}
243 signIn() {}
244 }
245
246 app.use(UsersCtrl);
247
248 expect(app.mountedApps).to.have.a.property('length').to.eq(1);
249
250 let subApp = app.mountedApps[0];
251
252 expect(subApp).to.have.a.property('parent').to.eq(app);
253 expect(subApp).to.have.a.property('name').to.eq('users');
254
255 let methodsLength = 2;
256 let beforeHooksLength = methodsLength + 1;
257 let afterHooksLength = 2;
258 let afterErrorHooksLength = 2;
259 expect(Object.keys(subApp.beforeHooks).length).to.eq(beforeHooksLength);
260 expect(Object.keys(subApp.afterHooks).length).to.eq(afterHooksLength);
261 expect(Object.keys(subApp.afterErrorHooks).length).to.eq(afterErrorHooksLength);
262 expect(subApp.methods.length).eq(methodsLength);
263 });
264
265 it('should be able to use a method', function() {
266 let method = new Method('test', {}, function() {});
267 app.use(method, {});
268 expect(app.methods.length).to.eq(1);
269 });
270 });
271
272 describe('set(setting, val)', function() {
273 it('should add a setting with corresponding value', function() {
274 app.set('abc', 1);
275 app.set('person.gender', 'male');
276 expect(app.settings).to.have.a.property('abc', 1);
277 expect(app.settings).to.have.a.deep.property('person.gender', 'male');
278 });
279 });
280
281 describe('get(setting)', function() {
282 it('should get a setting with corresponding value', function() {
283 app.set('abc', 1);
284 app.set('person.gender', 'male');
285 expect(app.get('abc')).to.eq(1);
286 expect(app.get('person.gender')).to.eq('male');
287 });
288 });
289
290 describe('enable(setting)', function() {
291 it('should enable a setting', function() {
292 app.enable('abc');
293 expect(app.get('abc')).to.eq(true);
294 });
295 });
296
297 describe('disable(setting)', function() {
298 it('should disable a setting', function() {
299 app.disable('abc');
300 expect(app.get('abc')).to.eq(false);
301 });
302 });
303
304 describe('enabled(setting)', function() {
305 it('should return whether a setting is enabled', function() {
306 app.enable('abc');
307 expect(app.enabled('abc')).to.eq(true);
308 app.disable('abc');
309 expect(app.enabled('abc')).to.eq(false);
310 });
311 });
312
313 describe('disabled(setting)', function() {
314 it('should return whether a setting is disabled', function() {
315 app.enable('abc');
316 expect(app.disabled('abc')).to.eq(false);
317 app.disable('abc');
318 expect(app.disabled('abc')).to.eq(true);
319 });
320 });
321
322 describe('fullName()', function() {
323 it('should return expected full name with or without parent object', function() {
324 expect(app.fullName()).to.be.eq('test');
325
326 app.parent = {
327 fullName: function() {
328 return 'users';
329 }
330 };
331
332 expect(app.fullName()).to.be.eq('users.test');
333 });
334 });
335
336 describe('fullPath()', function() {
337 it('should return expected full path with or without parent object', function() {
338 expect(app.fullPath()).to.be.eq('/');
339
340 app.setMountPath('/test');
341
342 app.parent = {
343 fullPath: function() {
344 return '/users';
345 }
346 };
347
348 expect(app.fullPath()).to.be.eq('/users/test');
349 });
350 });
351});