UNPKG

21.7 kBJavaScriptView Raw
1var assert = require('assert');
2var mongo = require('mongodb');
3var _ = require('lodash');
4var apos = require('apostrophe')();
5
6var db;
7
8var pages;
9
10var home;
11
12var page;
13
14var children;
15
16var about;
17
18var contact;
19
20var req = apos.getTaskReq();
21
22// TODO: test 'before' position for move(), test conflicting paths and slugs
23
24describe('apostrophe-pages', function() {
25 describe('initialize resources', function() {
26 it('initialize mongodb', function(done) {
27 db = new mongo.Db(
28 'apostest',
29 new mongo.Server('127.0.0.1', 27017, {}),
30 // Sensible default of safe: true
31 // (soon to be the driver's default)
32 { safe: true }
33 );
34 assert(!!db);
35 db.open(function(err) {
36 assert(!err);
37 return done();
38 });
39 });
40 it('initialize apostrophe', function(done) {
41 return apos.init({
42 db: db,
43 app: {
44 request: {},
45 locals: {},
46 get: function() {},
47 post: function() {}
48 }
49 }, function(err) {
50 assert(!err);
51 return done();
52 });
53 });
54 it('initialize apostrophe-pages', function(done) {
55 pages = require('../index.js')({
56 apos: apos,
57 ui: false
58 }, function(err) {
59 assert(!err);
60 assert(!!pages);
61 return done();
62 });
63 });
64 });
65 describe('remove test data', function() {
66 it('removed', function(done) {
67 apos.pages.remove({}, function(err) {
68 assert(!err);
69 done();
70 });
71 });
72 });
73 describe('insert test data', function() {
74 apos.pages = apos.pages;
75 it('inserted', function(done) {
76 apos.pages.insert(
77 [
78 {
79 _id: 'home',
80 path: 'home',
81 title: 'Home',
82 sortTitle: 'home',
83 level: 0,
84 rank: 0,
85 slug: '/',
86 body: {
87 items: [
88 {
89 type: 'richText',
90 content: '<p>Body content</p>'
91 }
92 ],
93 type: 'area'
94 },
95 sidebar: {
96 items: [
97 {
98 type: 'richText',
99 content: '<p>Sidebar content</p>'
100 }
101 ],
102 type: 'area'
103 },
104 published: true
105 },
106 // Kids in scrambled order so sort() has work to do
107 {
108 _id: 'contact',
109 path: 'home/contact',
110 title: 'Contact',
111 sortTitle: 'contact',
112 level: 1,
113 rank: 2,
114 slug: '/contact',
115 body: {
116 items: [
117 {
118 type: 'richText',
119 content: '<p>Body content</p>'
120 }
121 ],
122 type: 'area'
123 },
124 sidebar: {
125 items: [
126 {
127 type: 'richText',
128 content: '<p>Sidebar content</p>'
129 }
130 ],
131 type: 'area'
132 },
133 tags: [ 'red', 'green' ],
134 published: true
135 },
136 {
137 _id: 'about',
138 path: 'home/about',
139 title: 'About',
140 sortTitle: 'about',
141 level: 1,
142 rank: 0,
143 slug: '/about',
144 body: {
145 items: [
146 {
147 type: 'richText',
148 content: '<p>Body content</p>'
149 }
150 ],
151 type: 'area'
152 },
153 sidebar: {
154 items: [
155 {
156 type: 'richText',
157 content: '<p>Sidebar content</p>'
158 }
159 ],
160 type: 'area'
161 },
162 tags: [ 'green', 'blue' ],
163 published: true
164 },
165 {
166 _id: 'location',
167 path: 'home/about/location',
168 title: 'Location',
169 sortTitle: 'location',
170 level: 2,
171 rank: 1,
172 slug: '/about/location',
173 body: {
174 items: [
175 {
176 type: 'richText',
177 content: '<p>Body content</p>'
178 }
179 ],
180 type: 'area'
181 },
182 sidebar: {
183 items: [
184 {
185 type: 'richText',
186 content: '<p>Sidebar content</p>'
187 }
188 ],
189 type: 'area'
190 },
191 published: true
192 },
193 {
194 _id: 'people',
195 path: 'home/about/people',
196 title: 'People',
197 sortTitle: 'people',
198 level: 2,
199 rank: 0,
200 slug: '/about/people',
201 body: {
202 items: [
203 {
204 type: 'richText',
205 content: '<p>Body content</p>'
206 }
207 ],
208 type: 'area'
209 },
210 sidebar: {
211 items: [
212 {
213 type: 'richText',
214 content: '<p>Sidebar content</p>'
215 }
216 ],
217 type: 'area'
218 },
219 tags: [ 'green' ],
220 published: true
221 },
222 {
223 _id: 'friends',
224 // This page is an "orphan" that should not show up
225 // if methods other than getAncestors are given the
226 // orphan: false flag
227 orphan: true,
228 path: 'home/about/friends',
229 title: 'Friends',
230 sortTitle: 'friends',
231 level: 2,
232 rank: 2,
233 slug: '/about/friends',
234 body: {
235 items: [
236 {
237 type: 'richText',
238 content: '<p>Body content</p>'
239 }
240 ],
241 type: 'area'
242 },
243 sidebar: {
244 items: [
245 {
246 type: 'richText',
247 content: '<p>Sidebar content</p>'
248 }
249 ],
250 type: 'area'
251 },
252 tags: [ 'friends' ],
253 published: true
254 },
255 {
256 _id: 'products',
257 path: 'home/products',
258 title: 'Products',
259 sortTitle: 'products',
260 level: 1,
261 rank: 1,
262 slug: '/products',
263 body: {
264 items: [
265 {
266 type: 'richText',
267 content: '<p>Body content</p>'
268 }
269 ],
270 type: 'area'
271 },
272 sidebar: {
273 items: [
274 {
275 type: 'richText',
276 content: '<p>Sidebar content</p>'
277 }
278 ],
279 type: 'area'
280 },
281 published: true
282 }
283 ], function(err) {
284 assert(!err);
285 done();
286 }
287 );
288 });
289 });
290 describe('fetch home page', function() {
291 it('fetched', function(done) {
292 apos.pages.findOne({ _id: 'home' }, function(err, doc) {
293 assert(!!doc);
294 home = doc;
295 page = doc;
296 done();
297 });
298 });
299 });
300 describe('fetch ancestors of home page (should be empty)', function() {
301 it('fetched', function(done) {
302 pages.getAncestors(req, page, function(err, ancestors) {
303 assert(ancestors.length === 0);
304 done();
305 });
306 });
307 });
308
309 describe('fetch descendants of home page', function() {
310 it('fetched', function(done) {
311 pages.getDescendants(req, page, { depth: 2 }, function(err, childrenArg) {
312 children = childrenArg;
313 assert(!err);
314 assert(children.length === 3);
315 done();
316 });
317 });
318 it('in order', function() {
319 assert(children[0]._id === 'about');
320 assert(children[1]._id === 'products');
321 assert(children[2]._id === 'contact');
322 });
323 it('did not return areas', function() {
324 assert(!children[0].body);
325 assert(!children[1].body);
326 assert(!children[2].body);
327 });
328 it('have grandkids', function() {
329 assert(children[0].children.length === 3);
330 });
331 it('grandkids in order', function() {
332 assert(children[0].children[0]._id === 'people');
333 assert(children[0].children[1]._id === 'location');
334 assert(children[0].children[2]._id === 'friends');
335 });
336 it('fetch again with orphans turned off', function(done) {
337 pages.getDescendants(req, page, { depth: 2, orphan: false }, function(err, childrenArg) {
338 children = childrenArg;
339 assert(!err);
340 assert(children.length === 3);
341 done();
342 });
343 });
344 it('in order', function() {
345 assert(children[0]._id === 'about');
346 assert(children[1]._id === 'products');
347 assert(children[2]._id === 'contact');
348 });
349 it('did not return areas', function() {
350 assert(!children[0].body);
351 assert(!children[1].body);
352 assert(!children[2].body);
353 });
354 it('have correct number of grandkids', function() {
355 assert(children[0].children.length === 2);
356 });
357 it('grandkids in order', function() {
358 assert(children[0].children[0]._id === 'people');
359 assert(children[0].children[1]._id === 'location');
360 });
361 it('fetch again with areas turned on', function(done) {
362 pages.getDescendants(req, page, { depth: 2, areas: true }, function(err, childrenArg) {
363 children = childrenArg;
364 assert(!err);
365 assert(children.length === 3);
366 done();
367 });
368 });
369 it('did return areas', function() {
370 assert(children[0].sidebar);
371 assert(children[1].sidebar);
372 assert(children[2].sidebar);
373 assert(children[0].body);
374 assert(children[1].body);
375 assert(children[2].body);
376 });
377 it('fetch again with specific area', function(done) {
378 pages.getDescendants(req, page, { depth: 2, areas: [ 'body' ] }, function(err, childrenArg) {
379 children = childrenArg;
380 assert(!err);
381 assert(children.length === 3);
382 done();
383 });
384 });
385 it('returned body area', function() {
386 assert(children[0].body);
387 assert(children[1].body);
388 assert(children[2].body);
389 });
390 it('did not return sidebar area', function() {
391 assert(!children[0].sidebar);
392 assert(!children[1].sidebar);
393 assert(!children[2].sidebar);
394 });
395 });
396
397 var ancestors;
398
399 describe('fetch ancestors of home/about/people', function() {
400 it('fetched', function(done) {
401 var people = children[0].children[0];
402 pages.getAncestors(req, people, function(err, ancestorsArg) {
403 assert(!err);
404 assert(ancestorsArg);
405 ancestors = ancestorsArg;
406 done();
407 });
408 });
409 it('correct count', function() {
410 assert(ancestors.length === 2);
411 });
412 it('correct paths in order', function() {
413 assert(ancestors[0]._id === 'home');
414 assert(ancestors[1]._id === 'about');
415 });
416 it('did not return areas', function() {
417 assert(!ancestors[0].body);
418 assert(!ancestors[1].body);
419 assert(!ancestors[0].sidebar);
420 assert(!ancestors[1].sidebar);
421 });
422 it('fetch again with areas turned on', function(done) {
423 var people = children[0].children[0];
424 pages.getAncestors(req, people, { areas: true }, function(err, ancestorsArg) {
425 assert(!err);
426 assert(ancestorsArg);
427 ancestors = ancestorsArg;
428 done();
429 });
430 });
431 it('did return all areas', function() {
432 assert(ancestors[0].body);
433 assert(ancestors[1].body);
434 assert(ancestors[0].sidebar);
435 assert(ancestors[1].sidebar);
436 });
437 it('fetch again with specific area', function(done) {
438 var people = children[0].children[0];
439 pages.getAncestors(req, people, { areas: [ 'body' ] }, function(err, ancestorsArg) {
440 assert(!err);
441 assert(ancestorsArg);
442 ancestors = ancestorsArg;
443 done();
444 });
445 });
446 it('returned body area', function() {
447 assert(ancestors[0].body);
448 assert(ancestors[1].body);
449 });
450 it('did not return sidebar area', function() {
451 assert(!ancestors[0].sidebar);
452 assert(!ancestors[1].sidebar);
453 });
454 it('did not return children', function() {
455 assert(!ancestors[0].children);
456 assert(!ancestors[1].children);
457 });
458 it('fetch again with children', function(done) {
459 var people = children[0].children[0];
460 pages.getAncestors(req, people, { children: true }, function(err, ancestorsArg) {
461 assert(!err);
462 assert(ancestorsArg);
463 ancestors = ancestorsArg;
464 done();
465 });
466 });
467 it('did return children arrays', function() {
468 assert(Array.isArray(ancestors[0].children));
469 assert(Array.isArray(ancestors[1].children));
470 });
471 it('children arrays are correct', function() {
472 assert(ancestors[0].children.length === 3);
473 });
474 });
475
476 describe('getParent returns home/about for home/about/people', function() {
477 it('returned', function(done) {
478 var people = children[0].children[0];
479 pages.getParent(req, people, function(err, parent) {
480 assert(!err);
481 assert(parent);
482 assert(parent._id === 'about');
483 about = parent;
484 return done();
485 });
486 });
487 });
488
489 describe('move home/about/people after home/contact', function() {
490 var people;
491 it('people exists', function(done) {
492 people = children[0].children[0];
493 assert(people._id === 'people');
494 done();
495 });
496 it('moved without error', function(done) {
497 pages.move(req, people, '/contact', 'after', function(err) {
498 if (err) {
499 console.log(err);
500 }
501 assert(!err);
502 return done();
503 });
504 });
505 it('home has 4 descendants', function(done) {
506 pages.getDescendants(req, home, { depth: 1 }, function(err, childrenArg) {
507 children = childrenArg;
508 assert(children.length === 4);
509 done();
510 });
511 });
512 it('people is now the final child of home', function(done) {
513 assert(children[3]._id === 'people');
514 return done();
515 });
516 it('slug of people is now /people', function(done) {
517 assert(children[3].slug === '/people');
518 return done();
519 });
520 });
521
522 describe('move home/people back under home/about as first child', function() {
523 var people;
524 it('people exists', function(done) {
525 people = children[3];
526 assert(people._id === 'people');
527 done();
528 });
529 it('moved without error', function(done) {
530 pages.move(req, people, '/about', 'inside', function(err) {
531 if (err) {
532 console.log(err);
533 }
534 assert(!err);
535 return done();
536 });
537 });
538 it('home/about has 3 descendants', function(done) {
539 pages.getDescendants(req, about, { depth: 1 }, function(err, childrenArg) {
540 children = childrenArg;
541 assert(children.length === 3);
542 done();
543 });
544 });
545 it('first child of home/about is now people', function(done) {
546 assert(children[0]._id === 'people');
547 return done();
548 });
549 it('people is at /about/people', function(done) {
550 assert(children[0].slug === '/about/people');
551 return done();
552 });
553 });
554
555 describe('move home/about under home/contact, by slug', function() {
556 var location;
557 it('moved without error', function(done) {
558 pages.move(req, '/about', '/contact', 'inside', function(err) {
559 if (err) {
560 console.log(err);
561 }
562 assert(!err);
563 return done();
564 });
565 });
566 it('got contact', function(done) {
567 apos.pages.findOne({ slug: '/contact' }, function(err, page) {
568 contact = page;
569 assert(page);
570 return done();
571 });
572 });
573 it('home/contact has 1 child', function(done) {
574 pages.getDescendants(req, contact, { depth: 2 }, function(err, childrenArg) {
575 children = childrenArg;
576 assert(children.length === 1);
577 done();
578 });
579 });
580 it('home/contact/about/location exists at the right path', function(done) {
581 apos.pages.findOne({ _id: 'location', path: 'home/contact/about/location' }, function(err, page) {
582 location = page;
583 assert(location);
584 return done();
585 });
586 });
587 it('home/contact/about/location has level 3', function(done) {
588 assert(location.level === 3);
589 return done();
590 });
591 it('home/contact/about/location has slug /contact/about/location', function(done) {
592 assert(location.slug === '/contact/about/location');
593 return done();
594 });
595 });
596
597 describe('fetch pages by tag', function() {
598 var fetched;
599 it('fetched without error', function(done) {
600 pages.getByTag(req, 'green', function(err, fetchedArg) {
601 if (err) {
602 console.log(err);
603 }
604 assert(!err);
605 fetched = fetchedArg.pages;
606 return done();
607 });
608 });
609 it('fetched three pages', function(done) {
610 assert(fetched.length === 3);
611 return done();
612 });
613 it('first one must be about due to title order', function(done) {
614 assert(fetched[0]._id === 'about');
615 return done();
616 });
617 it('filterByTag returns only contact for "red"', function(done) {
618 var filtered = pages.filterByTag(fetched, 'red');
619 assert(filtered.length === 1);
620 assert(filtered[0]._id === 'contact');
621 return done();
622 });
623 });
624
625 describe('add page', function() {
626 it('adds a new page beneath /contact called /contact/new-kid', function(done) {
627 var req = {
628 user: {
629 permissions: {
630 admin: true
631 }
632 },
633 body: {
634 parent: '/contact',
635 title: 'New Kid',
636 published: true,
637 tags: [ 'one', 'two' ],
638 type: 'default',
639 body: {
640 type: 'area',
641 items: [
642 {
643 type: 'richText',
644 content: 'This is a test'
645 }
646 ]
647 }
648 }
649 };
650 var res = {
651 send: function(data) {
652 assert((!res.statusCode) || (res.statusCode === 200));
653 var page = JSON.parse(data);
654 assert(page.body.items.length > 0);
655 assert(typeof(page) === 'object');
656 assert(page.slug === '/contact/new-kid');
657 return apos.getPage(req, '/contact', function(err, page) {
658 assert(!err);
659 assert(page);
660 assert(page.slug === '/contact');
661 return pages.getDescendants(apos.getTaskReq(), page, { depth: 2 }, function(err, children) {
662 assert(children.length === 2);
663 assert(children[0].slug === '/contact/about');
664 assert(children[1].slug === '/contact/new-kid');
665 assert(children[1].path === 'home/contact/new-kid');
666 return done();
667 });
668 });
669 }
670 };
671 return pages._newRoute(req, res);
672 });
673 });
674
675 describe('edit page settings', function() {
676 it('propagates slug changes to children properly', function(done) {
677 var req = {
678 user: {
679 permissions: {
680 admin: true
681 }
682 },
683 body: {
684 originalSlug: '/contact/about',
685 slug: '/contact/about2',
686 title: 'About2',
687 published: true,
688 tags: [ 'one', 'two' ],
689 type: 'default'
690 }
691 };
692 var res = {
693 send: function(data) {
694 assert((!res.statusCode) || (res.statusCode === 200));
695 var page = JSON.parse(data);
696 assert(typeof(page) === 'object');
697 assert(page.slug === '/contact/about2');
698 return pages.getDescendants(apos.getTaskReq(), page, { depth: 2 }, function(err, childrenArg) {
699 children = childrenArg;
700 assert(!err);
701 assert(children.length === 3);
702 assert(children[0]._id === 'people');
703 assert(children[0].slug === '/contact/about2/people');
704 assert(children[1].slug === '/contact/about2/location');
705 assert(children[2].slug === '/contact/about2/friends');
706 return done();
707 });
708 }
709 };
710 return pages._editRoute(req, res);
711 });
712 it('retains children when avoiding a duplicate slug error', function(done) {
713 var req = {
714 user: {
715 permissions: {
716 admin: true
717 }
718 },
719 body: {
720 originalSlug: '/contact/about2',
721 slug: '/contact/new-kid',
722 title: 'About2',
723 published: true,
724 tags: [ 'one', 'two' ],
725 type: 'default'
726 }
727 };
728 var res = {
729 send: function(data) {
730 assert((!res.statusCode) || (res.statusCode === 200));
731 var page = JSON.parse(data);
732 assert(typeof(page) === 'object');
733 assert(page.slug.match(/^\/contact\/new\-kid\d$/));
734 var baseSlug = page.slug;
735 return pages.getDescendants(apos.getTaskReq(), page, { depth: 2 }, function(err, childrenArg) {
736 children = childrenArg;
737 assert(!err);
738 assert(children.length === 3);
739 assert(children[0]._id === 'people');
740 assert(children[0].slug === baseSlug + '/people');
741 assert(children[1].slug === baseSlug + '/location');
742 assert(children[2].slug === baseSlug + '/friends');
743 return done();
744 });
745 }
746 };
747 return pages._editRoute(req, res);
748 }); });
749});
750