]> BookStack Code Mirror - bookstack/blob - tests/Permissions/EntityPermissionsTest.php
8dc112e57d8f8182775c4bcc8d60ff3a65e43b12
[bookstack] / tests / Permissions / EntityPermissionsTest.php
1 <?php namespace Tests\Permissions;
2
3 use BookStack\Entities\Models\Book;
4 use BookStack\Entities\Models\Bookshelf;
5 use BookStack\Entities\Models\Chapter;
6 use BookStack\Entities\Models\Entity;
7 use BookStack\Auth\User;
8 use BookStack\Entities\Models\Page;
9 use Illuminate\Support\Str;
10 use Tests\BrowserKitTest;
11
12 class EntityPermissionsTest extends BrowserKitTest
13 {
14
15     /**
16      * @var User
17      */
18     protected $user;
19
20     /**
21      * @var User
22      */
23     protected $viewer;
24
25     public function setUp(): void
26     {
27         parent::setUp();
28         $this->user = $this->getEditor();
29         $this->viewer = $this->getViewer();
30     }
31
32     protected function setRestrictionsForTestRoles(Entity $entity, array $actions = [])
33     {
34         $roles = [
35             $this->user->roles->first(),
36             $this->viewer->roles->first(),
37         ];
38         $this->setEntityRestrictions($entity, $actions, $roles);
39     }
40
41     public function test_bookshelf_view_restriction()
42     {
43         $shelf = Bookshelf::first();
44
45         $this->actingAs($this->user)
46             ->visit($shelf->getUrl())
47             ->seePageIs($shelf->getUrl());
48
49         $this->setRestrictionsForTestRoles($shelf, []);
50
51         $this->forceVisit($shelf->getUrl())
52             ->see('Bookshelf not found');
53
54         $this->setRestrictionsForTestRoles($shelf, ['view']);
55
56         $this->visit($shelf->getUrl())
57             ->see($shelf->name);
58     }
59
60     public function test_bookshelf_update_restriction()
61     {
62         $shelf = Bookshelf::first();
63
64         $this->actingAs($this->user)
65             ->visit($shelf->getUrl('/edit'))
66             ->see('Edit Book');
67
68         $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']);
69
70         $this->forceVisit($shelf->getUrl('/edit'))
71             ->see('You do not have permission')->seePageIs('/');
72
73         $this->setRestrictionsForTestRoles($shelf, ['view', 'update']);
74
75         $this->visit($shelf->getUrl('/edit'))
76             ->seePageIs($shelf->getUrl('/edit'));
77     }
78
79     public function test_bookshelf_delete_restriction()
80     {
81         $shelf = Book::first();
82
83         $this->actingAs($this->user)
84             ->visit($shelf->getUrl('/delete'))
85             ->see('Delete Book');
86
87         $this->setRestrictionsForTestRoles($shelf, ['view', 'update']);
88
89         $this->forceVisit($shelf->getUrl('/delete'))
90             ->see('You do not have permission')->seePageIs('/');
91
92         $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']);
93
94         $this->visit($shelf->getUrl('/delete'))
95             ->seePageIs($shelf->getUrl('/delete'))->see('Delete Book');
96     }
97
98     public function test_book_view_restriction()
99     {
100         $book = Book::first();
101         $bookPage = $book->pages->first();
102         $bookChapter = $book->chapters->first();
103
104         $bookUrl = $book->getUrl();
105         $this->actingAs($this->user)
106             ->visit($bookUrl)
107             ->seePageIs($bookUrl);
108
109         $this->setRestrictionsForTestRoles($book, []);
110
111         $this->forceVisit($bookUrl)
112             ->see('Book not found');
113         $this->forceVisit($bookPage->getUrl())
114             ->see('Page not found');
115         $this->forceVisit($bookChapter->getUrl())
116             ->see('Chapter not found');
117
118         $this->setRestrictionsForTestRoles($book, ['view']);
119
120         $this->visit($bookUrl)
121             ->see($book->name);
122         $this->visit($bookPage->getUrl())
123             ->see($bookPage->name);
124         $this->visit($bookChapter->getUrl())
125             ->see($bookChapter->name);
126     }
127
128     public function test_book_create_restriction()
129     {
130         $book = Book::first();
131
132         $bookUrl = $book->getUrl();
133         $this->actingAs($this->viewer)
134             ->visit($bookUrl)
135             ->dontSeeInElement('.actions', 'New Page')
136             ->dontSeeInElement('.actions', 'New Chapter');
137         $this->actingAs($this->user)
138             ->visit($bookUrl)
139             ->seeInElement('.actions', 'New Page')
140             ->seeInElement('.actions', 'New Chapter');
141
142         $this->setRestrictionsForTestRoles($book, ['view', 'delete', 'update']);
143
144         $this->forceVisit($bookUrl . '/create-chapter')
145             ->see('You do not have permission')->seePageIs('/');
146         $this->forceVisit($bookUrl . '/create-page')
147             ->see('You do not have permission')->seePageIs('/');
148         $this->visit($bookUrl)->dontSeeInElement('.actions', 'New Page')
149             ->dontSeeInElement('.actions', 'New Chapter');
150
151         $this->setRestrictionsForTestRoles($book, ['view', 'create']);
152
153         $this->visit($bookUrl . '/create-chapter')
154             ->type('test chapter', 'name')
155             ->type('test description for chapter', 'description')
156             ->press('Save Chapter')
157             ->seePageIs($bookUrl . '/chapter/test-chapter');
158         $this->visit($bookUrl . '/create-page')
159             ->type('test page', 'name')
160             ->type('test content', 'html')
161             ->press('Save Page')
162             ->seePageIs($bookUrl . '/page/test-page');
163         $this->visit($bookUrl)->seeInElement('.actions', 'New Page')
164             ->seeInElement('.actions', 'New Chapter');
165     }
166
167     public function test_book_update_restriction()
168     {
169         $book = Book::first();
170         $bookPage = $book->pages->first();
171         $bookChapter = $book->chapters->first();
172
173         $bookUrl = $book->getUrl();
174         $this->actingAs($this->user)
175             ->visit($bookUrl . '/edit')
176             ->see('Edit Book');
177
178         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
179
180         $this->forceVisit($bookUrl . '/edit')
181             ->see('You do not have permission')->seePageIs('/');
182         $this->forceVisit($bookPage->getUrl() . '/edit')
183             ->see('You do not have permission')->seePageIs('/');
184         $this->forceVisit($bookChapter->getUrl() . '/edit')
185             ->see('You do not have permission')->seePageIs('/');
186
187         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
188
189         $this->visit($bookUrl . '/edit')
190             ->seePageIs($bookUrl . '/edit');
191         $this->visit($bookPage->getUrl() . '/edit')
192             ->seePageIs($bookPage->getUrl() . '/edit');
193         $this->visit($bookChapter->getUrl() . '/edit')
194             ->see('Edit Chapter');
195     }
196
197     public function test_book_delete_restriction()
198     {
199         $book = Book::first();
200         $bookPage = $book->pages->first();
201         $bookChapter = $book->chapters->first();
202
203         $bookUrl = $book->getUrl();
204         $this->actingAs($this->user)
205             ->visit($bookUrl . '/delete')
206             ->see('Delete Book');
207
208         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
209
210         $this->forceVisit($bookUrl . '/delete')
211             ->see('You do not have permission')->seePageIs('/');
212         $this->forceVisit($bookPage->getUrl() . '/delete')
213             ->see('You do not have permission')->seePageIs('/');
214         $this->forceVisit($bookChapter->getUrl() . '/delete')
215             ->see('You do not have permission')->seePageIs('/');
216
217         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
218
219         $this->visit($bookUrl . '/delete')
220             ->seePageIs($bookUrl . '/delete')->see('Delete Book');
221         $this->visit($bookPage->getUrl() . '/delete')
222             ->seePageIs($bookPage->getUrl() . '/delete')->see('Delete Page');
223         $this->visit($bookChapter->getUrl() . '/delete')
224             ->see('Delete Chapter');
225     }
226
227     public function test_chapter_view_restriction()
228     {
229         $chapter = Chapter::first();
230         $chapterPage = $chapter->pages->first();
231
232         $chapterUrl = $chapter->getUrl();
233         $this->actingAs($this->user)
234             ->visit($chapterUrl)
235             ->seePageIs($chapterUrl);
236
237         $this->setRestrictionsForTestRoles($chapter, []);
238
239         $this->forceVisit($chapterUrl)
240             ->see('Chapter not found');
241         $this->forceVisit($chapterPage->getUrl())
242             ->see('Page not found');
243
244         $this->setRestrictionsForTestRoles($chapter, ['view']);
245
246         $this->visit($chapterUrl)
247             ->see($chapter->name);
248         $this->visit($chapterPage->getUrl())
249             ->see($chapterPage->name);
250     }
251
252     public function test_chapter_create_restriction()
253     {
254         $chapter = Chapter::first();
255
256         $chapterUrl = $chapter->getUrl();
257         $this->actingAs($this->user)
258             ->visit($chapterUrl)
259             ->seeInElement('.actions', 'New Page');
260
261         $this->setRestrictionsForTestRoles($chapter, ['view', 'delete', 'update']);
262
263         $this->forceVisit($chapterUrl . '/create-page')
264             ->see('You do not have permission')->seePageIs('/');
265         $this->visit($chapterUrl)->dontSeeInElement('.actions', 'New Page');
266
267         $this->setRestrictionsForTestRoles($chapter, ['view', 'create']);
268
269
270         $this->visit($chapterUrl . '/create-page')
271             ->type('test page', 'name')
272             ->type('test content', 'html')
273             ->press('Save Page')
274             ->seePageIs($chapter->book->getUrl() . '/page/test-page');
275
276         $this->visit($chapterUrl)->seeInElement('.actions', 'New Page');
277     }
278
279     public function test_chapter_update_restriction()
280     {
281         $chapter = Chapter::first();
282         $chapterPage = $chapter->pages->first();
283
284         $chapterUrl = $chapter->getUrl();
285         $this->actingAs($this->user)
286             ->visit($chapterUrl . '/edit')
287             ->see('Edit Chapter');
288
289         $this->setRestrictionsForTestRoles($chapter, ['view', 'delete']);
290
291         $this->forceVisit($chapterUrl . '/edit')
292             ->see('You do not have permission')->seePageIs('/');
293         $this->forceVisit($chapterPage->getUrl() . '/edit')
294             ->see('You do not have permission')->seePageIs('/');
295
296         $this->setRestrictionsForTestRoles($chapter, ['view', 'update']);
297
298         $this->visit($chapterUrl . '/edit')
299             ->seePageIs($chapterUrl . '/edit')->see('Edit Chapter');
300         $this->visit($chapterPage->getUrl() . '/edit')
301             ->seePageIs($chapterPage->getUrl() . '/edit');
302     }
303
304     public function test_chapter_delete_restriction()
305     {
306         $chapter = Chapter::first();
307         $chapterPage = $chapter->pages->first();
308
309         $chapterUrl = $chapter->getUrl();
310         $this->actingAs($this->user)
311             ->visit($chapterUrl . '/delete')
312             ->see('Delete Chapter');
313
314         $this->setRestrictionsForTestRoles($chapter, ['view', 'update']);
315
316         $this->forceVisit($chapterUrl . '/delete')
317             ->see('You do not have permission')->seePageIs('/');
318         $this->forceVisit($chapterPage->getUrl() . '/delete')
319             ->see('You do not have permission')->seePageIs('/');
320
321         $this->setRestrictionsForTestRoles($chapter, ['view', 'delete']);
322
323         $this->visit($chapterUrl . '/delete')
324             ->seePageIs($chapterUrl . '/delete')->see('Delete Chapter');
325         $this->visit($chapterPage->getUrl() . '/delete')
326             ->seePageIs($chapterPage->getUrl() . '/delete')->see('Delete Page');
327     }
328
329     public function test_page_view_restriction()
330     {
331         $page = Page::first();
332
333         $pageUrl = $page->getUrl();
334         $this->actingAs($this->user)
335             ->visit($pageUrl)
336             ->seePageIs($pageUrl);
337
338         $this->setRestrictionsForTestRoles($page, ['update', 'delete']);
339
340         $this->forceVisit($pageUrl)
341             ->see('Page not found');
342
343         $this->setRestrictionsForTestRoles($page, ['view']);
344
345         $this->visit($pageUrl)
346             ->see($page->name);
347     }
348
349     public function test_page_update_restriction()
350     {
351         $page = Chapter::first();
352
353         $pageUrl = $page->getUrl();
354         $this->actingAs($this->user)
355             ->visit($pageUrl . '/edit')
356             ->seeInField('name', $page->name);
357
358         $this->setRestrictionsForTestRoles($page, ['view', 'delete']);
359
360         $this->forceVisit($pageUrl . '/edit')
361             ->see('You do not have permission')->seePageIs('/');
362
363         $this->setRestrictionsForTestRoles($page, ['view', 'update']);
364
365         $this->visit($pageUrl . '/edit')
366             ->seePageIs($pageUrl . '/edit')->seeInField('name', $page->name);
367     }
368
369     public function test_page_delete_restriction()
370     {
371         $page = Page::first();
372
373         $pageUrl = $page->getUrl();
374         $this->actingAs($this->user)
375             ->visit($pageUrl . '/delete')
376             ->see('Delete Page');
377
378         $this->setRestrictionsForTestRoles($page, ['view', 'update']);
379
380         $this->forceVisit($pageUrl . '/delete')
381             ->see('You do not have permission')->seePageIs('/');
382
383         $this->setRestrictionsForTestRoles($page, ['view', 'delete']);
384
385         $this->visit($pageUrl . '/delete')
386             ->seePageIs($pageUrl . '/delete')->see('Delete Page');
387     }
388
389     public function test_bookshelf_restriction_form()
390     {
391         $shelf = Bookshelf::first();
392         $this->asAdmin()->visit($shelf->getUrl('/permissions'))
393             ->see('Bookshelf Permissions')
394             ->check('restricted')
395             ->check('restrictions[2][view]')
396             ->press('Save Permissions')
397             ->seeInDatabase('bookshelves', ['id' => $shelf->id, 'restricted' => true])
398             ->seeInDatabase('entity_permissions', [
399                 'restrictable_id' => $shelf->id,
400                 'restrictable_type' => Bookshelf::newModelInstance()->getMorphClass(),
401                 'role_id' => '2',
402                 'action' => 'view'
403             ]);
404     }
405
406     public function test_book_restriction_form()
407     {
408         $book = Book::first();
409         $this->asAdmin()->visit($book->getUrl() . '/permissions')
410             ->see('Book Permissions')
411             ->check('restricted')
412             ->check('restrictions[2][view]')
413             ->press('Save Permissions')
414             ->seeInDatabase('books', ['id' => $book->id, 'restricted' => true])
415             ->seeInDatabase('entity_permissions', [
416                 'restrictable_id' => $book->id,
417                 'restrictable_type' => Book::newModelInstance()->getMorphClass(),
418                 'role_id' => '2',
419                 'action' => 'view'
420             ]);
421     }
422
423     public function test_chapter_restriction_form()
424     {
425         $chapter = Chapter::first();
426         $this->asAdmin()->visit($chapter->getUrl() . '/permissions')
427             ->see('Chapter Permissions')
428             ->check('restricted')
429             ->check('restrictions[2][update]')
430             ->press('Save Permissions')
431             ->seeInDatabase('chapters', ['id' => $chapter->id, 'restricted' => true])
432             ->seeInDatabase('entity_permissions', [
433                 'restrictable_id' => $chapter->id,
434                 'restrictable_type' => Chapter::newModelInstance()->getMorphClass(),
435                 'role_id' => '2',
436                 'action' => 'update'
437             ]);
438     }
439
440     public function test_page_restriction_form()
441     {
442         $page = Page::first();
443         $this->asAdmin()->visit($page->getUrl() . '/permissions')
444             ->see('Page Permissions')
445             ->check('restricted')
446             ->check('restrictions[2][delete]')
447             ->press('Save Permissions')
448             ->seeInDatabase('pages', ['id' => $page->id, 'restricted' => true])
449             ->seeInDatabase('entity_permissions', [
450                 'restrictable_id' => $page->id,
451                 'restrictable_type' => Page::newModelInstance()->getMorphClass(),
452                 'role_id' => '2',
453                 'action' => 'delete'
454             ]);
455     }
456
457     public function test_restricted_pages_not_visible_in_book_navigation_on_pages()
458     {
459         $chapter = Chapter::first();
460         $page = $chapter->pages->first();
461         $page2 = $chapter->pages[2];
462
463         $this->setRestrictionsForTestRoles($page, []);
464
465         $this->actingAs($this->user)
466             ->visit($page2->getUrl())
467             ->dontSeeInElement('.sidebar-page-list', $page->name);
468     }
469
470     public function test_restricted_pages_not_visible_in_book_navigation_on_chapters()
471     {
472         $chapter = Chapter::first();
473         $page = $chapter->pages->first();
474
475         $this->setRestrictionsForTestRoles($page, []);
476
477         $this->actingAs($this->user)
478             ->visit($chapter->getUrl())
479             ->dontSeeInElement('.sidebar-page-list', $page->name);
480     }
481
482     public function test_restricted_pages_not_visible_on_chapter_pages()
483     {
484         $chapter = Chapter::first();
485         $page = $chapter->pages->first();
486
487         $this->setRestrictionsForTestRoles($page, []);
488
489         $this->actingAs($this->user)
490             ->visit($chapter->getUrl())
491             ->dontSee($page->name);
492     }
493
494     public function test_restricted_chapter_pages_not_visible_on_book_page()
495     {
496         $chapter = Chapter::query()->first();
497         $this->actingAs($this->user)
498             ->visit($chapter->book->getUrl())
499             ->see($chapter->pages->first()->name);
500
501         foreach ($chapter->pages as $page) {
502             $this->setRestrictionsForTestRoles($page, []);
503         }
504
505         $this->actingAs($this->user)
506             ->visit($chapter->book->getUrl())
507             ->dontSee($chapter->pages->first()->name);
508     }
509
510     public function test_bookshelf_update_restriction_override()
511     {
512         $shelf = Bookshelf::first();
513
514         $this->actingAs($this->viewer)
515             ->visit($shelf->getUrl('/edit'))
516             ->dontSee('Edit Book');
517
518         $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']);
519
520         $this->forceVisit($shelf->getUrl('/edit'))
521             ->see('You do not have permission')->seePageIs('/');
522
523         $this->setRestrictionsForTestRoles($shelf, ['view', 'update']);
524
525         $this->visit($shelf->getUrl('/edit'))
526             ->seePageIs($shelf->getUrl('/edit'));
527     }
528
529     public function test_bookshelf_delete_restriction_override()
530     {
531         $shelf = Bookshelf::first();
532
533         $this->actingAs($this->viewer)
534             ->visit($shelf->getUrl('/delete'))
535             ->dontSee('Delete Book');
536
537         $this->setRestrictionsForTestRoles($shelf, ['view', 'update']);
538
539         $this->forceVisit($shelf->getUrl('/delete'))
540             ->see('You do not have permission')->seePageIs('/');
541
542         $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']);
543
544         $this->visit($shelf->getUrl('/delete'))
545             ->seePageIs($shelf->getUrl('/delete'))->see('Delete Book');
546     }
547
548     public function test_book_create_restriction_override()
549     {
550         $book = Book::first();
551
552         $bookUrl = $book->getUrl();
553         $this->actingAs($this->viewer)
554             ->visit($bookUrl)
555             ->dontSeeInElement('.actions', 'New Page')
556             ->dontSeeInElement('.actions', 'New Chapter');
557
558         $this->setRestrictionsForTestRoles($book, ['view', 'delete', 'update']);
559
560         $this->forceVisit($bookUrl . '/create-chapter')
561             ->see('You do not have permission')->seePageIs('/');
562         $this->forceVisit($bookUrl . '/create-page')
563             ->see('You do not have permission')->seePageIs('/');
564         $this->visit($bookUrl)->dontSeeInElement('.actions', 'New Page')
565             ->dontSeeInElement('.actions', 'New Chapter');
566
567         $this->setRestrictionsForTestRoles($book, ['view', 'create']);
568
569         $this->visit($bookUrl . '/create-chapter')
570             ->type('test chapter', 'name')
571             ->type('test description for chapter', 'description')
572             ->press('Save Chapter')
573             ->seePageIs($bookUrl . '/chapter/test-chapter');
574         $this->visit($bookUrl . '/create-page')
575             ->type('test page', 'name')
576             ->type('test content', 'html')
577             ->press('Save Page')
578             ->seePageIs($bookUrl . '/page/test-page');
579         $this->visit($bookUrl)->seeInElement('.actions', 'New Page')
580             ->seeInElement('.actions', 'New Chapter');
581     }
582
583     public function test_book_update_restriction_override()
584     {
585         $book = Book::first();
586         $bookPage = $book->pages->first();
587         $bookChapter = $book->chapters->first();
588
589         $bookUrl = $book->getUrl();
590         $this->actingAs($this->viewer)
591             ->visit($bookUrl . '/edit')
592             ->dontSee('Edit Book');
593
594         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
595
596         $this->forceVisit($bookUrl . '/edit')
597             ->see('You do not have permission')->seePageIs('/');
598         $this->forceVisit($bookPage->getUrl() . '/edit')
599             ->see('You do not have permission')->seePageIs('/');
600         $this->forceVisit($bookChapter->getUrl() . '/edit')
601             ->see('You do not have permission')->seePageIs('/');
602
603         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
604
605         $this->visit($bookUrl . '/edit')
606             ->seePageIs($bookUrl . '/edit');
607         $this->visit($bookPage->getUrl() . '/edit')
608             ->seePageIs($bookPage->getUrl() . '/edit');
609         $this->visit($bookChapter->getUrl() . '/edit')
610             ->see('Edit Chapter');
611     }
612
613     public function test_book_delete_restriction_override()
614     {
615         $book = Book::first();
616         $bookPage = $book->pages->first();
617         $bookChapter = $book->chapters->first();
618
619         $bookUrl = $book->getUrl();
620         $this->actingAs($this->viewer)
621             ->visit($bookUrl . '/delete')
622             ->dontSee('Delete Book');
623
624         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
625
626         $this->forceVisit($bookUrl . '/delete')
627             ->see('You do not have permission')->seePageIs('/');
628         $this->forceVisit($bookPage->getUrl() . '/delete')
629             ->see('You do not have permission')->seePageIs('/');
630         $this->forceVisit($bookChapter->getUrl() . '/delete')
631             ->see('You do not have permission')->seePageIs('/');
632
633         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
634
635         $this->visit($bookUrl . '/delete')
636             ->seePageIs($bookUrl . '/delete')->see('Delete Book');
637         $this->visit($bookPage->getUrl() . '/delete')
638             ->seePageIs($bookPage->getUrl() . '/delete')->see('Delete Page');
639         $this->visit($bookChapter->getUrl() . '/delete')
640             ->see('Delete Chapter');
641     }
642
643     public function test_page_visible_if_has_permissions_when_book_not_visible()
644     {
645         $book = Book::first();
646         $bookChapter = $book->chapters->first();
647         $bookPage = $bookChapter->pages->first();
648
649         foreach ([$book, $bookChapter, $bookPage] as $entity) {
650             $entity->name = Str::random(24);
651             $entity->save();
652         }
653
654         $this->setRestrictionsForTestRoles($book, []);
655         $this->setRestrictionsForTestRoles($bookPage, ['view']);
656
657         $this->actingAs($this->viewer);
658         $this->get($bookPage->getUrl());
659         $this->assertResponseOk();
660         $this->see($bookPage->name);
661         $this->dontSee(substr($book->name, 0, 15));
662         $this->dontSee(substr($bookChapter->name, 0, 15));
663     }
664
665     public function test_book_sort_view_permission()
666     {
667         $firstBook = Book::first();
668         $secondBook = Book::find(2);
669
670         $this->setRestrictionsForTestRoles($firstBook, ['view', 'update']);
671         $this->setRestrictionsForTestRoles($secondBook, ['view']);
672
673         // Test sort page visibility
674         $this->actingAs($this->user)->visit($secondBook->getUrl() . '/sort')
675                 ->see('You do not have permission')
676                 ->seePageIs('/');
677
678         // Check sort page on first book
679         $this->actingAs($this->user)->visit($firstBook->getUrl() . '/sort');
680     }
681
682     public function test_book_sort_permission() {
683         $firstBook = Book::first();
684         $secondBook = Book::find(2);
685
686         $this->setRestrictionsForTestRoles($firstBook, ['view', 'update']);
687         $this->setRestrictionsForTestRoles($secondBook, ['view']);
688
689         $firstBookChapter = $this->newChapter(['name' => 'first book chapter'], $firstBook);
690         $secondBookChapter = $this->newChapter(['name' => 'second book chapter'], $secondBook);
691
692         // Create request data
693         $reqData = [
694             [
695                 'id' => $firstBookChapter->id,
696                 'sort' => 0,
697                 'parentChapter' => false,
698                 'type' => 'chapter',
699                 'book' => $secondBook->id
700             ]
701         ];
702
703         // Move chapter from first book to a second book
704         $this->actingAs($this->user)->put($firstBook->getUrl() . '/sort', ['sort-tree' => json_encode($reqData)])
705                 ->followRedirects()
706                 ->see('You do not have permission')
707                 ->seePageIs('/');
708
709         $reqData = [
710             [
711                 'id' => $secondBookChapter->id,
712                 'sort' => 0,
713                 'parentChapter' => false,
714                 'type' => 'chapter',
715                 'book' => $firstBook->id
716             ]
717         ];
718
719         // Move chapter from second book to first book
720         $this->actingAs($this->user)->put($firstBook->getUrl() . '/sort', ['sort-tree' => json_encode($reqData)])
721                 ->followRedirects()
722                 ->see('You do not have permission')
723                 ->seePageIs('/');
724     }
725
726     public function test_can_create_page_if_chapter_has_permissions_when_book_not_visible()
727     {
728         $book = Book::first();
729         $this->setRestrictionsForTestRoles($book, []);
730         $bookChapter = $book->chapters->first();
731         $this->setRestrictionsForTestRoles($bookChapter, ['view']);
732
733         $this->actingAs($this->user)->visit($bookChapter->getUrl())
734             ->dontSee('New Page');
735
736         $this->setRestrictionsForTestRoles($bookChapter, ['view', 'create']);
737
738         $this->actingAs($this->user)->visit($bookChapter->getUrl())
739             ->click('New Page')
740             ->seeStatusCode(200)
741             ->type('test page', 'name')
742             ->type('test content', 'html')
743             ->press('Save Page')
744             ->seePageIs($book->getUrl('/page/test-page'))
745             ->seeStatusCode(200);
746     }
747 }