3 namespace Tests\Permissions;
5 use BookStack\Actions\Comment;
6 use BookStack\Auth\Role;
7 use BookStack\Auth\User;
8 use BookStack\Entities\Models\Book;
9 use BookStack\Entities\Models\Bookshelf;
10 use BookStack\Entities\Models\Chapter;
11 use BookStack\Entities\Models\Page;
12 use BookStack\Uploads\Image;
13 use Laravel\BrowserKitTesting\HttpException;
14 use Tests\BrowserKitTest;
16 class RolesTest extends BrowserKitTest
20 public function setUp(): void
23 $this->user = $this->getViewer();
26 public function test_admin_can_see_settings()
28 $this->asAdmin()->visit('/settings')->see('Settings');
31 public function test_cannot_delete_admin_role()
33 $adminRole = Role::getRole('admin');
34 $deletePageUrl = '/settings/roles/delete/' . $adminRole->id;
35 $this->asAdmin()->visit($deletePageUrl)
37 ->seePageIs($deletePageUrl)
38 ->see('cannot be deleted');
41 public function test_role_cannot_be_deleted_if_default()
43 $newRole = $this->createNewRole();
44 $this->setSettings(['registration-role' => $newRole->id]);
46 $deletePageUrl = '/settings/roles/delete/' . $newRole->id;
47 $this->asAdmin()->visit($deletePageUrl)
49 ->seePageIs($deletePageUrl)
50 ->see('cannot be deleted');
53 public function test_role_create_update_delete_flow()
55 $testRoleName = 'Test Role';
56 $testRoleDesc = 'a little test description';
57 $testRoleUpdateName = 'An Super Updated role';
60 $this->asAdmin()->visit('/settings')
62 ->seePageIs('/settings/roles')
63 ->click('Create New Role')
64 ->type('Test Role', 'display_name')
65 ->type('A little test description', 'description')
67 ->seeInDatabase('roles', ['display_name' => $testRoleName, 'description' => $testRoleDesc, 'mfa_enforced' => false])
68 ->seePageIs('/settings/roles');
70 $this->asAdmin()->visit('/settings/roles')
72 ->click($testRoleName)
73 ->type($testRoleUpdateName, '#display_name')
74 ->check('#mfa_enforced')
76 ->seeInDatabase('roles', ['display_name' => $testRoleUpdateName, 'description' => $testRoleDesc, 'mfa_enforced' => true])
77 ->seePageIs('/settings/roles');
79 $this->asAdmin()->visit('/settings/roles')
80 ->click($testRoleUpdateName)
81 ->click('Delete Role')
82 ->see($testRoleUpdateName)
84 ->seePageIs('/settings/roles')
85 ->dontSee($testRoleUpdateName);
88 public function test_admin_role_cannot_be_removed_if_last_admin()
90 $adminRole = Role::where('system_name', '=', 'admin')->first();
91 $adminUser = $this->getAdmin();
92 $adminRole->users()->where('id', '!=', $adminUser->id)->delete();
93 $this->assertEquals($adminRole->users()->count(), 1);
95 $viewerRole = $this->getViewer()->roles()->first();
97 $editUrl = '/settings/users/' . $adminUser->id;
98 $this->actingAs($adminUser)->put($editUrl, [
99 'name' => $adminUser->name,
100 'email' => $adminUser->email,
102 'viewer' => strval($viewerRole->id),
104 ])->followRedirects();
106 $this->seePageIs($editUrl);
107 $this->see('This user is the only user assigned to the administrator role');
110 public function test_migrate_users_on_delete_works()
112 $roleA = Role::query()->create(['display_name' => 'Delete Test A']);
113 $roleB = Role::query()->create(['display_name' => 'Delete Test B']);
114 $this->user->attachRole($roleB);
116 $this->assertCount(0, $roleA->users()->get());
117 $this->assertCount(1, $roleB->users()->get());
119 $deletePage = $this->asAdmin()->get("/settings/roles/delete/{$roleB->id}");
120 $deletePage->seeElement('select[name=migrate_role_id]');
121 $this->asAdmin()->delete("/settings/roles/delete/{$roleB->id}", [
122 'migrate_role_id' => $roleA->id,
125 $this->assertCount(1, $roleA->users()->get());
126 $this->assertEquals($this->user->id, $roleA->users()->first()->id);
129 public function test_manage_user_permission()
131 $this->actingAs($this->user)->visit('/settings/users')
133 $this->giveUserPermissions($this->user, ['users-manage']);
134 $this->actingAs($this->user)->visit('/settings/users')
135 ->seePageIs('/settings/users');
138 public function test_manage_users_permission_shows_link_in_header_if_does_not_have_settings_manage_permision()
140 $usersLink = 'href="' . url('/settings/users') . '"';
141 $this->actingAs($this->user)->visit('/')->dontSee($usersLink);
142 $this->giveUserPermissions($this->user, ['users-manage']);
143 $this->actingAs($this->user)->visit('/')->see($usersLink);
144 $this->giveUserPermissions($this->user, ['settings-manage', 'users-manage']);
145 $this->actingAs($this->user)->visit('/')->dontSee($usersLink);
148 public function test_user_cannot_change_email_unless_they_have_manage_users_permission()
150 $userProfileUrl = '/settings/users/' . $this->user->id;
151 $originalEmail = $this->user->email;
152 $this->actingAs($this->user);
154 $this->visit($userProfileUrl)
156 ->seeElement('input[name=email][disabled]');
157 $this->put($userProfileUrl, [
158 'name' => 'my_new_name',
161 $this->seeInDatabase('users', [
162 'id' => $this->user->id,
163 'email' => $originalEmail,
164 'name' => 'my_new_name',
167 $this->giveUserPermissions($this->user, ['users-manage']);
169 $this->visit($userProfileUrl)
171 ->dontSeeElement('input[name=email][disabled]')
172 ->seeElement('input[name=email]');
173 $this->put($userProfileUrl, [
174 'name' => 'my_new_name_2',
178 $this->seeInDatabase('users', [
179 'id' => $this->user->id,
181 'name' => 'my_new_name_2',
185 public function test_user_roles_manage_permission()
187 $this->actingAs($this->user)->visit('/settings/roles')
188 ->seePageIs('/')->visit('/settings/roles/1')->seePageIs('/');
189 $this->giveUserPermissions($this->user, ['user-roles-manage']);
190 $this->actingAs($this->user)->visit('/settings/roles')
191 ->seePageIs('/settings/roles')->click('Admin')
195 public function test_settings_manage_permission()
197 $this->actingAs($this->user)->visit('/settings')
199 $this->giveUserPermissions($this->user, ['settings-manage']);
200 $this->actingAs($this->user)->visit('/settings')
201 ->seePageIs('/settings')->press('Save Settings')->see('Settings Saved');
204 public function test_restrictions_manage_all_permission()
206 $page = Page::take(1)->get()->first();
207 $this->actingAs($this->user)->visit($page->getUrl())
208 ->dontSee('Permissions')
209 ->visit($page->getUrl() . '/permissions')
211 $this->giveUserPermissions($this->user, ['restrictions-manage-all']);
212 $this->actingAs($this->user)->visit($page->getUrl())
214 ->click('Permissions')
215 ->see('Page Permissions')->seePageIs($page->getUrl() . '/permissions');
218 public function test_restrictions_manage_own_permission()
220 $otherUsersPage = Page::first();
221 $content = $this->createEntityChainBelongingToUser($this->user);
223 // Set a different creator on the page we're checking to ensure
224 // that the owner fields are checked
225 $page = $content['page']; /** @var Page $page */
226 $page->created_by = $otherUsersPage->id;
227 $page->owned_by = $this->user->id;
230 // Check can't restrict other's content
231 $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
232 ->dontSee('Permissions')
233 ->visit($otherUsersPage->getUrl() . '/permissions')
235 // Check can't restrict own content
236 $this->actingAs($this->user)->visit($page->getUrl())
237 ->dontSee('Permissions')
238 ->visit($page->getUrl() . '/permissions')
241 $this->giveUserPermissions($this->user, ['restrictions-manage-own']);
243 // Check can't restrict other's content
244 $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
245 ->dontSee('Permissions')
246 ->visit($otherUsersPage->getUrl() . '/permissions')
248 // Check can restrict own content
249 $this->actingAs($this->user)->visit($page->getUrl())
251 ->click('Permissions')
252 ->seePageIs($page->getUrl() . '/permissions');
256 * Check a standard entity access permission.
258 * @param string $permission
259 * @param array $accessUrls Urls that are only accessible after having the permission
260 * @param array $visibles Check this text, In the buttons toolbar, is only visible with the permission
262 private function checkAccessPermission($permission, $accessUrls = [], $visibles = [])
264 foreach ($accessUrls as $url) {
265 $this->actingAs($this->user)->visit($url)
268 foreach ($visibles as $url => $text) {
269 $this->actingAs($this->user)->visit($url)
270 ->dontSeeInElement('.action-buttons', $text);
273 $this->giveUserPermissions($this->user, [$permission]);
275 foreach ($accessUrls as $url) {
276 $this->actingAs($this->user)->visit($url)
279 foreach ($visibles as $url => $text) {
280 $this->actingAs($this->user)->visit($url)
285 public function test_bookshelves_create_all_permissions()
287 $this->checkAccessPermission('bookshelf-create-all', [
290 '/shelves' => 'New Shelf',
293 $this->visit('/create-shelf')
294 ->type('test shelf', 'name')
295 ->type('shelf desc', 'description')
296 ->press('Save Shelf')
297 ->seePageIs('/shelves/test-shelf');
300 public function test_bookshelves_edit_own_permission()
302 $otherShelf = Bookshelf::first();
303 $ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
304 $ownShelf->forceFill(['owned_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
305 $this->regenEntityPermissions($ownShelf);
307 $this->checkAccessPermission('bookshelf-update-own', [
308 $ownShelf->getUrl('/edit'),
310 $ownShelf->getUrl() => 'Edit',
313 $this->visit($otherShelf->getUrl())
314 ->dontSeeInElement('.action-buttons', 'Edit')
315 ->visit($otherShelf->getUrl('/edit'))
319 public function test_bookshelves_edit_all_permission()
321 $otherShelf = Bookshelf::first();
322 $this->checkAccessPermission('bookshelf-update-all', [
323 $otherShelf->getUrl('/edit'),
325 $otherShelf->getUrl() => 'Edit',
329 public function test_bookshelves_delete_own_permission()
331 $this->giveUserPermissions($this->user, ['bookshelf-update-all']);
332 $otherShelf = Bookshelf::first();
333 $ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
334 $ownShelf->forceFill(['owned_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
335 $this->regenEntityPermissions($ownShelf);
337 $this->checkAccessPermission('bookshelf-delete-own', [
338 $ownShelf->getUrl('/delete'),
340 $ownShelf->getUrl() => 'Delete',
343 $this->visit($otherShelf->getUrl())
344 ->dontSeeInElement('.action-buttons', 'Delete')
345 ->visit($otherShelf->getUrl('/delete'))
347 $this->visit($ownShelf->getUrl())->visit($ownShelf->getUrl('/delete'))
349 ->seePageIs('/shelves')
350 ->dontSee($ownShelf->name);
353 public function test_bookshelves_delete_all_permission()
355 $this->giveUserPermissions($this->user, ['bookshelf-update-all']);
356 $otherShelf = Bookshelf::first();
357 $this->checkAccessPermission('bookshelf-delete-all', [
358 $otherShelf->getUrl('/delete'),
360 $otherShelf->getUrl() => 'Delete',
363 $this->visit($otherShelf->getUrl())->visit($otherShelf->getUrl('/delete'))
365 ->seePageIs('/shelves')
366 ->dontSee($otherShelf->name);
369 public function test_books_create_all_permissions()
371 $this->checkAccessPermission('book-create-all', [
374 '/books' => 'Create New Book',
377 $this->visit('/create-book')
378 ->type('test book', 'name')
379 ->type('book desc', 'description')
381 ->seePageIs('/books/test-book');
384 public function test_books_edit_own_permission()
386 $otherBook = Book::take(1)->get()->first();
387 $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
388 $this->checkAccessPermission('book-update-own', [
389 $ownBook->getUrl() . '/edit',
391 $ownBook->getUrl() => 'Edit',
394 $this->visit($otherBook->getUrl())
395 ->dontSeeInElement('.action-buttons', 'Edit')
396 ->visit($otherBook->getUrl() . '/edit')
400 public function test_books_edit_all_permission()
402 $otherBook = Book::take(1)->get()->first();
403 $this->checkAccessPermission('book-update-all', [
404 $otherBook->getUrl() . '/edit',
406 $otherBook->getUrl() => 'Edit',
410 public function test_books_delete_own_permission()
412 $this->giveUserPermissions($this->user, ['book-update-all']);
413 $otherBook = Book::take(1)->get()->first();
414 $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
415 $this->checkAccessPermission('book-delete-own', [
416 $ownBook->getUrl() . '/delete',
418 $ownBook->getUrl() => 'Delete',
421 $this->visit($otherBook->getUrl())
422 ->dontSeeInElement('.action-buttons', 'Delete')
423 ->visit($otherBook->getUrl() . '/delete')
425 $this->visit($ownBook->getUrl())->visit($ownBook->getUrl() . '/delete')
427 ->seePageIs('/books')
428 ->dontSee($ownBook->name);
431 public function test_books_delete_all_permission()
433 $this->giveUserPermissions($this->user, ['book-update-all']);
434 $otherBook = Book::take(1)->get()->first();
435 $this->checkAccessPermission('book-delete-all', [
436 $otherBook->getUrl() . '/delete',
438 $otherBook->getUrl() => 'Delete',
441 $this->visit($otherBook->getUrl())->visit($otherBook->getUrl() . '/delete')
443 ->seePageIs('/books')
444 ->dontSee($otherBook->name);
447 public function test_chapter_create_own_permissions()
449 $book = Book::take(1)->get()->first();
450 $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
451 $this->checkAccessPermission('chapter-create-own', [
452 $ownBook->getUrl('/create-chapter'),
454 $ownBook->getUrl() => 'New Chapter',
457 $this->visit($ownBook->getUrl('/create-chapter'))
458 ->type('test chapter', 'name')
459 ->type('chapter desc', 'description')
460 ->press('Save Chapter')
461 ->seePageIs($ownBook->getUrl('/chapter/test-chapter'));
463 $this->visit($book->getUrl())
464 ->dontSeeInElement('.action-buttons', 'New Chapter')
465 ->visit($book->getUrl('/create-chapter'))
469 public function test_chapter_create_all_permissions()
471 $book = Book::take(1)->get()->first();
472 $this->checkAccessPermission('chapter-create-all', [
473 $book->getUrl('/create-chapter'),
475 $book->getUrl() => 'New Chapter',
478 $this->visit($book->getUrl('/create-chapter'))
479 ->type('test chapter', 'name')
480 ->type('chapter desc', 'description')
481 ->press('Save Chapter')
482 ->seePageIs($book->getUrl('/chapter/test-chapter'));
485 public function test_chapter_edit_own_permission()
487 $otherChapter = Chapter::take(1)->get()->first();
488 $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
489 $this->checkAccessPermission('chapter-update-own', [
490 $ownChapter->getUrl() . '/edit',
492 $ownChapter->getUrl() => 'Edit',
495 $this->visit($otherChapter->getUrl())
496 ->dontSeeInElement('.action-buttons', 'Edit')
497 ->visit($otherChapter->getUrl() . '/edit')
501 public function test_chapter_edit_all_permission()
503 $otherChapter = Chapter::take(1)->get()->first();
504 $this->checkAccessPermission('chapter-update-all', [
505 $otherChapter->getUrl() . '/edit',
507 $otherChapter->getUrl() => 'Edit',
511 public function test_chapter_delete_own_permission()
513 $this->giveUserPermissions($this->user, ['chapter-update-all']);
514 $otherChapter = Chapter::take(1)->get()->first();
515 $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
516 $this->checkAccessPermission('chapter-delete-own', [
517 $ownChapter->getUrl() . '/delete',
519 $ownChapter->getUrl() => 'Delete',
522 $bookUrl = $ownChapter->book->getUrl();
523 $this->visit($otherChapter->getUrl())
524 ->dontSeeInElement('.action-buttons', 'Delete')
525 ->visit($otherChapter->getUrl() . '/delete')
527 $this->visit($ownChapter->getUrl())->visit($ownChapter->getUrl() . '/delete')
529 ->seePageIs($bookUrl)
530 ->dontSeeInElement('.book-content', $ownChapter->name);
533 public function test_chapter_delete_all_permission()
535 $this->giveUserPermissions($this->user, ['chapter-update-all']);
536 $otherChapter = Chapter::take(1)->get()->first();
537 $this->checkAccessPermission('chapter-delete-all', [
538 $otherChapter->getUrl() . '/delete',
540 $otherChapter->getUrl() => 'Delete',
543 $bookUrl = $otherChapter->book->getUrl();
544 $this->visit($otherChapter->getUrl())->visit($otherChapter->getUrl() . '/delete')
546 ->seePageIs($bookUrl)
547 ->dontSeeInElement('.book-content', $otherChapter->name);
550 public function test_page_create_own_permissions()
552 $book = Book::first();
553 $chapter = Chapter::first();
555 $entities = $this->createEntityChainBelongingToUser($this->user);
556 $ownBook = $entities['book'];
557 $ownChapter = $entities['chapter'];
559 $createUrl = $ownBook->getUrl('/create-page');
560 $createUrlChapter = $ownChapter->getUrl('/create-page');
561 $accessUrls = [$createUrl, $createUrlChapter];
563 foreach ($accessUrls as $url) {
564 $this->actingAs($this->user)->visit($url)
568 $this->checkAccessPermission('page-create-own', [], [
569 $ownBook->getUrl() => 'New Page',
570 $ownChapter->getUrl() => 'New Page',
573 $this->giveUserPermissions($this->user, ['page-create-own']);
575 foreach ($accessUrls as $index => $url) {
576 $this->actingAs($this->user)->visit($url);
577 $expectedUrl = Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
578 $this->seePageIs($expectedUrl);
581 $this->visit($createUrl)
582 ->type('test page', 'name')
583 ->type('page desc', 'html')
585 ->seePageIs($ownBook->getUrl('/page/test-page'));
587 $this->visit($book->getUrl())
588 ->dontSeeInElement('.action-buttons', 'New Page')
589 ->visit($book->getUrl() . '/create-page')
591 $this->visit($chapter->getUrl())
592 ->dontSeeInElement('.action-buttons', 'New Page')
593 ->visit($chapter->getUrl() . '/create-page')
597 public function test_page_create_all_permissions()
599 $book = Book::take(1)->get()->first();
600 $chapter = Chapter::take(1)->get()->first();
601 $baseUrl = $book->getUrl() . '/page';
602 $createUrl = $book->getUrl('/create-page');
604 $createUrlChapter = $chapter->getUrl('/create-page');
605 $accessUrls = [$createUrl, $createUrlChapter];
607 foreach ($accessUrls as $url) {
608 $this->actingAs($this->user)->visit($url)
612 $this->checkAccessPermission('page-create-all', [], [
613 $book->getUrl() => 'New Page',
614 $chapter->getUrl() => 'New Page',
617 $this->giveUserPermissions($this->user, ['page-create-all']);
619 foreach ($accessUrls as $index => $url) {
620 $this->actingAs($this->user)->visit($url);
621 $expectedUrl = Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
622 $this->seePageIs($expectedUrl);
625 $this->visit($createUrl)
626 ->type('test page', 'name')
627 ->type('page desc', 'html')
629 ->seePageIs($book->getUrl('/page/test-page'));
631 $this->visit($chapter->getUrl('/create-page'))
632 ->type('new test page', 'name')
633 ->type('page desc', 'html')
635 ->seePageIs($book->getUrl('/page/new-test-page'));
638 public function test_page_edit_own_permission()
640 $otherPage = Page::take(1)->get()->first();
641 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
642 $this->checkAccessPermission('page-update-own', [
643 $ownPage->getUrl() . '/edit',
645 $ownPage->getUrl() => 'Edit',
648 $this->visit($otherPage->getUrl())
649 ->dontSeeInElement('.action-buttons', 'Edit')
650 ->visit($otherPage->getUrl() . '/edit')
654 public function test_page_edit_all_permission()
656 $otherPage = Page::take(1)->get()->first();
657 $this->checkAccessPermission('page-update-all', [
658 $otherPage->getUrl() . '/edit',
660 $otherPage->getUrl() => 'Edit',
664 public function test_page_delete_own_permission()
666 $this->giveUserPermissions($this->user, ['page-update-all']);
667 $otherPage = Page::take(1)->get()->first();
668 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
669 $this->checkAccessPermission('page-delete-own', [
670 $ownPage->getUrl() . '/delete',
672 $ownPage->getUrl() => 'Delete',
675 $parent = $ownPage->chapter ?? $ownPage->book;
676 $this->visit($otherPage->getUrl())
677 ->dontSeeInElement('.action-buttons', 'Delete')
678 ->visit($otherPage->getUrl() . '/delete')
680 $this->visit($ownPage->getUrl())->visit($ownPage->getUrl() . '/delete')
682 ->seePageIs($parent->getUrl())
683 ->dontSeeInElement('.book-content', $ownPage->name);
686 public function test_page_delete_all_permission()
688 $this->giveUserPermissions($this->user, ['page-update-all']);
689 $otherPage = Page::take(1)->get()->first();
690 $this->checkAccessPermission('page-delete-all', [
691 $otherPage->getUrl() . '/delete',
693 $otherPage->getUrl() => 'Delete',
696 $parent = $otherPage->chapter ?? $otherPage->book;
697 $this->visit($otherPage->getUrl())->visit($otherPage->getUrl() . '/delete')
699 ->seePageIs($parent->getUrl())
700 ->dontSeeInElement('.book-content', $otherPage->name);
703 public function test_public_role_visible_in_user_edit_screen()
705 $user = User::first();
706 $adminRole = Role::getSystemRole('admin');
707 $publicRole = Role::getSystemRole('public');
708 $this->asAdmin()->visit('/settings/users/' . $user->id)
709 ->seeElement('[name="roles[' . $adminRole->id . ']"]')
710 ->seeElement('[name="roles[' . $publicRole->id . ']"]');
713 public function test_public_role_visible_in_role_listing()
715 $this->asAdmin()->visit('/settings/roles')
720 public function test_public_role_visible_in_default_role_setting()
722 $this->asAdmin()->visit('/settings')
723 ->seeElement('[data-system-role-name="admin"]')
724 ->seeElement('[data-system-role-name="public"]');
727 public function test_public_role_not_deleteable()
729 $this->asAdmin()->visit('/settings/roles')
732 ->click('Delete Role')
735 ->see('Cannot be deleted');
738 public function test_image_delete_own_permission()
740 $this->giveUserPermissions($this->user, ['image-update-all']);
741 $page = Page::first();
742 $image = factory(Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $this->user->id, 'updated_by' => $this->user->id]);
744 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
745 ->seeStatusCode(403);
747 $this->giveUserPermissions($this->user, ['image-delete-own']);
749 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
751 ->dontSeeInDatabase('images', ['id' => $image->id]);
754 public function test_image_delete_all_permission()
756 $this->giveUserPermissions($this->user, ['image-update-all']);
757 $admin = $this->getAdmin();
758 $page = Page::first();
759 $image = factory(Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $admin->id, 'updated_by' => $admin->id]);
761 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
762 ->seeStatusCode(403);
764 $this->giveUserPermissions($this->user, ['image-delete-own']);
766 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
767 ->seeStatusCode(403);
769 $this->giveUserPermissions($this->user, ['image-delete-all']);
771 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
773 ->dontSeeInDatabase('images', ['id' => $image->id]);
776 public function test_role_permission_removal()
778 // To cover issue fixed in f99c8ff99aee9beb8c692f36d4b84dc6e651e50a.
779 $page = Page::first();
780 $viewerRole = Role::getRole('viewer');
781 $viewer = $this->getViewer();
782 $this->actingAs($viewer)->visit($page->getUrl())->assertResponseStatus(200);
784 $this->asAdmin()->put('/settings/roles/' . $viewerRole->id, [
785 'display_name' => $viewerRole->display_name,
786 'description' => $viewerRole->description,
788 ])->assertResponseStatus(302);
790 $this->expectException(HttpException::class);
791 $this->actingAs($viewer)->visit($page->getUrl())->assertResponseStatus(404);
794 public function test_empty_state_actions_not_visible_without_permission()
796 $admin = $this->getAdmin();
798 $book = factory(Book::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id]);
799 $this->updateEntityPermissions($book);
800 $this->actingAs($this->getViewer())->visit($book->getUrl())
801 ->dontSee('Create a new page')
802 ->dontSee('Add a chapter');
805 $chapter = factory(Chapter::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id, 'book_id' => $book->id]);
806 $this->updateEntityPermissions($chapter);
807 $this->actingAs($this->getViewer())->visit($chapter->getUrl())
808 ->dontSee('Create a new page')
809 ->dontSee('Sort the current book');
812 public function test_comment_create_permission()
814 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
816 $this->actingAs($this->user)->addComment($ownPage);
818 $this->assertResponseStatus(403);
820 $this->giveUserPermissions($this->user, ['comment-create-all']);
822 $this->actingAs($this->user)->addComment($ownPage);
823 $this->assertResponseStatus(200);
826 public function test_comment_update_own_permission()
828 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
829 $this->giveUserPermissions($this->user, ['comment-create-all']);
830 $commentId = $this->actingAs($this->user)->addComment($ownPage);
832 // no comment-update-own
833 $this->actingAs($this->user)->updateComment($commentId);
834 $this->assertResponseStatus(403);
836 $this->giveUserPermissions($this->user, ['comment-update-own']);
838 // now has comment-update-own
839 $this->actingAs($this->user)->updateComment($commentId);
840 $this->assertResponseStatus(200);
843 public function test_comment_update_all_permission()
845 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
846 $commentId = $this->asAdmin()->addComment($ownPage);
848 // no comment-update-all
849 $this->actingAs($this->user)->updateComment($commentId);
850 $this->assertResponseStatus(403);
852 $this->giveUserPermissions($this->user, ['comment-update-all']);
854 // now has comment-update-all
855 $this->actingAs($this->user)->updateComment($commentId);
856 $this->assertResponseStatus(200);
859 public function test_comment_delete_own_permission()
861 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
862 $this->giveUserPermissions($this->user, ['comment-create-all']);
863 $commentId = $this->actingAs($this->user)->addComment($ownPage);
865 // no comment-delete-own
866 $this->actingAs($this->user)->deleteComment($commentId);
867 $this->assertResponseStatus(403);
869 $this->giveUserPermissions($this->user, ['comment-delete-own']);
871 // now has comment-update-own
872 $this->actingAs($this->user)->deleteComment($commentId);
873 $this->assertResponseStatus(200);
876 public function test_comment_delete_all_permission()
878 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
879 $commentId = $this->asAdmin()->addComment($ownPage);
881 // no comment-delete-all
882 $this->actingAs($this->user)->deleteComment($commentId);
883 $this->assertResponseStatus(403);
885 $this->giveUserPermissions($this->user, ['comment-delete-all']);
887 // now has comment-delete-all
888 $this->actingAs($this->user)->deleteComment($commentId);
889 $this->assertResponseStatus(200);
892 private function addComment($page)
894 $comment = factory(Comment::class)->make();
895 $url = "/comment/$page->id";
897 'text' => $comment->text,
898 'html' => $comment->html,
901 $this->postJson($url, $request);
902 $comment = $page->comments()->first();
904 return $comment === null ? null : $comment->id;
907 private function updateComment($commentId)
909 $comment = factory(Comment::class)->make();
910 $url = "/comment/$commentId";
912 'text' => $comment->text,
913 'html' => $comment->html,
916 return $this->putJson($url, $request);
919 private function deleteComment($commentId)
921 $url = '/comment/' . $commentId;
923 return $this->json('DELETE', $url);