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