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