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