UNPKG

29.4 kBJavaScriptView Raw
1'use strict';
2
3var request = require('supertest');
4var chance = new (require('chance'))();
5var assert = require('assert');
6var _ = require('lodash');
7var async = require('async');
8var docker = process.env.DOCKER;
9
10module.exports = function(app) {
11 // The Helper class.
12 var Helper = function(owner, template, hook) {
13 this.contextName = '';
14 this.lastSubmission = null;
15 this.lastResponse = null;
16 this.owner = owner;
17 this.series = [];
18 this.expects = [];
19 this.template = template || {
20 project: null,
21 forms: {},
22 actions: {},
23 submissions: {},
24 roles: {},
25 users: {}
26 };
27 this.hook = hook;
28 };
29
30 Helper.prototype.perms = function(permissions) {
31 const permsConfig = [];
32 _.each(permissions, (roles, name) => {
33 permsConfig.push({
34 type: name,
35 roles: _.map(roles, (roleName) => {
36 return this.template.roles[roleName]._id.toString()
37 })
38 });
39 });
40 return permsConfig;
41 };
42
43 Helper.prototype.getTemplate = function() {
44 return this.template;
45 };
46
47 // Return the last submission made.
48 Helper.prototype.getLastSubmission = function() {
49 return this.lastSubmission;
50 };
51
52 Helper.prototype.getForms = function(done) {
53 var url = '';
54 if (this.template.project && this.template.project._id) {
55 url += '/project/' + this.template.project._id;
56 }
57 url += '/form?limit=9999';
58 request(app)
59 .get(url)
60 .set('x-jwt-token', this.owner.token)
61 .expect('Content-Type', /json/)
62 .expect(200)
63 .end((err, res) => {
64 if (err) {
65 return done(err);
66 }
67
68 _.each(res.body, (form) => {
69 this.template.forms[form.name] = form;
70 });
71 this.lastResponse = res;
72 this.owner.token = res.headers['x-jwt-token'];
73 done(null, this.template.forms);
74 });
75 };
76
77 Helper.prototype.getForm = function(name) {
78 if (this.template.forms.hasOwnProperty(name)) {
79 return this.template.forms[name];
80 }
81
82 return null;
83 };
84
85 Helper.prototype.getActions = function(form, done) {
86 var url = '';
87 if (this.template.project && this.template.project._id) {
88 url += '/project/' + this.template.project._id;
89 }
90 url += '/form/' + this.template.forms[form]._id + '/action';
91 request(app)
92 .get(url)
93 .set('x-jwt-token', this.owner.token)
94 .expect('Content-Type', /json/)
95 .expect(200)
96 .end((err, res) => {
97 if (err) {
98 return done(err, res);
99 }
100 if (!res.body) {
101 return done('No response', res)
102 }
103
104 this.lastResponse = res;
105 this.owner.token = res.headers['x-jwt-token'];
106 this.template.actions[form] = [];
107 for (var i = 0; i < res.body.length; i++) {
108 this.template.actions[form].push(res.body[i]);
109 }
110
111 done(null, res.body);
112 });
113 };
114
115 Helper.prototype.getAction = function(form, action) {
116 if (!action && form) {
117 if (typeof form ==='string') {
118 form = {
119 title: form
120 };
121 }
122
123 action = form;
124 form = this.contextName;
125 }
126 if (!action._id && !action.title) {
127 return undefined;
128 }
129
130 var _action;
131 this.template.actions[form] = this.template.actions[form] || [];
132 this.template.actions[form].forEach(function(a) {
133 if (_action) {
134 return;
135 }
136
137 // NOTE: Titles are not unique for actions, use only when positive one exists.
138 if (a.title === action.title || a._id === action._id) {
139 _action = a;
140 return;
141 }
142 });
143
144 return _action;
145 };
146
147 Helper.prototype.deleteAction = function(form, action, done) {
148 this.getActions(form, (err, actions) => {
149 if (err) {
150 return done(err);
151 }
152
153 let _action;
154 actions.forEach((a) => {
155 if (a.title === action.title || a._id === action._id) {
156 _action = a;
157 return;
158 }
159 });
160 if (_action) {
161 var url = '';
162 if (this.template.project && this.template.project._id) {
163 url += '/project/' + this.template.project._id;
164 }
165 url += '/form/' + this.template.forms[form]._id + '/action/' + _action._id;
166
167 request(app)
168 .delete(url)
169 .set('x-jwt-token', this.owner.token)
170 .expect(200)
171 .end((err, res) => {
172 if (err) {
173 return done(err, res);
174 }
175 if (!res.body) {
176 return done('No response', res)
177 }
178
179 this.lastResponse = res;
180 this.owner.token = res.headers['x-jwt-token'];
181 _.remove(this.template.actions[form], {_id: _action._id});
182 done();
183 });
184 }
185 else {
186 return done('Action not found');
187 }
188 });
189 };
190
191 Helper.prototype.getRoles = function(done) {
192 var url = '';
193 if (this.template.project && this.template.project._id) {
194 url += '/project/' + this.template.project._id;
195 }
196 url += '/role?limit=9999';
197
198 // Get the roles created for this project.
199 request(app)
200 .get(url)
201 .set('x-jwt-token', this.owner.token)
202 .expect('Content-Type', /json/)
203 .expect(200)
204 .end((err, res) => {
205 if (err) {
206 return done(err);
207 }
208
209 // Assign the roles.
210 assert.equal(res.body.length, 3);
211 _.each(res.body, (role) => {
212 if (role.admin) {
213 this.template.roles.administrator = role;
214 }
215 else if (role.default) {
216 this.template.roles.anonymous = role;
217 }
218 else {
219 this.template.roles.authenticated = role;
220 }
221 });
222 assert.equal(Object.keys(this.template.roles).length, 3);
223 this.owner.token = res.headers['x-jwt-token'];
224 this.lastResponse = res;
225 done(null, this.template.roles);
226 });
227 };
228
229 /**
230 * Get a role by its title.
231 *
232 * @param title
233 * @returns {*|undefined}
234 */
235 Helper.prototype.getRole = function(title) {
236 this.template.roles = this.template.roles || {};
237 return this.template.roles[title] || undefined;
238 };
239
240 Helper.prototype.getRolesAndForms = function(done) {
241 async.series([
242 async.apply(this.getForms.bind(this)),
243 async.apply(this.getRoles.bind(this))
244 ], (err) => {
245 if (err) {
246 return done(err);
247 }
248 done(null, this.template);
249 });
250 };
251
252 Helper.prototype.getProject = function(done) {
253 if (!app.hasProjects && !docker) {
254 return done('No project');
255 }
256 if (!this.template.project) {
257 return done('No project');
258 }
259
260 request(app)
261 .get('/project/' + this.template.project._id)
262 .set('x-jwt-token', this.owner.token)
263 .expect('Content-Type', /json/)
264 .expect(200)
265 .end((err, res) => {
266 if (err) {
267 return done(err);
268 }
269 this.lastResponse = res;
270 this.template.project = res.body;
271 return done(null, res.body);
272 });
273 };
274
275 Helper.prototype.createProject = function(settings, done) {
276 if (app.hasProjects || docker) {
277 request(app)
278 .post('/project')
279 .send({
280 title: chance.word(),
281 name: chance.word(),
282 description: chance.sentence(),
283 settings: settings !== undefined ? settings : {}
284 })
285 .set('x-jwt-token', this.owner.token)
286 .expect('Content-Type', /json/)
287 .expect(201)
288 .end((err, res) => {
289 if (err) {
290 return done(err);
291 }
292
293 this.lastResponse = res;
294 this.template.project = res.body;
295 this.getRolesAndForms((err) => {
296 if (err) {
297 return done(err);
298 }
299 return done(null, res.body);
300 });
301 });
302 }
303 else {
304 this.getRolesAndForms((err) => {
305 if (err) {
306 return done(err);
307 }
308 return done(null, this.template);
309 });
310 }
311 };
312
313 Helper.prototype.project = function(settings) {
314 this.series.push(async.apply(this.createProject.bind(this), settings));
315 return this;
316 };
317
318 Helper.prototype.updateForm = function(form, done) {
319 let url = '';
320 if (this.template.project && this.template.project._id) {
321 url += '/project/' + this.template.project._id;
322 }
323 url += '/form/' + form._id;
324
325 request(app).put(url)
326 .send(_.omit(form, 'modified'))
327 .set('x-jwt-token', this.owner.token)
328 .expect('Content-Type', /json/)
329 .expect(200)
330 .end((err, res) => {
331 if (err) {
332 return done(err, res);
333 }
334 this.owner.token = res.headers['x-jwt-token'];
335 this.template.forms[form.name] = res.body;
336 done(null, res.body);
337 });
338 }
339
340 Helper.prototype.upsertForm = function(form, done) {
341 this.contextName = form.name;
342
343 // If no access is provided, then use the default.
344 if (!form.hasOwnProperty('access')) {
345 form.access = [];
346 }
347 if (!form.hasOwnProperty('submissionAccess')) {
348 form.submissionAccess = [];
349 }
350
351 // Convert the role names to role ids.
352 ['access', 'submissionAccess'].forEach(accessName =>
353 _.each(form[accessName], (perm, i) =>
354 _.each(perm.roles, (permRole, j) => {
355 if (this.template.roles.hasOwnProperty(permRole)) {
356 form[accessName][i].roles[j] = this.template.roles[permRole]._id;
357 }
358 })
359 )
360 );
361
362 var method = 'post';
363 var status = 201;
364 var url = '';
365 if (this.template.project && this.template.project._id) {
366 url += '/project/' + this.template.project._id;
367 }
368 url += '/form';
369 var data = {
370 title: form.name,
371 name: form.name,
372 path: form.name,
373 type: form.type,
374 access: form.access,
375 submissionAccess: form.submissionAccess,
376 components: form.components
377 };
378 if (this.template.forms.hasOwnProperty(form.name)) {
379 method = 'put';
380 status = 200;
381 url += '/' + this.template.forms[form.name]._id;
382 data = {
383 components: form.components
384 };
385
386 // Allow upsert to modify machineNames
387 if (form.hasOwnProperty('machineName')) {
388 data.machineName = form.machineName;
389 }
390 }
391 request(app)[method](url)
392 .send(data)
393 .set('x-jwt-token', this.owner.token)
394 .expect('Content-Type', /json/)
395 .expect(status)
396 .end((err, res) => {
397 if (err) {
398 return done(err, res);
399 }
400 this.lastResponse = res;
401 this.owner.token = res.headers['x-jwt-token'];
402 this.template.forms[form.name] = res.body;
403 done(null, res.body);
404 });
405 };
406
407 Helper.prototype.form = function(name, components, access) {
408 var form;
409 if (typeof name !== 'string') {
410 // If the first param is an array, its components.
411 if (name instanceof Array) {
412 form = form || {};
413 form.components = name;
414 }
415 else {
416 form = name;
417 }
418
419 // parse out the name or make one.
420 form = form || {};
421 name = form.name || chance.word();
422 }
423 else {
424 form = form || {};
425 form.name = name;
426 }
427
428 if (components instanceof Array) {
429 form = form || {};
430 form.components = components;
431 }
432 if (access) {
433 form = form || {};
434 if (access.hasOwnProperty('access') && access.access instanceof Array) {
435 form.access = access.access;
436 }
437 if (access.hasOwnProperty('submissionAccess') && access.submissionAccess instanceof Array) {
438 form.submissionAccess = access.submissionAccess;
439 }
440 }
441
442 form = form || {};
443 form.name = form.name || chance.word();
444 form.type = form.type || 'form';
445 form.components = form.components || [];
446 form.access = form.access || [];
447 form.submissionAccess = form.submissionAccess || [];
448
449 this.series.push(async.apply(this.upsertForm.bind(this), form));
450 return this;
451 };
452
453 Helper.prototype._deleteForm = function(_id, done) {
454 if (this.template.forms.hasOwnProperty(_id)) {
455 _id = this.template.forms[_id]._id.toString();
456 }
457 let url = '/form/' + _id;
458 if (this.hook) {
459 url = this.hook.alter('url', url, this.template);
460 }
461 request(app)
462 .delete(url)
463 .set('x-jwt-token', this.owner.token)
464 .expect(200)
465 .end(done);
466 };
467
468 Helper.prototype.deleteForm = function(form) {
469 var _id = form._id || form;
470
471 this.series.push(async.apply(this._deleteForm.bind(this), _id));
472 return this;
473 };
474
475 Helper.prototype.resource = function(name, components, access) {
476 var resource = {
477 type: 'resource'
478 };
479
480 if (typeof name === 'string') {
481 resource.name = name;
482 }
483 if (name instanceof Array) {
484 resource.components = name;
485 }
486
487 return this.form.call(this, resource, components, access);
488 };
489
490 /**
491 * Chainable method to create an adhoc role.
492 *
493 * @param role
494 * @returns {Helper}
495 */
496 Helper.prototype.role = function(role, update) {
497 if (update) {
498 this.series.push(async.apply(this.upsertRole.bind(this), role, update));
499 return this;
500 }
501
502 this.series.push(async.apply(this.upsertRole.bind(this), role));
503 return this;
504 };
505
506 Helper.prototype.updateAction = function(form, action, done) {
507 if (!this.template.actions.hasOwnProperty(form)) {
508 return done('No actions exist for the given form.');
509 }
510
511 var _action = this.getAction.call(this, form, action);
512 if (!_action) {
513 return done('No action could be found.');
514 }
515 if (!_action.hasOwnProperty('_id')) {
516 return done('Could not determine which action to modify.');
517 }
518
519 var url = '';
520 if (this.template.project && this.template.project._id) {
521 url += '/project/' + this.template.project._id;
522 }
523 url += '/form/' + this.template.forms[form]._id + '/action/' + _action._id;
524
525 request(app)
526 .put(url)
527 .send(action)
528 .set('x-jwt-token', this.owner.token)
529 .expect('Content-Type', /json/)
530 .expect(200)
531 .end((err, res) => {
532 if (err) {
533 return done(err, res);
534 }
535 if (!res.body) {
536 return done('No response', res)
537 }
538
539 this.lastResponse = res;
540 this.owner.token = res.headers['x-jwt-token'];
541 for (var a = 0; a < this.template.actions[form].length; a++) {
542 if (
543 this.template.actions[form][a]._id === _action._id
544 || this.template.actions[form][a].name === _action.name
545 ) {
546 this.template.actions[form][a] = res.body;
547 break;
548 }
549 }
550
551 done(null, res.body);
552 });
553 };
554
555 Helper.prototype.createAction = function(form, action, done) {
556 if (typeof form === 'object') {
557 action = form;
558 form = this.contextName;
559 }
560
561 if (!this.template.forms.hasOwnProperty(form)) {
562 return done('Form not found');
563 }
564
565 var _action = this.getAction(form, {_id: action._id});
566 if (_action) {
567 return this.updateAction(form, action, done);
568 }
569
570 if (action.settings) {
571 if (action.settings.resources) {
572 var resources = [];
573 _.each(action.settings.resources, resource => {
574 if (this.template.forms.hasOwnProperty(resource)) {
575 resources.push(this.template.forms[resource]._id);
576 }
577 });
578 action.settings.resources = resources;
579 }
580
581 if (action.settings.resource) {
582 if (this.template.forms.hasOwnProperty(action.settings.resource)) {
583 action.settings.resource = this.template.forms[action.settings.resource]._id;
584 }
585 }
586
587 if (action.settings.role && this.template.roles.hasOwnProperty(action.settings.role)) {
588 action.settings.role = this.template.roles[action.settings.role]._id;
589 }
590 }
591
592 var url = '';
593 if (this.template.project && this.template.project._id) {
594 url += '/project/' + this.template.project._id;
595 }
596 url += '/form/' + this.template.forms[form]._id + '/action';
597
598 request(app)
599 .post(url)
600 .send(action)
601 .set('x-jwt-token', this.owner.token)
602 .expect('Content-Type', /json/)
603 .expect(201)
604 .end((err, res) => {
605 if (err) {
606 return done(err);
607 }
608
609 this.lastResponse = res;
610 this.owner.token = res.headers['x-jwt-token'];
611 if (!this.template.actions[form]) {
612 this.template.actions[form] = [];
613 }
614 this.template.actions[form].push(res.body);
615 done(null, res.body);
616 });
617 };
618
619 Helper.prototype.action = function(form, action) {
620 this.series.push(async.apply(this.createAction.bind(this), form, action));
621 return this;
622 };
623
624 Helper.prototype.removeAction = function(form, action) {
625 this.series.push(async.apply(this.deleteAction.bind(this), form, action));
626 return this;
627 };
628
629 Helper.prototype.updateSubmission = function(submission, user, expect, done) {
630 if (typeof user === 'function') {
631 done = user;
632 user = this.owner;
633 }
634
635 if (typeof expect === 'function') {
636 done = expect;
637 expect = [];
638 }
639
640 expect = expect || [];
641 if (typeof user === 'string') {
642 user = this.template.users[user];
643 }
644
645 if (user === undefined) {
646 user = this.owner;
647 }
648
649 var url = '';
650 if (this.template.project && this.template.project._id) {
651 url += '/project/' + this.template.project._id;
652 }
653 url += '/form/' + submission.form + '/submission/' + submission._id;
654
655 let currentRequest = request(app).put(url).send(submission);
656 if (user) {
657 currentRequest = currentRequest.set('x-jwt-token', user.token);
658 }
659 if (expect.length) {
660 currentRequest = currentRequest.expect('Content-Type', expect[0]).expect(expect[1]);
661 }
662 else {
663 currentRequest = currentRequest.expect('Content-Type', /json/).expect(200);
664 }
665 currentRequest.end((err, res) => {
666 if (err) {
667 return done(err);
668 }
669
670 this.lastResponse = res;
671 if (expect.length && expect[1] > 299) {
672 return done(null, res.body);
673 }
674
675 user.token = res.headers['x-jwt-token'];
676 this.lastSubmission = res.body;
677 _.each(this.template.submissions, (sub, form) => {
678 if (sub._id === submission._id) {
679 this.template.submissions[form] = res.body;
680 }
681 });
682 done(null, res.body);
683 });
684 };
685
686 Helper.prototype.createSubmission = function(form, data, user, expect, done) {
687 // Two arguments.
688 if (typeof form === 'object') {
689 if (typeof data === 'function') {
690 done = data;
691 }
692 data = form;
693 form = this.contextName;
694 }
695
696 // Three arguments.
697 if (typeof user === 'function') {
698 done = user;
699 user = this.owner;
700 }
701
702 // Four arguments
703 if (typeof expect === 'function') {
704 done = expect;
705 expect = [];
706 }
707
708 expect = expect || [];
709 if (typeof user === 'string') {
710 user = this.template.users[user];
711 }
712
713 if (user === undefined) {
714 user = this.owner;
715 }
716
717 if (!this.template.forms.hasOwnProperty(form)) {
718 return done('Form not found');
719 }
720
721 var url = '';
722 if (this.template.project && this.template.project._id) {
723 url += '/project/' + this.template.project._id;
724 }
725 url += '/form/' + this.template.forms[form]._id + '/submission';
726
727 // Allow passing in the submission as well
728 if (!data.hasOwnProperty('data')) {
729 data = {data};
730 }
731
732 let currentRequest = request(app).post(url).send(data);
733 if (user) {
734 currentRequest = currentRequest.set('x-jwt-token', user.token);
735 }
736 if (expect.length) {
737 currentRequest = currentRequest.expect('Content-Type', expect[0]).expect(expect[1]);
738 }
739 else {
740 if (this.expects.length) {
741 _.each(this.expects, (expect) => {
742 currentRequest = currentRequest.expect(...expect);
743 });
744 }
745 else {
746 currentRequest = currentRequest.expect('Content-Type', /json/).expect(201);
747 }
748 }
749 currentRequest.end((err, res) => {
750 this.nextExpect = false;
751 if (err) {
752 return done(err);
753 }
754
755 this.lastResponse = res;
756 if (expect.length && expect[1] > 299) {
757 return done(null, res.body);
758 }
759
760 if (user && res.headers['x-jwt-token']) {
761 user.token = res.headers['x-jwt-token'];
762 }
763 this.template.submissions = this.template.submissions || {};
764 if (!this.template.submissions[form]) {
765 this.template.submissions[form] = [];
766 }
767
768 this.lastSubmission = res.body;
769 this.template.submissions[form].push(res.body);
770 done(null, res.body);
771 });
772 };
773
774 /**
775 * Get a submission either by ID or by Index.
776 *
777 * @param form
778 * @param id - (string) for Submission ID, (number) for Index.
779 * @param user
780 * @param done
781 * @return {*}
782 */
783 Helper.prototype.getSubmission = function(form, id, user, expect, done) {
784 if (typeof form === 'object') {
785 if (typeof id === 'function') {
786 done = id;
787 }
788 id = form;
789 form = this.contextName;
790 }
791
792 if (typeof user === 'function') {
793 done = user;
794 user = this.owner;
795 }
796
797 if (typeof expect === 'function') {
798 done = expect;
799 expect = [];
800 }
801
802 expect = expect || [];
803 if (typeof user === 'string') {
804 user = this.template.users[user];
805 }
806
807 if (user === undefined) {
808 user = this.owner;
809 }
810
811 if (!this.template.forms.hasOwnProperty(form)) {
812 return done('Form not found');
813 }
814
815 var url = '';
816 var subIndex = true;
817 if (this.template.project && this.template.project._id) {
818 url += '/project/' + this.template.project._id;
819 }
820 url += '/form/' + this.template.forms[form]._id + '/submission';
821 if (typeof id === 'string') {
822 subIndex = false;
823 url += '/' + id;
824 }
825
826 let currentRequest = request(app).get(url).send();
827 if (user) {
828 currentRequest = currentRequest.set('x-jwt-token', user.token);
829 }
830 if (expect.length) {
831 currentRequest = currentRequest.expect('Content-Type', expect[0]).expect(expect[1]);
832 }
833 else {
834 currentRequest = currentRequest.expect('Content-Type', /json/).expect(200);
835 }
836 currentRequest.end((err, res) => {
837 if (err) {
838 return done(err);
839 }
840
841 this.lastResponse = res;
842 if (expect.length && expect[1] > 299) {
843 return done();
844 }
845
846 if (user && res.headers['x-jwt-token']) {
847 user.token = res.headers['x-jwt-token'];
848 }
849 this.template.submissions = this.template.submissions || {};
850 if (subIndex) {
851 this.template.submissions[form] = res.body;
852 }
853 else if (!this.template.submissions[form]) {
854 this.template.submissions[form] = [];
855 }
856
857 const submission = subIndex ? res.body[id] : res.body;
858 this.lastSubmission = submission;
859 if (!subIndex) {
860 const index = _.findIndex(this.template.submissions[form], {_id: submission._id});
861 if (index === -1) {
862 this.template.submissions[form].push(submission);
863 }
864 else {
865 this.template.submissions[form][index] = submission;
866 }
867 }
868 done(null, submission);
869 });
870 };
871
872 Helper.prototype.deleteSubmission = function(submission, user, expect, done) {
873 if (typeof user === 'function') {
874 done = user;
875 user = this.owner;
876 }
877
878 if (typeof expect === 'function') {
879 done = expect;
880 expect = [];
881 }
882
883 expect = expect || [];
884 if (typeof user === 'string') {
885 user = this.template.users[user];
886 }
887
888 if (user === undefined) {
889 user = this.owner;
890 }
891
892 var url = '';
893 if (this.template.project && this.template.project._id) {
894 url += '/project/' + this.template.project._id;
895 }
896 url += '/form/' + submission.form + '/submission/' + submission._id;
897
898 let currentRequest = request(app).delete(url).send(submission);
899 if (user) {
900 currentRequest = currentRequest.set('x-jwt-token', user.token);
901 }
902 if (expect.length) {
903 currentRequest = currentRequest.expect('Content-Type', expect[0]).expect(expect[1]);
904 }
905 else {
906 currentRequest = currentRequest.expect('Content-Type', /json/).expect(200);
907 }
908 currentRequest.end((err, res) => {
909 if (err) {
910 return done(err);
911 }
912
913 this.lastResponse = res;
914 if (expect.length && expect[1] > 299) {
915 return done();
916 }
917
918 if (user && res.headers['x-jwt-token']) {
919 user.token = res.headers['x-jwt-token'];
920 }
921 _.remove(this.template.submissions, {_id: submission._id});
922 done();
923 });
924 };
925
926 /**
927 * Internal helper to create or edit a role
928 *
929 * @param role
930 * @param done
931 */
932 Helper.prototype.upsertRole = function(role, update, done) {
933 if (typeof update === 'function') {
934 done = update;
935 update = undefined;
936 }
937
938 var url = '';
939 if (this.template.project && this.template.project._id) {
940 url += '/project/' + this.template.project._id;
941 }
942 url += '/role';
943
944 if (update) {
945 var _role;
946 if (!role._id) {
947 _role = this.getRole(role.title || role);
948 }
949
950 url += '/' + _role._id;
951 request(app)
952 .put(url)
953 .send(update)
954 .set('x-jwt-token', this.owner.token)
955 .expect('Content-Type', /json/)
956 .expect(200)
957 .end((err, res) => {
958 if (err) {
959 return done(err, res);
960 }
961
962 var response = res.body;
963 this.lastResponse = res;
964 this.owner.token = res.headers['x-jwt-token'];
965 this.template.roles = this.template.roles || {};
966 this.template.roles[response.title] = response;
967 done(null, response);
968 });
969 }
970 else {
971 request(app)
972 .post(url)
973 .send(role)
974 .set('x-jwt-token', this.owner.token)
975 .expect('Content-Type', /json/)
976 .expect(201)
977 .end((err, res) => {
978 if (err) {
979 return done(err);
980 }
981
982 var response = res.body;
983 this.lastResponse = res;
984 this.owner.token = res.headers['x-jwt-token'];
985 this.template.roles = this.template.roles || {};
986 this.template.roles[response.title] = response;
987 done(null, response);
988 });
989 }
990 };
991
992 /**
993 * Delete a role.
994 *
995 * @param role
996 * @param done
997 */
998 Helper.prototype.deleteRole = function(role, done) {
999 var _role;
1000 if (!role._id) {
1001 _role = this.getRole(role.title || role);
1002 }
1003
1004 var url = '';
1005 if (this.template.project && this.template.project._id) {
1006 url += '/project/' + this.template.project._id;
1007 }
1008 url += '/role/' + _role._id;
1009
1010 request(app)
1011 .delete(url)
1012 .set('x-jwt-token', this.owner.token)
1013 .expect(200)
1014 .end((err, res) => {
1015 if (err) {
1016 return done(err);
1017 }
1018
1019 var response = res.body;
1020 this.lastResponse = res;
1021 this.owner.token = res.headers['x-jwt-token'];
1022 this.template.roles = this.template.roles || {};
1023 delete this.template.roles[response.title];
1024 done(null, response);
1025 });
1026 };
1027
1028 Helper.prototype.submission = function(form, data, user, expects) {
1029 if (data && data._id && data.form) {
1030 this.series.push(async.apply(this.updateSubmission.bind(this), data, user, expects));
1031 }
1032 else {
1033 this.series.push(async.apply(this.createSubmission.bind(this), form, data, user, expects));
1034 }
1035 return this;
1036 };
1037
1038 Helper.prototype.expect = function(...args) {
1039 this.expects.push(args);
1040 return this;
1041 };
1042
1043 Helper.prototype.user = function(form, user, data) {
1044 data = data || {};
1045 data.email = chance.email();
1046 data.password = chance.word();
1047 this.series.push((done) => {
1048 this.createSubmission(form, {data}, (err, submission) => {
1049 if (err) {
1050 return done(err);
1051 }
1052
1053 assert(submission, 'Must have a user object');
1054 assert(submission._id, 'Must have created a new user');
1055 this.template.users[user] = submission;
1056 this.template.users[user].data.password = data.password;
1057
1058 // Now authenticate as this user to get JWT token.
1059 this.createSubmission(form + 'Login', {data: {
1060 email: this.template.users[user].data.email,
1061 password: this.template.users[user].data.password
1062 }}, null, [/application\/json/, 200], (err) => {
1063 if (err) {
1064 return done(err);
1065 }
1066
1067 const res = this.lastResponse.res;
1068 assert(res.headers['x-jwt-token'], 'Authentication must return x-jwt-token');
1069 this.template.users[user].token = res.headers['x-jwt-token'];
1070 done(null, this.template.users[user]);
1071 });
1072 });
1073 });
1074 return this;
1075 };
1076
1077 Helper.prototype.execute = function(done) {
1078 return async.series(this.series, (err, res) => {
1079 this.series = [];
1080 this.expects = [];
1081 if (err) {
1082 return done(err, res);
1083 }
1084 done(null, this);
1085 });
1086 };
1087
1088 Helper.assert = {
1089 propertiesEqual: (source, compare) => {
1090 _.each(source, (value, key) => {
1091 if (compare.hasOwnProperty(key)) {
1092 assert.deepEqual(value, compare[key]);
1093 }
1094 });
1095 }
1096 };
1097
1098 return Helper;
1099};