]> BookStack Code Mirror - bookstack/blob - tests/Permissions/EntityPermissionsTest.php
Updated tests to use ssddanbrown/asserthtml package
[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     protected 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         $resp = $this->actingAs($this->viewer)->get($bookUrl);
142         $this->withHtml($resp)->assertElementNotContains('.actions', 'New Page')
143             ->assertElementNotContains('.actions', 'New Chapter');
144         $resp = $this->actingAs($this->user)->get($bookUrl);
145         $this->withHtml($resp)->assertElementContains('.actions', 'New Page')
146             ->assertElementContains('.actions', 'New Chapter');
147
148         $this->setRestrictionsForTestRoles($book, ['view', 'delete', 'update']);
149
150         $this->get($bookUrl . '/create-chapter')->assertRedirect('/');
151         $this->get('/')->assertSee('You do not have permission');
152
153         $this->get($bookUrl . '/create-page')->assertRedirect('/');
154         $this->get('/')->assertSee('You do not have permission');
155
156         $resp = $this->get($bookUrl);
157         $this->withHtml($resp)->assertElementNotContains('.actions', 'New Page')
158             ->assertElementNotContains('.actions', 'New Chapter');
159
160         $this->setRestrictionsForTestRoles($book, ['view', 'create']);
161
162         $resp = $this->post($book->getUrl('/create-chapter'), [
163             'name'        => 'test chapter',
164             'description' => 'desc',
165         ]);
166         $resp->assertRedirect($book->getUrl('/chapter/test-chapter'));
167
168         $this->get($book->getUrl('/create-page'));
169         /** @var Page $page */
170         $page = Page::query()->where('draft', '=', true)->orderBy('id', 'desc')->first();
171         $resp = $this->post($page->getUrl(), [
172             'name' => 'test page',
173             'html' => 'test content',
174         ]);
175         $resp->assertRedirect($book->getUrl('/page/test-page'));
176
177         $resp = $this->get($bookUrl);
178         $this->withHtml($resp)->assertElementContains('.actions', 'New Page')
179             ->assertElementContains('.actions', 'New Chapter');
180     }
181
182     public function test_book_update_restriction()
183     {
184         /** @var Book $book */
185         $book = Book::query()->first();
186         $bookPage = $book->pages->first();
187         $bookChapter = $book->chapters->first();
188
189         $bookUrl = $book->getUrl();
190         $this->actingAs($this->user)
191             ->get($bookUrl . '/edit')
192             ->assertSee('Edit Book');
193
194         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
195
196         $this->get($bookUrl . '/edit')->assertRedirect('/');
197         $this->get('/')->assertSee('You do not have permission');
198         $this->get($bookPage->getUrl() . '/edit')->assertRedirect('/');
199         $this->get('/')->assertSee('You do not have permission');
200         $this->get($bookChapter->getUrl() . '/edit')->assertRedirect('/');
201         $this->get('/')->assertSee('You do not have permission');
202
203         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
204
205         $this->get($bookUrl . '/edit')->assertOk();
206         $this->get($bookPage->getUrl() . '/edit')->assertOk();
207         $this->get($bookChapter->getUrl() . '/edit')->assertSee('Edit Chapter');
208     }
209
210     public function test_book_delete_restriction()
211     {
212         /** @var Book $book */
213         $book = Book::query()->first();
214         $bookPage = $book->pages->first();
215         $bookChapter = $book->chapters->first();
216
217         $bookUrl = $book->getUrl();
218         $this->actingAs($this->user)->get($bookUrl . '/delete')
219             ->assertSee('Delete Book');
220
221         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
222
223         $this->get($bookUrl . '/delete')->assertRedirect('/');
224         $this->get('/')->assertSee('You do not have permission');
225         $this->get($bookPage->getUrl() . '/delete')->assertRedirect('/');
226         $this->get('/')->assertSee('You do not have permission');
227         $this->get($bookChapter->getUrl() . '/delete')->assertRedirect('/');
228         $this->get('/')->assertSee('You do not have permission');
229
230         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
231
232         $this->get($bookUrl . '/delete')->assertOk()->assertSee('Delete Book');
233         $this->get($bookPage->getUrl('/delete'))->assertOk()->assertSee('Delete Page');
234         $this->get($bookChapter->getUrl('/delete'))->assertSee('Delete Chapter');
235     }
236
237     public function test_chapter_view_restriction()
238     {
239         /** @var Chapter $chapter */
240         $chapter = Chapter::query()->first();
241         $chapterPage = $chapter->pages->first();
242
243         $chapterUrl = $chapter->getUrl();
244         $this->actingAs($this->user)->get($chapterUrl)->assertOk();
245
246         $this->setRestrictionsForTestRoles($chapter, []);
247
248         $this->followingRedirects()->get($chapterUrl)->assertSee('Chapter not found');
249         $this->followingRedirects()->get($chapterPage->getUrl())->assertSee('Page not found');
250
251         $this->setRestrictionsForTestRoles($chapter, ['view']);
252
253         $this->get($chapterUrl)->assertSee($chapter->name);
254         $this->get($chapterPage->getUrl())->assertSee($chapterPage->name);
255     }
256
257     public function test_chapter_create_restriction()
258     {
259         /** @var Chapter $chapter */
260         $chapter = Chapter::query()->first();
261
262         $chapterUrl = $chapter->getUrl();
263         $resp = $this->actingAs($this->user)->get($chapterUrl);
264         $this->withHtml($resp)->assertElementContains('.actions', 'New Page');
265
266         $this->setRestrictionsForTestRoles($chapter, ['view', 'delete', 'update']);
267
268         $this->get($chapterUrl . '/create-page')->assertRedirect('/');
269         $this->get('/')->assertSee('You do not have permission');
270         $this->withHtml($this->get($chapterUrl))->assertElementNotContains('.actions', 'New Page');
271
272         $this->setRestrictionsForTestRoles($chapter, ['view', 'create']);
273
274         $this->get($chapter->getUrl('/create-page'));
275         /** @var Page $page */
276         $page = Page::query()->where('draft', '=', true)->orderBy('id', 'desc')->first();
277         $resp = $this->post($page->getUrl(), [
278             'name' => 'test page',
279             'html' => 'test content',
280         ]);
281         $resp->assertRedirect($chapter->book->getUrl('/page/test-page'));
282
283         $this->withHtml($this->get($chapterUrl))->assertElementContains('.actions', 'New Page');
284     }
285
286     public function test_chapter_update_restriction()
287     {
288         /** @var Chapter $chapter */
289         $chapter = Chapter::query()->first();
290         $chapterPage = $chapter->pages->first();
291
292         $chapterUrl = $chapter->getUrl();
293         $this->actingAs($this->user)->get($chapterUrl . '/edit')
294             ->assertSee('Edit Chapter');
295
296         $this->setRestrictionsForTestRoles($chapter, ['view', 'delete']);
297
298         $this->get($chapterUrl . '/edit')->assertRedirect('/');
299         $this->get('/')->assertSee('You do not have permission');
300         $this->get($chapterPage->getUrl() . '/edit')->assertRedirect('/');
301         $this->get('/')->assertSee('You do not have permission');
302
303         $this->setRestrictionsForTestRoles($chapter, ['view', 'update']);
304
305         $this->get($chapterUrl . '/edit')->assertOk()->assertSee('Edit Chapter');
306         $this->get($chapterPage->getUrl() . '/edit')->assertOk();
307     }
308
309     public function test_chapter_delete_restriction()
310     {
311         /** @var Chapter $chapter */
312         $chapter = Chapter::query()->first();
313         $chapterPage = $chapter->pages->first();
314
315         $chapterUrl = $chapter->getUrl();
316         $this->actingAs($this->user)
317             ->get($chapterUrl . '/delete')
318             ->assertSee('Delete Chapter');
319
320         $this->setRestrictionsForTestRoles($chapter, ['view', 'update']);
321
322         $this->get($chapterUrl . '/delete')->assertRedirect('/');
323         $this->get('/')->assertSee('You do not have permission');
324         $this->get($chapterPage->getUrl() . '/delete')->assertRedirect('/');
325         $this->get('/')->assertSee('You do not have permission');
326
327         $this->setRestrictionsForTestRoles($chapter, ['view', 'delete']);
328
329         $this->get($chapterUrl . '/delete')->assertOk()->assertSee('Delete Chapter');
330         $this->get($chapterPage->getUrl() . '/delete')->assertOk()->assertSee('Delete Page');
331     }
332
333     public function test_page_view_restriction()
334     {
335         /** @var Page $page */
336         $page = Page::query()->first();
337
338         $pageUrl = $page->getUrl();
339         $this->actingAs($this->user)->get($pageUrl)->assertOk();
340
341         $this->setRestrictionsForTestRoles($page, ['update', 'delete']);
342
343         $this->get($pageUrl)->assertSee('Page not found');
344
345         $this->setRestrictionsForTestRoles($page, ['view']);
346
347         $this->get($pageUrl)->assertSee($page->name);
348     }
349
350     public function test_page_update_restriction()
351     {
352         /** @var Page $page */
353         $page = Page::query()->first();
354
355         $pageUrl = $page->getUrl();
356         $resp = $this->actingAs($this->user)
357             ->get($pageUrl . '/edit');
358         $this->withHtml($resp)->assertElementExists('input[name="name"][value="' . $page->name . '"]');
359
360         $this->setRestrictionsForTestRoles($page, ['view', 'delete']);
361
362         $this->get($pageUrl . '/edit')->assertRedirect('/');
363         $this->get('/')->assertSee('You do not have permission');
364
365         $this->setRestrictionsForTestRoles($page, ['view', 'update']);
366
367         $resp = $this->get($pageUrl . '/edit')
368             ->assertOk();
369         $this->withHtml($resp)->assertElementExists('input[name="name"][value="' . $page->name . '"]');
370     }
371
372     public function test_page_delete_restriction()
373     {
374         /** @var Page $page */
375         $page = Page::query()->first();
376
377         $pageUrl = $page->getUrl();
378         $this->actingAs($this->user)
379             ->get($pageUrl . '/delete')
380             ->assertSee('Delete Page');
381
382         $this->setRestrictionsForTestRoles($page, ['view', 'update']);
383
384         $this->get($pageUrl . '/delete')->assertRedirect('/');
385         $this->get('/')->assertSee('You do not have permission');
386
387         $this->setRestrictionsForTestRoles($page, ['view', 'delete']);
388
389         $this->get($pageUrl . '/delete')->assertOk()->assertSee('Delete Page');
390     }
391
392     protected function entityRestrictionFormTest(string $model, string $title, string $permission, string $roleId)
393     {
394         /** @var Entity $modelInstance */
395         $modelInstance = $model::query()->first();
396         $this->asAdmin()->get($modelInstance->getUrl('/permissions'))
397             ->assertSee($title);
398
399         $this->put($modelInstance->getUrl('/permissions'), [
400             'restricted'   => 'true',
401             'restrictions' => [
402                 $roleId => [
403                     $permission => 'true',
404                 ],
405             ],
406         ]);
407
408         $this->assertDatabaseHas($modelInstance->getTable(), ['id' => $modelInstance->id, 'restricted' => true]);
409         $this->assertDatabaseHas('entity_permissions', [
410             'restrictable_id'   => $modelInstance->id,
411             'restrictable_type' => $modelInstance->getMorphClass(),
412             'role_id'           => $roleId,
413             'action'            => $permission,
414         ]);
415     }
416
417     public function test_bookshelf_restriction_form()
418     {
419         $this->entityRestrictionFormTest(Bookshelf::class, 'Bookshelf Permissions', 'view', '2');
420     }
421
422     public function test_book_restriction_form()
423     {
424         $this->entityRestrictionFormTest(Book::class, 'Book Permissions', 'view', '2');
425     }
426
427     public function test_chapter_restriction_form()
428     {
429         $this->entityRestrictionFormTest(Chapter::class, 'Chapter Permissions', 'update', '2');
430     }
431
432     public function test_page_restriction_form()
433     {
434         $this->entityRestrictionFormTest(Page::class, 'Page Permissions', 'delete', '2');
435     }
436
437     public function test_restricted_pages_not_visible_in_book_navigation_on_pages()
438     {
439         /** @var Chapter $chapter */
440         $chapter = Chapter::query()->first();
441         $page = $chapter->pages->first();
442         $page2 = $chapter->pages[2];
443
444         $this->setRestrictionsForTestRoles($page, []);
445
446         $resp = $this->actingAs($this->user)->get($page2->getUrl());
447         $this->withHtml($resp)->assertElementNotContains('.sidebar-page-list', $page->name);
448     }
449
450     public function test_restricted_pages_not_visible_in_book_navigation_on_chapters()
451     {
452         /** @var Chapter $chapter */
453         $chapter = Chapter::query()->first();
454         $page = $chapter->pages->first();
455
456         $this->setRestrictionsForTestRoles($page, []);
457
458         $resp = $this->actingAs($this->user)->get($chapter->getUrl());
459         $this->withHtml($resp)->assertElementNotContains('.sidebar-page-list', $page->name);
460     }
461
462     public function test_restricted_pages_not_visible_on_chapter_pages()
463     {
464         /** @var Chapter $chapter */
465         $chapter = Chapter::query()->first();
466         $page = $chapter->pages->first();
467
468         $this->setRestrictionsForTestRoles($page, []);
469
470         $this->actingAs($this->user)
471             ->get($chapter->getUrl())
472             ->assertDontSee($page->name);
473     }
474
475     public function test_restricted_chapter_pages_not_visible_on_book_page()
476     {
477         /** @var Chapter $chapter */
478         $chapter = Chapter::query()->first();
479         $this->actingAs($this->user)
480             ->get($chapter->book->getUrl())
481             ->assertSee($chapter->pages->first()->name);
482
483         foreach ($chapter->pages as $page) {
484             $this->setRestrictionsForTestRoles($page, []);
485         }
486
487         $this->actingAs($this->user)
488             ->get($chapter->book->getUrl())
489             ->assertDontSee($chapter->pages->first()->name);
490     }
491
492     public function test_bookshelf_update_restriction_override()
493     {
494         /** @var Bookshelf $shelf */
495         $shelf = Bookshelf::query()->first();
496
497         $this->actingAs($this->viewer)
498             ->get($shelf->getUrl('/edit'))
499             ->assertDontSee('Edit Book');
500
501         $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']);
502
503         $this->get($shelf->getUrl('/edit'))->assertRedirect('/');
504         $this->get('/')->assertSee('You do not have permission');
505
506         $this->setRestrictionsForTestRoles($shelf, ['view', 'update']);
507
508         $this->get($shelf->getUrl('/edit'))->assertOk();
509     }
510
511     public function test_bookshelf_delete_restriction_override()
512     {
513         /** @var Bookshelf $shelf */
514         $shelf = Bookshelf::query()->first();
515
516         $this->actingAs($this->viewer)
517             ->get($shelf->getUrl('/delete'))
518             ->assertDontSee('Delete Book');
519
520         $this->setRestrictionsForTestRoles($shelf, ['view', 'update']);
521
522         $this->get($shelf->getUrl('/delete'))->assertRedirect('/');
523         $this->get('/')->assertSee('You do not have permission');
524
525         $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']);
526
527         $this->get($shelf->getUrl('/delete'))->assertOk()->assertSee('Delete Book');
528     }
529
530     public function test_book_create_restriction_override()
531     {
532         /** @var Book $book */
533         $book = Book::query()->first();
534
535         $bookUrl = $book->getUrl();
536         $resp = $this->actingAs($this->viewer)->get($bookUrl);
537         $this->withHtml($resp)->assertElementNotContains('.actions', 'New Page')
538             ->assertElementNotContains('.actions', 'New Chapter');
539
540         $this->setRestrictionsForTestRoles($book, ['view', 'delete', 'update']);
541
542         $this->get($bookUrl . '/create-chapter')->assertRedirect('/');
543         $this->get('/')->assertSee('You do not have permission');
544         $this->get($bookUrl . '/create-page')->assertRedirect('/');
545         $this->get('/')->assertSee('You do not have permission');
546          $resp = $this->get($bookUrl);
547         $this->withHtml($resp)->assertElementNotContains('.actions', 'New Page')
548             ->assertElementNotContains('.actions', 'New Chapter');
549
550         $this->setRestrictionsForTestRoles($book, ['view', 'create']);
551
552         $resp = $this->post($book->getUrl('/create-chapter'), [
553             'name'        => 'test chapter',
554             'description' => 'test desc',
555         ]);
556         $resp->assertRedirect($book->getUrl('/chapter/test-chapter'));
557
558         $this->get($book->getUrl('/create-page'));
559         /** @var Page $page */
560         $page = Page::query()->where('draft', '=', true)->orderByDesc('id')->first();
561         $resp = $this->post($page->getUrl(), [
562             'name' => 'test page',
563             'html' => 'test desc',
564         ]);
565         $resp->assertRedirect($book->getUrl('/page/test-page'));
566
567         $resp = $this->get($bookUrl);
568         $this->withHtml($resp)->assertElementContains('.actions', 'New Page')
569             ->assertElementContains('.actions', 'New Chapter');
570     }
571
572     public function test_book_update_restriction_override()
573     {
574         /** @var Book $book */
575         $book = Book::query()->first();
576         $bookPage = $book->pages->first();
577         $bookChapter = $book->chapters->first();
578
579         $bookUrl = $book->getUrl();
580         $this->actingAs($this->viewer)->get($bookUrl . '/edit')
581             ->assertDontSee('Edit Book');
582
583         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
584
585         $this->get($bookUrl . '/edit')->assertRedirect('/');
586         $this->get('/')->assertSee('You do not have permission');
587         $this->get($bookPage->getUrl() . '/edit')->assertRedirect('/');
588         $this->get('/')->assertSee('You do not have permission');
589         $this->get($bookChapter->getUrl() . '/edit')->assertRedirect('/');
590         $this->get('/')->assertSee('You do not have permission');
591
592         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
593
594         $this->get($bookUrl . '/edit')->assertOk();
595         $this->get($bookPage->getUrl() . '/edit')->assertOk();
596         $this->get($bookChapter->getUrl() . '/edit')->assertSee('Edit Chapter');
597     }
598
599     public function test_book_delete_restriction_override()
600     {
601         /** @var Book $book */
602         $book = Book::query()->first();
603         $bookPage = $book->pages->first();
604         $bookChapter = $book->chapters->first();
605
606         $bookUrl = $book->getUrl();
607         $this->actingAs($this->viewer)
608             ->get($bookUrl . '/delete')
609             ->assertDontSee('Delete Book');
610
611         $this->setRestrictionsForTestRoles($book, ['view', 'update']);
612
613         $this->get($bookUrl . '/delete')->assertRedirect('/');
614         $this->get('/')->assertSee('You do not have permission');
615         $this->get($bookPage->getUrl() . '/delete')->assertRedirect('/');
616         $this->get('/')->assertSee('You do not have permission');
617         $this->get($bookChapter->getUrl() . '/delete')->assertRedirect('/');
618         $this->get('/')->assertSee('You do not have permission');
619
620         $this->setRestrictionsForTestRoles($book, ['view', 'delete']);
621
622         $this->get($bookUrl . '/delete')->assertOk()->assertSee('Delete Book');
623         $this->get($bookPage->getUrl() . '/delete')->assertOk()->assertSee('Delete Page');
624         $this->get($bookChapter->getUrl() . '/delete')->assertSee('Delete Chapter');
625     }
626
627     public function test_page_visible_if_has_permissions_when_book_not_visible()
628     {
629         /** @var Book $book */
630         $book = Book::query()->first();
631         $bookChapter = $book->chapters->first();
632         $bookPage = $bookChapter->pages->first();
633
634         foreach ([$book, $bookChapter, $bookPage] as $entity) {
635             $entity->name = Str::random(24);
636             $entity->save();
637         }
638
639         $this->setRestrictionsForTestRoles($book, []);
640         $this->setRestrictionsForTestRoles($bookPage, ['view']);
641
642         $this->actingAs($this->viewer);
643         $resp = $this->get($bookPage->getUrl());
644         $resp->assertOk();
645         $resp->assertSee($bookPage->name);
646         $resp->assertDontSee(substr($book->name, 0, 15));
647         $resp->assertDontSee(substr($bookChapter->name, 0, 15));
648     }
649
650     public function test_book_sort_view_permission()
651     {
652         /** @var Book $firstBook */
653         $firstBook = Book::query()->first();
654         /** @var Book $secondBook */
655         $secondBook = Book::query()->find(2);
656
657         $this->setRestrictionsForTestRoles($firstBook, ['view', 'update']);
658         $this->setRestrictionsForTestRoles($secondBook, ['view']);
659
660         // Test sort page visibility
661         $this->actingAs($this->user)->get($secondBook->getUrl('/sort'))->assertRedirect('/');
662         $this->get('/')->assertSee('You do not have permission');
663
664         // Check sort page on first book
665         $this->actingAs($this->user)->get($firstBook->getUrl('/sort'));
666     }
667
668     public function test_can_create_page_if_chapter_has_permissions_when_book_not_visible()
669     {
670         /** @var Book $book */
671         $book = Book::query()->first();
672         $this->setRestrictionsForTestRoles($book, []);
673         $bookChapter = $book->chapters->first();
674         $this->setRestrictionsForTestRoles($bookChapter, ['view']);
675
676         $this->actingAs($this->user)->get($bookChapter->getUrl())
677             ->assertDontSee('New Page');
678
679         $this->setRestrictionsForTestRoles($bookChapter, ['view', 'create']);
680
681         $this->get($bookChapter->getUrl('/create-page'));
682         /** @var Page $page */
683         $page = Page::query()->where('draft', '=', true)->orderByDesc('id')->first();
684         $resp = $this->post($page->getUrl(), [
685             'name' => 'test page',
686             'html' => 'test content',
687         ]);
688         $resp->assertRedirect($book->getUrl('/page/test-page'));
689     }
690 }