1 | var assert = require('assert');
|
2 | var mongo = require('mongodb');
|
3 | var _ = require('lodash');
|
4 | var apos = require('apostrophe')();
|
5 |
|
6 | var db;
|
7 |
|
8 | var pages;
|
9 |
|
10 | var home;
|
11 |
|
12 | var page;
|
13 |
|
14 | var children;
|
15 |
|
16 | var about;
|
17 |
|
18 | var contact;
|
19 |
|
20 | var req = apos.getTaskReq();
|
21 |
|
22 |
|
23 |
|
24 | describe('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 |
|
31 |
|
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 |
|
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 |
|
225 |
|
226 |
|
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 |
|