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