UNPKG

53.7 kBJavaScriptView Raw
1var t = require('../test-lib/test.js');
2var assert = require('assert');
3var _ = require('@sailshq/lodash');
4
5var apos;
6
7var simpleFields = [
8 {
9 name: 'name',
10 label: 'Name',
11 type: 'string'
12 },
13 {
14 name: 'address',
15 label: 'Address',
16 type: 'string',
17 textarea: true
18 },
19 {
20 name: 'variety',
21 label: 'Variety',
22 type: 'select',
23 choices: [
24 {
25 value: 'candy',
26 label: 'Candy'
27 },
28 {
29 value: 'cheese',
30 label: 'Cheese'
31 }
32 ],
33 def: 'candy'
34 },
35 {
36 name: 'tags',
37 label: 'Tags',
38 type: 'tags'
39 },
40 {
41 name: 'slug',
42 label: 'Slug',
43 type: 'slug'
44 }
45];
46
47var realWorldCase = {
48 "addFields": [
49 {
50 "type": "string",
51 "name": "title",
52 "label": "Title",
53 "required": true,
54 "sortify": true
55 },
56 {
57 "type": "slug",
58 "name": "slug",
59 "label": "Slug",
60 "required": true
61 },
62 {
63 "type": "tags",
64 "name": "tags",
65 "label": "Tags"
66 },
67 {
68 "type": "boolean",
69 "name": "published",
70 "label": "Published",
71 "def": true
72 },
73 {
74 "type": "boolean",
75 "name": "trash",
76 "label": "Trash",
77 "contextual": true,
78 "def": false
79 },
80 {
81 "type": "slug",
82 "name": "slug",
83 "label": "Old URL",
84 "required": true,
85 "page": true
86 },
87 {
88 "name": "title",
89 "label": "Description",
90 "type": "string",
91 "required": true
92 },
93 {
94 "type": "boolean",
95 "name": "published",
96 "label": "Published",
97 "required": true,
98 "def": true,
99 "contextual": true
100 },
101 {
102 "name": "urlType",
103 "label": "Link To",
104 "type": "select",
105 "choices": [
106 {
107 "label": "Internal Page",
108 "value": "internal",
109 "showFields": [
110 "_newPage"
111 ]
112 },
113 {
114 "label": "External URL",
115 "value": "external",
116 "showFields": [
117 "externalUrl"
118 ]
119 }
120 ]
121 },
122 {
123 "name": "externalUrl",
124 "label": "URL",
125 "type": "url"
126 },
127 {
128 "name": "_newPage",
129 "type": "joinByOne",
130 "withType": "apostrophe-page",
131 "label": "Page Title",
132 "idField": "pageId"
133 }
134 ],
135 "removeFields": [
136 "tags"
137 ],
138 "arrangeFields": [
139 {
140 "name": "basics",
141 "label": "Basics",
142 "fields": [
143 "title",
144 "slug",
145 "published",
146 "tags"
147 ]
148 },
149 {
150 "name": "permissions",
151 "label": "Permissions",
152 "fields": [
153 "loginRequired",
154 "_viewUsers",
155 "_viewGroups",
156 "_editUsers",
157 "_editGroups"
158 ],
159 "last": true
160 },
161 {
162 "name": "info",
163 "label": "Info",
164 "fields": [
165 "slug",
166 "urlType",
167 "_newPage",
168 "title",
169 "externalUrl"
170 ]
171 }
172 ]
173};
174
175var pageSlug = [
176 {
177 type: 'slug',
178 name: 'slug',
179 page: true
180 }
181];
182
183var regularSlug = [
184 {
185 type: 'slug',
186 name: 'slug'
187 }
188];
189
190var hasArea = {
191 addFields: [
192 {
193 type: 'area',
194 name: 'body',
195 label: 'Body',
196 widgets: {
197 'apostrophe-rich-text': {}
198 }
199 }
200 ]
201};
202
203describe('Schemas', function() {
204
205 this.timeout(t.timeout);
206
207 after(function(done) {
208 return t.destroy(apos, done);
209 });
210
211 /// ///
212 // EXISTENCE
213 /// ///
214
215 it('should be a property of the apos object', function(done) {
216 apos = require('../index.js')({
217 root: module,
218 shortName: 'test',
219
220 modules: {
221 'apostrophe-express': {
222 secret: 'xxx',
223 port: 7900
224 }
225 },
226 afterInit: function(callback) {
227 assert(apos.schemas);
228 apos.argv._ = [];
229 return callback(null);
230 },
231 afterListen: function(err) {
232 assert(!err);
233 done();
234 }
235 });
236 });
237
238 it('should compose schemas correctly', function() {
239 var options = {
240 addFields: [
241 {
242 name: 'name',
243 type: 'string',
244 label: 'Name'
245 },
246 {
247 name: 'address',
248 type: 'string',
249 label: 'Address',
250 textarea: true
251 },
252 {
253 name: 'variety',
254 type: 'select',
255 label: 'Variety',
256 choices: [
257 {
258 value: 'candy',
259 label: 'Candy'
260 },
261 {
262 value: 'cheese',
263 label: 'Cheese'
264 }
265 ]
266 }
267 ],
268 removeFields: [ 'address' ],
269 alterFields: function(schema) {
270 var variety = _.find(schema, { name: 'variety' });
271 assert(variety);
272 variety.choices.push({
273 value: 'record',
274 label: 'Record'
275 });
276 }
277 };
278 var schema = apos.schemas.compose(options);
279 assert(schema.length === 2);
280 assert(schema[0].name === 'name');
281 assert(schema[1].name === 'variety');
282 assert(_.keys(schema[1].choices).length === 3);
283 });
284
285 it('should compose a schema for a complex real world case correctly', function() {
286 var schema = apos.schemas.compose(realWorldCase);
287 assert(schema);
288 var externalUrl = _.find(schema, { name: 'externalUrl' });
289 assert(externalUrl);
290 assert(externalUrl.group.name === 'info');
291 var _newPage = _.find(schema, { name: '_newPage' });
292 assert(_newPage);
293 assert(_newPage.group.name === 'info');
294 });
295
296 it('should error if a field is required and an empty value is submitted for a string field type', function(done) {
297 var schema = apos.schemas.compose({
298 addFields: [
299 {
300 type: 'string',
301 name: 'name',
302 label: 'Name',
303 required: true
304 }
305 ]
306 });
307 assert(schema.length === 1);
308 var input = {
309 name: ''
310 };
311 var req = apos.tasks.getReq();
312 var result = {};
313 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
314 assert(err === 'name.required');
315 done();
316 });
317 });
318
319 it('should error if the value submitted is less than min length for a string field type', function(done) {
320 var schema = apos.schemas.compose({
321 addFields: [
322 {
323 type: 'string',
324 name: 'name',
325 label: 'Name',
326 min: 5
327 }
328 ]
329 });
330 assert(schema.length === 1);
331 var input = {
332 name: 'Cow'
333 };
334 var req = apos.tasks.getReq();
335 var result = {};
336 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
337 assert(err === 'name.min');
338 done();
339 });
340 });
341
342 it('should convert and keep the correct value for a field which is required for a string field type', function(done) {
343 var schema = apos.schemas.compose({
344 addFields: [
345 {
346 type: 'string',
347 name: 'name',
348 label: 'Name',
349 required: true
350 }
351 ]
352 });
353 assert(schema.length === 1);
354 var input = {
355 name: 'Apostrophe^CMS'
356 };
357 var req = apos.tasks.getReq();
358 var result = {};
359 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
360 assert(!err);
361 assert(result.name === 'Apostrophe^CMS');
362 done();
363 });
364 });
365
366 it('should error if an email address is improperly formed', function(done) {
367 var schema = apos.schemas.compose({
368 addFields: [
369 {
370 type: 'email',
371 name: 'email',
372 label: 'Email'
373 }
374 ]
375 });
376 assert(schema.length === 1);
377 var input = {
378 email: 'testguy1%oopsbad'
379 };
380 var req = apos.tasks.getReq();
381 var result = {};
382 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
383 assert(err === 'email.invalid');
384 done();
385 });
386 });
387
388 it('should tolerate no email value if field not required', function(done) {
389 var schema = apos.schemas.compose({
390 addFields: [
391 {
392 type: 'email',
393 name: 'email',
394 label: 'Email'
395 }
396 ]
397 });
398 assert(schema.length === 1);
399 var input = {
400 email: ''
401 };
402 var req = apos.tasks.getReq();
403 var result = {};
404 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
405 assert(!err);
406 done();
407 });
408 });
409
410 it('should reject no email value if field required', function(done) {
411 var schema = apos.schemas.compose({
412 addFields: [
413 {
414 type: 'email',
415 name: 'email',
416 label: 'Email',
417 required: true
418 }
419 ]
420 });
421 assert(schema.length === 1);
422 var input = {
423 email: ''
424 };
425 var req = apos.tasks.getReq();
426 var result = {};
427 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
428 assert(err);
429 assert(err === 'email.required');
430 done();
431 });
432 });
433
434 it('should accept a well formed email address with a + sign', function(done) {
435 var schema = apos.schemas.compose({
436 addFields: [
437 {
438 type: 'email',
439 name: 'email',
440 label: 'Email'
441 }
442 ]
443 });
444 assert(schema.length === 1);
445 var input = {
446 email: 'testguy1+cool@yaygreat.com'
447 };
448 var req = apos.tasks.getReq();
449 var result = {};
450 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
451 assert(!err);
452 done();
453 });
454 });
455
456 it('should keep an empty submitted field value null when there is a min / max configuration for an integer field type', function(done) {
457 var schema = apos.schemas.compose({
458 addFields: [
459 {
460 type: 'integer',
461 name: 'price',
462 label: 'Price',
463 min: 1,
464 max: 10
465 }
466 ]
467 });
468 assert(schema.length === 1);
469 var input = {
470 price: ''
471 };
472 var req = apos.tasks.getReq();
473 var result = {};
474 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
475 assert(!err);
476 assert(_.keys(result).length === 1);
477 assert(result.price === null);
478 done();
479 });
480 });
481
482 it('should keep an empty submitted field value null when there is a min / max configuration for a float field type', function(done) {
483 var schema = apos.schemas.compose({
484 addFields: [
485 {
486 type: 'float',
487 name: 'price',
488 label: 'Price',
489 min: 1,
490 max: 10
491 }
492 ]
493 });
494 assert(schema.length === 1);
495 var input = {
496 price: ''
497 };
498 var req = apos.tasks.getReq();
499 var result = {};
500 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
501 assert(!err);
502 assert(_.keys(result).length === 1);
503 assert(result.price === null);
504 done();
505 });
506 });
507
508 it('should keep an empty submitted field value null for a time field type', function(done) {
509 var schema = apos.schemas.compose({
510 addFields: [
511 {
512 type: 'time',
513 name: 'time',
514 label: 'time'
515 }
516 ]
517 });
518 assert(schema.length === 1);
519 var input = {
520 time: ''
521 };
522 var req = apos.tasks.getReq();
523 var result = {};
524 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
525 assert(!err);
526 assert(_.keys(result).length === 1);
527 assert(result.time === null);
528 done();
529 });
530 });
531
532 it('should keep an empty submitted field value null for a date field type', function(done) {
533 var schema = apos.schemas.compose({
534 addFields: [
535 {
536 type: 'date',
537 name: 'date',
538 label: 'date'
539 }
540 ]
541 });
542 assert(schema.length === 1);
543 var input = {
544 date: ''
545 };
546 var req = apos.tasks.getReq();
547 var result = {};
548 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
549 assert(!err);
550 assert(_.keys(result).length === 1);
551 assert(result.date === null);
552 done();
553 });
554 });
555
556 it('should ensure a max value is being trimmed to the max length for a string field type', function(done) {
557 var schema = apos.schemas.compose({
558 addFields: [
559 {
560 type: 'string',
561 name: 'name',
562 label: 'Name',
563 max: 5
564 }
565 ]
566 });
567 assert(schema.length === 1);
568 var input = {
569 name: 'Apostrophe'
570 };
571 var req = apos.tasks.getReq();
572 var result = {};
573 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
574 assert(!err);
575 assert(_.keys(result).length === 1);
576 assert(result.name === 'Apost');
577 done();
578 });
579 });
580
581 it('should allow saving a 0 value provided as a number if a field is required for an integer field type', function(done) {
582 var schema = apos.schemas.compose({
583 addFields: [
584 {
585 type: 'integer',
586 name: 'price',
587 label: 'Price',
588 required: true
589 }
590 ]
591 });
592 assert(schema.length === 1);
593 var input = {
594 price: 0
595 };
596 var req = apos.tasks.getReq();
597 var result = {};
598 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
599 assert(!err);
600 assert(_.keys(result).length === 1);
601 assert(result.price === 0);
602 done();
603 });
604 });
605
606 it('should gracefully reject null provided as a number if a field is required for an integer field type', function(done) {
607 var schema = apos.schemas.compose({
608 addFields: [
609 {
610 type: 'integer',
611 name: 'price',
612 label: 'Price',
613 required: true
614 }
615 ]
616 });
617 assert(schema.length === 1);
618 var input = {
619 price: null
620 };
621 var req = apos.tasks.getReq();
622 var result = {};
623 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
624 assert(err);
625 assert.equal(err, 'price.required');
626 done();
627 });
628 });
629
630 it('should gracefully reject undefined provided as a number if a field is required for an integer field type', function(done) {
631 var schema = apos.schemas.compose({
632 addFields: [
633 {
634 type: 'integer',
635 name: 'price',
636 label: 'Price',
637 required: true
638 }
639 ]
640 });
641 assert(schema.length === 1);
642 var input = {
643 price: undefined
644 };
645 var req = apos.tasks.getReq();
646 var result = {};
647 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
648 assert(err);
649 assert.equal(err, 'price.required');
650 done();
651 });
652 });
653
654 it('should allow saving a 0 value provided as a float if a field is required for an float field type', function(done) {
655 var schema = apos.schemas.compose({
656 addFields: [
657 {
658 type: 'float',
659 name: 'price',
660 label: 'Price',
661 required: true
662 }
663 ]
664 });
665 assert(schema.length === 1);
666 var input = {
667 price: 0.00
668 };
669 var req = apos.tasks.getReq();
670 var result = {};
671 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
672 assert(!err);
673 assert(_.keys(result).length === 1);
674 assert(result.price === 0.00);
675 done();
676 });
677 });
678
679 it('should allow saving a 0 value provided as a number if a field is required for an float field type', function(done) {
680 var schema = apos.schemas.compose({
681 addFields: [
682 {
683 type: 'float',
684 name: 'price',
685 label: 'Price',
686 required: true
687 }
688 ]
689 });
690 assert(schema.length === 1);
691 var input = {
692 price: 0
693 };
694 var req = apos.tasks.getReq();
695 var result = {};
696 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
697 assert(!err);
698 assert(_.keys(result).length === 1);
699 assert(result.price === 0);
700 done();
701 });
702 });
703
704 it('should allow saving a 0 value provided as a number if a field is required for an string field type', function(done) {
705 var schema = apos.schemas.compose({
706 addFields: [
707 {
708 type: 'string',
709 name: 'price',
710 label: 'Price',
711 required: true
712 }
713 ]
714 });
715 assert(schema.length === 1);
716 var input = {
717 price: 0
718 };
719 var req = apos.tasks.getReq();
720 var result = {};
721 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
722 assert(!err);
723 assert(_.keys(result).length === 1);
724 assert(result.price === '0');
725 done();
726 });
727 });
728
729 it('should allow saving a 0 value provided as a string if a field is required for an integer field type', function(done) {
730 var schema = apos.schemas.compose({
731 addFields: [
732 {
733 type: 'integer',
734 name: 'price',
735 label: 'Price',
736 required: true
737 }
738 ]
739 });
740 assert(schema.length === 1);
741 var input = {
742 price: '0'
743 };
744 var req = apos.tasks.getReq();
745 var result = {};
746 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
747 assert(!err);
748 assert(_.keys(result).length === 1);
749 assert(result.price === 0);
750 done();
751 });
752 });
753
754 it('should allow saving a 0 value provided as a string if a field is required for an string field type', function(done) {
755 var schema = apos.schemas.compose({
756 addFields: [
757 {
758 type: 'string',
759 name: 'price',
760 label: 'Price',
761 required: true
762 }
763 ]
764 });
765 assert(schema.length === 1);
766 var input = {
767 price: '0'
768 };
769 var req = apos.tasks.getReq();
770 var result = {};
771 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
772 assert(!err);
773 assert(_.keys(result).length === 1);
774 assert(result.price === '0');
775 done();
776 });
777 });
778
779 it('should allow saving a 0 value provided as a string if a field is required for an float field type', function(done) {
780 var schema = apos.schemas.compose({
781 addFields: [
782 {
783 type: 'float',
784 name: 'price',
785 label: 'Price',
786 required: true
787 }
788 ]
789 });
790 assert(schema.length === 1);
791 var input = {
792 price: '0'
793 };
794 var req = apos.tasks.getReq();
795 var result = {};
796 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
797 assert(!err);
798 assert(_.keys(result).length === 1);
799 assert(result.price === 0);
800 done();
801 });
802 });
803
804 it('should allow saving a 0 value provided as a string if there is no min value set for an integer field type', function(done) {
805 var schema = apos.schemas.compose({
806 addFields: [
807 {
808 type: 'integer',
809 name: 'price',
810 label: 'Price'
811 }
812 ]
813 });
814 assert(schema.length === 1);
815 var input = {
816 price: '0'
817 };
818 var req = apos.tasks.getReq();
819 var result = {};
820 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
821 assert(!err);
822 assert(_.keys(result).length === 1);
823 assert(result.price === 0);
824 done();
825 });
826 });
827
828 it('should allow saving a 0 value provided as a string if there is no min value set for a float field type', function(done) {
829 var schema = apos.schemas.compose({
830 addFields: [
831 {
832 type: 'float',
833 name: 'price',
834 label: 'Price'
835 }
836 ]
837 });
838 assert(schema.length === 1);
839 var input = {
840 price: '0'
841 };
842 var req = apos.tasks.getReq();
843 var result = {};
844 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
845 assert(!err);
846 assert(_.keys(result).length === 1);
847 assert(result.price === 0);
848 done();
849 });
850 });
851
852 it('should allow saving a negative value provided as a number for an integer field type', function(done) {
853 var schema = apos.schemas.compose({
854 addFields: [
855 {
856 type: 'integer',
857 name: 'price',
858 label: 'Price'
859 }
860 ]
861 });
862 assert(schema.length === 1);
863 var input = {
864 price: -1
865 };
866 var req = apos.tasks.getReq();
867 var result = {};
868 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
869 assert(!err);
870 assert(_.keys(result).length === 1);
871 assert(result.price === -1);
872 done();
873 });
874 });
875
876 it('should allow saving a negative value provided as a float for an float field type', function(done) {
877 var schema = apos.schemas.compose({
878 addFields: [
879 {
880 type: 'float',
881 name: 'price',
882 label: 'Price'
883 }
884 ]
885 });
886 assert(schema.length === 1);
887 var input = {
888 price: -1.3
889 };
890 var req = apos.tasks.getReq();
891 var result = {};
892 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
893 assert(!err);
894 assert(_.keys(result).length === 1);
895 assert(result.price === -1.3);
896 done();
897 });
898 });
899
900 it('should allow saving a negative value provided as a float for an string field type', function(done) {
901 var schema = apos.schemas.compose({
902 addFields: [
903 {
904 type: 'string',
905 name: 'price',
906 label: 'Price'
907 }
908 ]
909 });
910 assert(schema.length === 1);
911 var input = {
912 price: -1.3
913 };
914 var req = apos.tasks.getReq();
915 var result = {};
916 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
917 assert(!err);
918 assert(_.keys(result).length === 1);
919 assert(result.price === '-1.3');
920 done();
921 });
922 });
923
924 it('should allow saving a negative value provided as a number if a field is required for an integer field type', function(done) {
925 var schema = apos.schemas.compose({
926 addFields: [
927 {
928 type: 'integer',
929 name: 'price',
930 label: 'Price',
931 required: true
932 }
933 ]
934 });
935 assert(schema.length === 1);
936 var input = {
937 price: -1
938 };
939 var req = apos.tasks.getReq();
940 var result = {};
941 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
942 assert(!err);
943 assert(_.keys(result).length === 1);
944 assert(result.price === -1);
945 done();
946 });
947 });
948
949 it('should allow saving a negative value provided as a number if a field is required for an float field type', function(done) {
950 var schema = apos.schemas.compose({
951 addFields: [
952 {
953 type: 'float',
954 name: 'price',
955 label: 'Price',
956 required: true
957 }
958 ]
959 });
960 assert(schema.length === 1);
961 var input = {
962 price: -1.3
963 };
964 var req = apos.tasks.getReq();
965 var result = {};
966 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
967 assert(!err);
968 assert(_.keys(result).length === 1);
969 assert(result.price === -1.3);
970 done();
971 });
972 });
973
974 it('should allow saving a negative value provided as a string if a field is required for an float field type', function(done) {
975 var schema = apos.schemas.compose({
976 addFields: [
977 {
978 type: 'float',
979 name: 'price',
980 label: 'Price',
981 required: true
982 }
983 ]
984 });
985 assert(schema.length === 1);
986 var input = {
987 price: '-1.3'
988 };
989 var req = apos.tasks.getReq();
990 var result = {};
991 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
992 assert(!err);
993 assert(_.keys(result).length === 1);
994 assert(result.price === -1.3);
995 done();
996 });
997 });
998
999 it('should override the saved value if min and max value has been set and the submitted value is out of range for an integer field type', function(done) {
1000 var schema = apos.schemas.compose({
1001 addFields: [
1002 {
1003 type: 'integer',
1004 name: 'price',
1005 label: 'Price',
1006 min: 5,
1007 max: 6
1008 }
1009 ]
1010 });
1011 assert(schema.length === 1);
1012 var input = {
1013 price: '3'
1014 };
1015 var req = apos.tasks.getReq();
1016 var result = {};
1017 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1018 assert(!err);
1019 assert(_.keys(result).length === 1);
1020 assert(result.price === 5);
1021 done();
1022 });
1023 });
1024
1025 it('should override the saved value if min and max value has been set and the submitted value is out of range for a float field type', function(done) {
1026 var schema = apos.schemas.compose({
1027 addFields: [
1028 {
1029 type: 'float',
1030 name: 'price',
1031 label: 'Price',
1032 min: 5.1,
1033 max: 6
1034 }
1035 ]
1036 });
1037 assert(schema.length === 1);
1038 var input = {
1039 price: '3.2'
1040 };
1041 var req = apos.tasks.getReq();
1042 var result = {};
1043 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1044 assert(!err);
1045 assert(_.keys(result).length === 1);
1046 assert(result.price === 5.1);
1047 done();
1048 });
1049 });
1050
1051 it('should ensure a min value is being set to the configured min value if a lower value is submitted for an integer field type', function(done) {
1052 var schema = apos.schemas.compose({
1053 addFields: [
1054 {
1055 type: 'integer',
1056 name: 'price',
1057 label: 'Price',
1058 min: 5
1059 }
1060 ]
1061 });
1062 assert(schema.length === 1);
1063 var input = {
1064 price: '1'
1065 };
1066 var req = apos.tasks.getReq();
1067 var result = {};
1068 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1069 assert(!err);
1070 assert(_.keys(result).length === 1);
1071 assert(result.price === 5);
1072 done();
1073 });
1074 });
1075
1076 it('should ensure a min value is being set to the configured min value if a lower value is submitted for a float field type', function(done) {
1077 var schema = apos.schemas.compose({
1078 addFields: [
1079 {
1080 type: 'float',
1081 name: 'price',
1082 label: 'Price',
1083 min: 5.3
1084 }
1085 ]
1086 });
1087 assert(schema.length === 1);
1088 var input = {
1089 price: '1.2'
1090 };
1091 var req = apos.tasks.getReq();
1092 var result = {};
1093 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1094 assert(!err);
1095 assert(_.keys(result).length === 1);
1096 assert(result.price === 5.3);
1097 done();
1098 });
1099 });
1100
1101 it('should ensure a max value is being set to the max if a higher value is submitted for an integer field type', function(done) {
1102 var schema = apos.schemas.compose({
1103 addFields: [
1104 {
1105 type: 'integer',
1106 name: 'price',
1107 label: 'Price',
1108 max: 5
1109 }
1110 ]
1111 });
1112 assert(schema.length === 1);
1113 var input = {
1114 price: '8'
1115 };
1116 var req = apos.tasks.getReq();
1117 var result = {};
1118 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1119 assert(!err);
1120 assert(_.keys(result).length === 1);
1121 assert(result.price === 5);
1122 done();
1123 });
1124 });
1125
1126 it('should ensure a max value is being set to the max if a higher value is submitted for a float field type', function(done) {
1127 var schema = apos.schemas.compose({
1128 addFields: [
1129 {
1130 type: 'float',
1131 name: 'price',
1132 label: 'Price',
1133 max: 5.9
1134 }
1135 ]
1136 });
1137 assert(schema.length === 1);
1138 var input = {
1139 price: '8'
1140 };
1141 var req = apos.tasks.getReq();
1142 var result = {};
1143 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1144 assert(!err);
1145 assert(_.keys(result).length === 1);
1146 assert(result.price === 5.9);
1147 done();
1148 });
1149 });
1150
1151 it('should not modify a value if the submitted value is within min and max for an integer field type', function(done) {
1152 var schema = apos.schemas.compose({
1153 addFields: [
1154 {
1155 type: 'integer',
1156 name: 'price',
1157 label: 'Price',
1158 min: 4,
1159 max: 6
1160 }
1161 ]
1162 });
1163 assert(schema.length === 1);
1164 var input = {
1165 price: '5'
1166 };
1167 var req = apos.tasks.getReq();
1168 var result = {};
1169 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1170 assert(!err);
1171 assert(_.keys(result).length === 1);
1172 assert(result.price === 5);
1173 done();
1174 });
1175 });
1176
1177 it('should not modify a value if the submitted value is within min and max for a float field type', function(done) {
1178 var schema = apos.schemas.compose({
1179 addFields: [
1180 {
1181 type: 'float',
1182 name: 'price',
1183 label: 'Price',
1184 min: 4,
1185 max: 5
1186 }
1187 ]
1188 });
1189 assert(schema.length === 1);
1190 var input = {
1191 price: '4.3'
1192 };
1193 var req = apos.tasks.getReq();
1194 var result = {};
1195 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1196 assert(!err);
1197 assert(_.keys(result).length === 1);
1198 assert(result.price === 4.3);
1199 done();
1200 });
1201 });
1202
1203 it('should not allow a text value to be submitted for a required integer field', function(done) {
1204 var schema = apos.schemas.compose({
1205 addFields: [
1206 {
1207 type: 'integer',
1208 name: 'price',
1209 label: 'Price',
1210 required: true
1211 }
1212 ]
1213 });
1214 assert(schema.length === 1);
1215 var input = {
1216 price: 'A'
1217 };
1218 var req = apos.tasks.getReq();
1219 var result = {};
1220 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1221 assert(err);
1222 done();
1223 });
1224 });
1225
1226 it('should not allow a text value to be submitted for a required float field', function(done) {
1227 var schema = apos.schemas.compose({
1228 addFields: [
1229 {
1230 type: 'float',
1231 name: 'price',
1232 label: 'Price',
1233 required: true
1234 }
1235 ]
1236 });
1237 assert(schema.length === 1);
1238 var input = {
1239 price: 'A'
1240 };
1241 var req = apos.tasks.getReq();
1242 var result = {};
1243 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1244 assert(err);
1245 done();
1246 });
1247 });
1248
1249 it('should not allow a text value to be submitted for a non required integer field with min and max', function(done) {
1250 var schema = apos.schemas.compose({
1251 addFields: [
1252 {
1253 type: 'integer',
1254 name: 'price',
1255 label: 'Price',
1256 min: 1,
1257 max: 10
1258 }
1259 ]
1260 });
1261 assert(schema.length === 1);
1262 var input = {
1263 price: 'A'
1264 };
1265 var req = apos.tasks.getReq();
1266 var result = {};
1267 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1268 assert(err);
1269 done();
1270 });
1271 });
1272
1273 it('should not allow a text value to be submitted for a non required float field with min and max', function(done) {
1274 var schema = apos.schemas.compose({
1275 addFields: [
1276 {
1277 type: 'float',
1278 name: 'price',
1279 label: 'Price',
1280 min: 1,
1281 max: 10
1282 }
1283 ]
1284 });
1285 assert(schema.length === 1);
1286 var input = {
1287 price: 'A'
1288 };
1289 var req = apos.tasks.getReq();
1290 var result = {};
1291 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1292 assert(err);
1293 done();
1294 });
1295 });
1296
1297 it('should not allow a text value to be submitted for a non required integer field with a default value set', function(done) {
1298 var schema = apos.schemas.compose({
1299 addFields: [
1300 {
1301 type: 'integer',
1302 name: 'price',
1303 label: 'Price',
1304 def: 2
1305 }
1306 ]
1307 });
1308 assert(schema.length === 1);
1309 var input = {
1310 price: 'A'
1311 };
1312 var req = apos.tasks.getReq();
1313 var result = {};
1314 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1315 assert(err);
1316 done();
1317 });
1318 });
1319
1320 it('should not allow a text value to be submitted for a non required float field with a default value set', function(done) {
1321 var schema = apos.schemas.compose({
1322 addFields: [
1323 {
1324 type: 'float',
1325 name: 'price',
1326 label: 'Price',
1327 def: 2.10
1328 }
1329 ]
1330 });
1331 assert(schema.length === 1);
1332 var input = {
1333 price: 'A'
1334 };
1335 var req = apos.tasks.getReq();
1336 var result = {};
1337 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1338 assert(err);
1339 done();
1340 });
1341 });
1342
1343 it('should not allow a text value to be submitted for a non required integer field', function(done) {
1344 var schema = apos.schemas.compose({
1345 addFields: [
1346 {
1347 type: 'integer',
1348 name: 'price',
1349 label: 'Price'
1350 }
1351 ]
1352 });
1353 assert(schema.length === 1);
1354 var input = {
1355 price: 'A'
1356 };
1357 var req = apos.tasks.getReq();
1358 var result = {};
1359 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1360 assert(err);
1361 done();
1362 });
1363 });
1364
1365 it('should not allow a text value to be submitted for a non required float field', function(done) {
1366 var schema = apos.schemas.compose({
1367 addFields: [
1368 {
1369 type: 'float',
1370 name: 'price',
1371 label: 'Price'
1372 }
1373 ]
1374 });
1375 assert(schema.length === 1);
1376 var input = {
1377 price: 'A'
1378 };
1379 var req = apos.tasks.getReq();
1380 var result = {};
1381 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1382 assert(err);
1383 done();
1384 });
1385 });
1386
1387 it('should allow a parsable string/integer value to be submitted for a non required integer field', function(done) {
1388 var schema = apos.schemas.compose({
1389 addFields: [
1390 {
1391 type: 'integer',
1392 name: 'price',
1393 label: 'Price'
1394 }
1395 ]
1396 });
1397 assert(schema.length === 1);
1398 var input = {
1399 price: '22a'
1400 };
1401 var req = apos.tasks.getReq();
1402 var result = {};
1403 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1404 assert(!err);
1405 assert(result.price === 22);
1406 done();
1407 });
1408 });
1409
1410 it('should allow a parsable string/float value to be submitted for a non required float field', function(done) {
1411 var schema = apos.schemas.compose({
1412 addFields: [
1413 {
1414 type: 'float',
1415 name: 'price',
1416 label: 'Price'
1417 }
1418 ]
1419 });
1420 assert(schema.length === 1);
1421 var input = {
1422 price: '11.4b'
1423 };
1424 var req = apos.tasks.getReq();
1425 var result = {};
1426 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1427 assert(!err);
1428 assert(result.price === 11.4);
1429 done();
1430 });
1431 });
1432
1433 it('should convert simple data correctly', function(done) {
1434 var schema = apos.schemas.compose({
1435 addFields: simpleFields
1436 });
1437 assert(schema.length === 5);
1438 var input = apos.schemas.newInstance(schema);
1439 Object.assign(input, {
1440 name: 'Bob Smith',
1441 address: '5017 Awesome Street\nPhiladelphia, PA 19147',
1442 irrelevant: 'Irrelevant',
1443 slug: 'This Is Cool'
1444 });
1445 var req = apos.tasks.getReq();
1446 var result = {};
1447 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1448 assert(!err);
1449 // no irrelevant or missing fields
1450 assert(_.keys(result).length === 5);
1451 // expected fields came through
1452 assert(result.name === input.name);
1453 assert(result.address === input.address);
1454 // default
1455 assert(result.variety === simpleFields[2].choices[0].value);
1456 assert(Array.isArray(result.tags) && (result.tags.length === 0));
1457 assert(result.slug === 'this-is-cool');
1458 done();
1459 });
1460 });
1461
1462 it('should convert tags correctly', function(done) {
1463 var schema = apos.schemas.compose({
1464 addFields: simpleFields
1465 });
1466 assert(schema.length === 5);
1467 var input = {
1468 tags: [ 4, 5, 'Seven' ]
1469 };
1470 var req = apos.tasks.getReq();
1471 var result = {};
1472 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1473 assert(!err);
1474 // without def, the default is undefined, so this is right
1475 assert(_.keys(result.tags).length === 3);
1476 assert(Array.isArray(result.tags));
1477 assert(result.tags[0] === '4');
1478 assert(result.tags[1] === '5');
1479 // case conversion
1480 assert(result.tags[2] === 'seven');
1481 assert(result.slug === 'none');
1482 done();
1483 });
1484 });
1485
1486 it('should update a password if provided', function(done) {
1487 var schema = apos.schemas.compose({
1488 addFields: [
1489 {
1490 type: 'password',
1491 name: 'password',
1492 label: 'Password'
1493 }
1494 ]
1495 });
1496 assert(schema.length === 1);
1497 var input = {
1498 password: 'silly'
1499 };
1500 var req = apos.tasks.getReq();
1501 var result = { password: 'serious' };
1502 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1503 assert(!err);
1504 assert(_.keys(result).length === 1);
1505 // hashing is not the business of schemas, see the
1506 // apostrophe-users module
1507 assert(result.password === 'silly');
1508 done();
1509 });
1510 });
1511
1512 it('should leave a password alone if not provided', function(done) {
1513 var schema = apos.schemas.compose({
1514 addFields: [
1515 {
1516 type: 'password',
1517 name: 'password',
1518 label: 'Password'
1519 }
1520 ]
1521 });
1522 assert(schema.length === 1);
1523 var input = {
1524 password: ''
1525 };
1526 var req = apos.tasks.getReq();
1527 var result = { password: 'serious' };
1528 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1529 assert(!err);
1530 assert(_.keys(result).length === 1);
1531 // hashing is not the business of schemas, see the
1532 // apostrophe-users module
1533 assert(result.password === 'serious');
1534 done();
1535 });
1536 });
1537
1538 it('should handle array schemas', function(done) {
1539 var schema = apos.schemas.compose({
1540 addFields: [
1541 {
1542 type: 'array',
1543 name: 'addresses',
1544 label: 'Addresses',
1545 schema: [
1546 {
1547 name: 'address',
1548 type: 'string',
1549 label: 'Address'
1550 }
1551 ]
1552 }
1553 ]
1554 });
1555 assert(schema.length === 1);
1556 var input = {
1557 addresses: [
1558 {
1559 address: '500 test lane'
1560 },
1561 {
1562 address: '602 test ave'
1563 }
1564 ]
1565 };
1566 var req = apos.tasks.getReq();
1567 var result = {};
1568 return apos.schemas.convert(req, schema, 'form', input, result, function(err) {
1569 assert(!err);
1570 assert(_.keys(result).length === 1);
1571 assert(Array.isArray(result.addresses));
1572 assert(result.addresses.length === 2);
1573 assert(result.addresses[0].id);
1574 assert(result.addresses[1].id);
1575 assert(result.addresses[0].address === '500 test lane');
1576 assert(result.addresses[1].address === '602 test ave');
1577 done();
1578 });
1579 });
1580
1581 it('should convert string areas correctly', function(done) {
1582 var schema = apos.schemas.compose(hasArea);
1583 assert(schema.length === 1);
1584 var input = {
1585 irrelevant: 'Irrelevant',
1586 // Should get escaped, not be treated as HTML
1587 body: 'This is the greatest <h1>thing</h1>'
1588 };
1589 var req = apos.tasks.getReq();
1590 var result = {};
1591 return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
1592 assert(!err);
1593 // no irrelevant or missing fields
1594 assert(_.keys(result).length === 1);
1595 // expected fields came through
1596 assert(result.body);
1597 assert(result.body.type === 'area');
1598 assert(result.body.items);
1599 assert(result.body.items[0]);
1600 assert(result.body.items[0].type === 'apostrophe-rich-text');
1601 assert(result.body.items[0].content === apos.utils.escapeHtml(input.body));
1602 done();
1603 });
1604 });
1605
1606 it('should convert string areas gracefully when they are undefined', function(done) {
1607 var schema = apos.schemas.compose(hasArea);
1608 assert(schema.length === 1);
1609 var input = {
1610 irrelevant: 'Irrelevant',
1611 // Should get escaped, not be treated as HTML
1612 body: undefined
1613 };
1614 var req = apos.tasks.getReq();
1615 var result = {};
1616 return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
1617 assert(!err);
1618 // no irrelevant or missing fields
1619 assert(_.keys(result).length === 1);
1620 // expected fields came through
1621 assert(result.body);
1622 assert(result.body.type === 'area');
1623 assert(result.body.items);
1624 assert(!result.body.items[0]);
1625 done();
1626 });
1627 });
1628
1629 it('should accept csv as a bc equivalent for string in convert', function(done) {
1630 var schema = apos.schemas.compose(hasArea);
1631 assert(schema.length === 1);
1632 var input = {
1633 irrelevant: 'Irrelevant',
1634 // Should get escaped, not be treated as HTML
1635 body: 'This is the greatest <h1>thing</h1>'
1636 };
1637 var req = apos.tasks.getReq();
1638 var result = {};
1639 return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
1640 assert(!err);
1641 // no irrelevant or missing fields
1642 assert(_.keys(result).length === 1);
1643 // expected fields came through
1644 assert(result.body);
1645 assert(result.body.type === 'area');
1646 assert(result.body.items);
1647 assert(result.body.items[0]);
1648 assert(result.body.items[0].type === 'apostrophe-rich-text');
1649 assert(result.body.items[0].content === apos.utils.escapeHtml(input.body));
1650 done();
1651 });
1652 });
1653
1654 it('should clean up extra slashes in page slugs', function(done) {
1655 var req = apos.tasks.getReq();
1656 var schema = apos.schemas.compose({ addFields: pageSlug });
1657 assert(schema.length === 1);
1658 var input = {
1659 slug: '/wiggy//wacky///wobbly////whizzle/////'
1660 };
1661 var result = {};
1662 return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
1663 assert(!err);
1664 assert(result.slug === '/wiggy/wacky/wobbly/whizzle');
1665 done();
1666 });
1667 });
1668
1669 it('retains trailing / on the home page', function(done) {
1670 var req = apos.tasks.getReq();
1671 var schema = apos.schemas.compose({ addFields: pageSlug });
1672 assert(schema.length === 1);
1673 var input = {
1674 slug: '/'
1675 };
1676 var result = {};
1677 return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
1678 assert(!err);
1679 assert(result.slug === '/');
1680 done();
1681 });
1682 });
1683
1684 it('does not keep slashes when page: true not present for slug', function(done) {
1685 var req = apos.tasks.getReq();
1686 var schema = apos.schemas.compose({ addFields: regularSlug });
1687 assert(schema.length === 1);
1688 var input = {
1689 slug: '/wiggy//wacky///wobbly////whizzle/////'
1690 };
1691 var result = {};
1692 return apos.schemas.convert(req, schema, 'string', input, result, function(err) {
1693 assert(!err);
1694 assert(result.slug === 'wiggy-wacky-wobbly-whizzle');
1695 done();
1696 });
1697 });
1698
1699 it('enforces required property for ordinary field', function(done) {
1700 var req = apos.tasks.getReq();
1701 var schema = apos.schemas.compose({
1702 addFields: [
1703 {
1704 name: 'age',
1705 label: 'Age',
1706 type: 'integer',
1707 required: true
1708 }
1709 ]
1710 });
1711 var output = {};
1712 apos.schemas.convert(req, schema, 'form', { age: '' }, output, function(err) {
1713 assert(err);
1714 assert(err === 'age.required');
1715 done();
1716 });
1717 });
1718
1719 it('ignores required property for hidden field', function(done) {
1720 var req = apos.tasks.getReq();
1721 var schema = apos.schemas.compose({
1722 addFields: [
1723 {
1724 name: 'age',
1725 type: 'integer',
1726 required: true
1727 },
1728 {
1729 name: 'shoeSize',
1730 type: 'integer',
1731 required: false
1732 },
1733 {
1734 name: 'ageOrShoeSize',
1735 type: 'select',
1736 choices: [
1737 {
1738 label: 'age',
1739 value: 'age',
1740 showFields: [ 'age' ]
1741 },
1742 {
1743 label: 'shoeSize',
1744 value: 'shoeSize',
1745 showFields: [ 'shoeSize' ]
1746 }
1747 ]
1748 }
1749 ]
1750 });
1751 var output = {};
1752 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'shoeSize', age: '' }, output, function(err) {
1753 assert(!err);
1754 assert(output.ageOrShoeSize === 'shoeSize');
1755 done();
1756 });
1757 });
1758
1759 it('enforces required property for shown field', function(done) {
1760 var req = apos.tasks.getReq();
1761 var schema = apos.schemas.compose({
1762 addFields: [
1763 {
1764 name: 'age',
1765 type: 'integer',
1766 required: true
1767 },
1768 {
1769 name: 'shoeSize',
1770 type: 'integer',
1771 required: false
1772 },
1773 {
1774 name: 'ageOrShoeSize',
1775 type: 'select',
1776 choices: [
1777 {
1778 label: 'age',
1779 value: 'age',
1780 showFields: [ 'age' ]
1781 },
1782 {
1783 label: 'shoeSize',
1784 value: 'shoeSize',
1785 showFields: [ 'shoeSize' ]
1786 }
1787 ]
1788 }
1789 ]
1790 });
1791 var output = {};
1792 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'age', age: '' }, output, function(err) {
1793 assert(err);
1794 assert(err === 'age.required');
1795 done();
1796 });
1797 });
1798
1799 it('ignores required property for recursively hidden field', function(done) {
1800 var req = apos.tasks.getReq();
1801 var schema = apos.schemas.compose({
1802 addFields: [
1803 {
1804 name: 'age',
1805 type: 'integer',
1806 required: true
1807 },
1808 {
1809 name: 'shoeSize',
1810 type: 'integer',
1811 required: false
1812 },
1813 {
1814 name: 'ageOrShoeSize',
1815 type: 'select',
1816 choices: [
1817 {
1818 label: 'age',
1819 value: 'age',
1820 showFields: [ 'age' ]
1821 },
1822 {
1823 label: 'shoeSize',
1824 value: 'shoeSize',
1825 showFields: [ 'shoeSize' ]
1826 }
1827 ]
1828 },
1829 {
1830 name: 'doWeCare',
1831 type: 'select',
1832 choices: [
1833 {
1834 label: 'Yes',
1835 value: '1',
1836 showFields: [ 'ageOrShoeSize' ]
1837 },
1838 {
1839 label: 'No',
1840 value: '0',
1841 showFields: []
1842 }
1843 ]
1844 }
1845 ]
1846 });
1847 var output = {};
1848 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'age', doWeCare: '0', age: '' }, output, function(err) {
1849 assert(!err);
1850 assert(output.ageOrShoeSize === 'age');
1851 done();
1852 });
1853 });
1854
1855 it('enforces required property for recursively shown field', function(done) {
1856 var req = apos.tasks.getReq();
1857 var schema = apos.schemas.compose({
1858 addFields: [
1859 {
1860 name: 'age',
1861 type: 'integer',
1862 required: true
1863 },
1864 {
1865 name: 'shoeSize',
1866 type: 'integer',
1867 required: false
1868 },
1869 {
1870 name: 'ageOrShoeSize',
1871 type: 'select',
1872 choices: [
1873 {
1874 label: 'age',
1875 value: 'age',
1876 showFields: [ 'age' ]
1877 },
1878 {
1879 label: 'shoeSize',
1880 value: 'shoeSize',
1881 showFields: [ 'shoeSize' ]
1882 }
1883 ]
1884 },
1885 {
1886 name: 'doWeCare',
1887 type: 'select',
1888 choices: [
1889 {
1890 label: 'Yes',
1891 value: '1',
1892 showFields: [ 'ageOrShoeSize' ]
1893 },
1894 {
1895 label: 'No',
1896 value: '0',
1897 showFields: []
1898 }
1899 ]
1900 }
1901 ]
1902 });
1903 var output = {};
1904 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'age', doWeCare: '1', age: '' }, output, function(err) {
1905 assert(err);
1906 assert(err === 'age.required');
1907 done();
1908 });
1909 });
1910
1911 it('ignores required property for recursively hidden field with checkboxes', function(done) {
1912 var req = apos.tasks.getReq();
1913 var schema = apos.schemas.compose({
1914 addFields: [
1915 {
1916 name: 'age',
1917 type: 'integer',
1918 required: true
1919 },
1920 {
1921 name: 'shoeSize',
1922 type: 'integer',
1923 required: false
1924 },
1925 {
1926 name: 'ageOrShoeSize',
1927 type: 'checkboxes',
1928 choices: [
1929 {
1930 label: 'age',
1931 value: 'age',
1932 showFields: [ 'age' ]
1933 },
1934 {
1935 label: 'shoeSize',
1936 value: 'shoeSize',
1937 showFields: [ 'shoeSize' ]
1938 }
1939 ]
1940 },
1941 {
1942 name: 'doWeCare',
1943 type: 'checkboxes',
1944 choices: [
1945 {
1946 label: 'Yes',
1947 value: '1',
1948 showFields: [ 'ageOrShoeSize' ]
1949 },
1950 {
1951 label: 'No',
1952 value: '0',
1953 showFields: []
1954 }
1955 ]
1956 }
1957 ]
1958 });
1959 var output = {};
1960 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: ['age'], doWeCare: ['0'], age: '' }, output, function(err) {
1961 assert(!err);
1962 assert.deepEqual(output.ageOrShoeSize, ['age']);
1963 done();
1964 });
1965 });
1966
1967 it('enforces required property for recursively shown field with checkboxes', function(done) {
1968 var req = apos.tasks.getReq();
1969 var schema = apos.schemas.compose({
1970 addFields: [
1971 {
1972 name: 'age',
1973 type: 'integer',
1974 required: true
1975 },
1976 {
1977 name: 'shoeSize',
1978 type: 'integer',
1979 required: false
1980 },
1981 {
1982 name: 'ageOrShoeSize',
1983 type: 'checkboxes',
1984 choices: [
1985 {
1986 label: 'age',
1987 value: 'age',
1988 showFields: [ 'age' ]
1989 },
1990 {
1991 label: 'shoeSize',
1992 value: 'shoeSize',
1993 showFields: [ 'shoeSize' ]
1994 }
1995 ]
1996 },
1997 {
1998 name: 'doWeCare',
1999 type: 'checkboxes',
2000 choices: [
2001 {
2002 label: 'Yes',
2003 value: '1',
2004 showFields: [ 'ageOrShoeSize' ]
2005 },
2006 {
2007 label: 'No',
2008 value: '0',
2009 showFields: []
2010 }
2011 ]
2012 }
2013 ]
2014 });
2015 var output = {};
2016 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: ['age', 'shoeSize'], doWeCare: ['1'], age: '' }, output, function(err) {
2017 assert(err);
2018 assert(err === 'age.required');
2019 done();
2020 });
2021 });
2022
2023 it('ignores required property for recursively hidden field with boolean', function(done) {
2024 var req = apos.tasks.getReq();
2025 var schema = apos.schemas.compose({
2026 addFields: [
2027 {
2028 name: 'age',
2029 type: 'integer',
2030 required: true
2031 },
2032 {
2033 name: 'shoeSize',
2034 type: 'integer',
2035 required: false
2036 },
2037 {
2038 name: 'ageOrShoeSize',
2039 type: 'select',
2040 choices: [
2041 {
2042 label: 'age',
2043 value: 'age',
2044 showFields: [ 'age' ]
2045 },
2046 {
2047 label: 'shoeSize',
2048 value: 'shoeSize',
2049 showFields: [ 'shoeSize' ]
2050 }
2051 ]
2052 },
2053 {
2054 name: 'doWeCare',
2055 type: 'boolean',
2056 choices: [
2057 {
2058 value: true,
2059 showFields: [ 'ageOrShoeSize' ]
2060 },
2061 {
2062 value: false,
2063 showFields: []
2064 }
2065 ]
2066 }
2067 ]
2068 });
2069 var output = {};
2070 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: 'age', doWeCare: false, age: '' }, output, function(err) {
2071 assert(!err);
2072 assert(output.ageOrShoeSize === 'age');
2073 done();
2074 });
2075 });
2076
2077 it('enforces required property for recursively shown field with boolean', function(done) {
2078 var req = apos.tasks.getReq();
2079 var schema = apos.schemas.compose({
2080 addFields: [
2081 {
2082 name: 'age',
2083 type: 'integer',
2084 required: true
2085 },
2086 {
2087 name: 'shoeSize',
2088 type: 'integer',
2089 required: false
2090 },
2091 {
2092 name: 'ageOrShoeSize',
2093 type: 'checkboxes',
2094 choices: [
2095 {
2096 label: 'age',
2097 value: 'age',
2098 showFields: [ 'age' ]
2099 },
2100 {
2101 label: 'shoeSize',
2102 value: 'shoeSize',
2103 showFields: [ 'shoeSize' ]
2104 }
2105 ]
2106 },
2107 {
2108 name: 'doWeCare',
2109 type: 'boolean',
2110 choices: [
2111 {
2112 value: true,
2113 showFields: [ 'ageOrShoeSize' ]
2114 },
2115 {
2116 value: false,
2117 showFields: []
2118 }
2119 ]
2120 }
2121 ]
2122 });
2123 var output = {};
2124 apos.schemas.convert(req, schema, 'form', { ageOrShoeSize: ['age', 'shoeSize'], doWeCare: true, age: '' }, output, function(err) {
2125 assert(err);
2126 assert(err === 'age.required');
2127 done();
2128 });
2129 });
2130
2131});