1 <?php namespace Tests\Permissions;
3 use BookStack\Actions\Comment;
4 use BookStack\Auth\User;
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Bookshelf;
7 use BookStack\Entities\Models\Chapter;
8 use BookStack\Entities\Models\Page;
9 use BookStack\Auth\Role;
10 use BookStack\Uploads\Image;
11 use Laravel\BrowserKitTesting\HttpException;
12 use Tests\BrowserKitTest;
14 class RolesTest extends BrowserKitTest
18 public function setUp(): void
21 $this->user = $this->getViewer();
24 public function test_admin_can_see_settings()
26 $this->asAdmin()->visit('/settings')->see('Settings');
29 public function test_cannot_delete_admin_role()
31 $adminRole = Role::getRole('admin');
32 $deletePageUrl = '/settings/roles/delete/' . $adminRole->id;
33 $this->asAdmin()->visit($deletePageUrl)
35 ->seePageIs($deletePageUrl)
36 ->see('cannot be deleted');
39 public function test_role_cannot_be_deleted_if_default()
41 $newRole = $this->createNewRole();
42 $this->setSettings(['registration-role' => $newRole->id]);
44 $deletePageUrl = '/settings/roles/delete/' . $newRole->id;
45 $this->asAdmin()->visit($deletePageUrl)
47 ->seePageIs($deletePageUrl)
48 ->see('cannot be deleted');
51 public function test_role_create_update_delete_flow()
53 $testRoleName = 'Test Role';
54 $testRoleDesc = 'a little test description';
55 $testRoleUpdateName = 'An Super Updated role';
58 $this->asAdmin()->visit('/settings')
60 ->seePageIs('/settings/roles')
61 ->click('Create New Role')
62 ->type('Test Role', 'display_name')
63 ->type('A little test description', 'description')
65 ->seeInDatabase('roles', ['display_name' => $testRoleName, 'description' => $testRoleDesc])
66 ->seePageIs('/settings/roles');
68 $this->asAdmin()->visit('/settings/roles')
70 ->click($testRoleName)
71 ->type($testRoleUpdateName, '#display_name')
73 ->seeInDatabase('roles', ['display_name' => $testRoleUpdateName, 'description' => $testRoleDesc])
74 ->seePageIs('/settings/roles');
76 $this->asAdmin()->visit('/settings/roles')
77 ->click($testRoleUpdateName)
78 ->click('Delete Role')
79 ->see($testRoleUpdateName)
81 ->seePageIs('/settings/roles')
82 ->dontSee($testRoleUpdateName);
85 public function test_admin_role_cannot_be_removed_if_last_admin()
87 $adminRole = Role::where('system_name', '=', 'admin')->first();
88 $adminUser = $this->getAdmin();
89 $adminRole->users()->where('id', '!=', $adminUser->id)->delete();
90 $this->assertEquals($adminRole->users()->count(), 1);
92 $viewerRole = $this->getViewer()->roles()->first();
94 $editUrl = '/settings/users/' . $adminUser->id;
95 $this->actingAs($adminUser)->put($editUrl, [
96 'name' => $adminUser->name,
97 'email' => $adminUser->email,
99 'viewer' => strval($viewerRole->id),
101 ])->followRedirects();
103 $this->seePageIs($editUrl);
104 $this->see('This user is the only user assigned to the administrator role');
107 public function test_migrate_users_on_delete_works()
109 $roleA = Role::query()->create(['display_name' => 'Delete Test A']);
110 $roleB = Role::query()->create(['display_name' => 'Delete Test B']);
111 $this->user->attachRole($roleB);
113 $this->assertCount(0, $roleA->users()->get());
114 $this->assertCount(1, $roleB->users()->get());
116 $deletePage = $this->asAdmin()->get("/settings/roles/delete/{$roleB->id}");
117 $deletePage->seeElement('select[name=migrate_role_id]');
118 $this->asAdmin()->delete("/settings/roles/delete/{$roleB->id}", [
119 'migrate_role_id' => $roleA->id,
122 $this->assertCount(1, $roleA->users()->get());
123 $this->assertEquals($this->user->id, $roleA->users()->first()->id);
126 public function test_manage_user_permission()
128 $this->actingAs($this->user)->visit('/settings/users')
130 $this->giveUserPermissions($this->user, ['users-manage']);
131 $this->actingAs($this->user)->visit('/settings/users')
132 ->seePageIs('/settings/users');
135 public function test_manage_users_permission_shows_link_in_header_if_does_not_have_settings_manage_permision()
137 $usersLink = 'href="'.url('/settings/users') . '"';
138 $this->actingAs($this->user)->visit('/')->dontSee($usersLink);
139 $this->giveUserPermissions($this->user, ['users-manage']);
140 $this->actingAs($this->user)->visit('/')->see($usersLink);
141 $this->giveUserPermissions($this->user, ['settings-manage', 'users-manage']);
142 $this->actingAs($this->user)->visit('/')->dontSee($usersLink);
145 public function test_user_cannot_change_email_unless_they_have_manage_users_permission()
147 $userProfileUrl = '/settings/users/' . $this->user->id;
148 $originalEmail = $this->user->email;
149 $this->actingAs($this->user);
151 $this->visit($userProfileUrl)
153 ->seeElement('input[name=email][disabled]');
154 $this->put($userProfileUrl, [
155 'name' => 'my_new_name',
158 $this->seeInDatabase('users', [
159 'id' => $this->user->id,
160 'email' => $originalEmail,
161 'name' => 'my_new_name',
164 $this->giveUserPermissions($this->user, ['users-manage']);
166 $this->visit($userProfileUrl)
168 ->dontSeeElement('input[name=email][disabled]')
169 ->seeElement('input[name=email]');
170 $this->put($userProfileUrl, [
171 'name' => 'my_new_name_2',
175 $this->seeInDatabase('users', [
176 'id' => $this->user->id,
178 'name' => 'my_new_name_2',
182 public function test_user_roles_manage_permission()
184 $this->actingAs($this->user)->visit('/settings/roles')
185 ->seePageIs('/')->visit('/settings/roles/1')->seePageIs('/');
186 $this->giveUserPermissions($this->user, ['user-roles-manage']);
187 $this->actingAs($this->user)->visit('/settings/roles')
188 ->seePageIs('/settings/roles')->click('Admin')
192 public function test_settings_manage_permission()
194 $this->actingAs($this->user)->visit('/settings')
196 $this->giveUserPermissions($this->user, ['settings-manage']);
197 $this->actingAs($this->user)->visit('/settings')
198 ->seePageIs('/settings')->press('Save Settings')->see('Settings Saved');
201 public function test_restrictions_manage_all_permission()
203 $page = Page::take(1)->get()->first();
204 $this->actingAs($this->user)->visit($page->getUrl())
205 ->dontSee('Permissions')
206 ->visit($page->getUrl() . '/permissions')
208 $this->giveUserPermissions($this->user, ['restrictions-manage-all']);
209 $this->actingAs($this->user)->visit($page->getUrl())
211 ->click('Permissions')
212 ->see('Page Permissions')->seePageIs($page->getUrl() . '/permissions');
215 public function test_restrictions_manage_own_permission()
217 $otherUsersPage = Page::first();
218 $content = $this->createEntityChainBelongingToUser($this->user);
219 // Check can't restrict other's content
220 $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
221 ->dontSee('Permissions')
222 ->visit($otherUsersPage->getUrl() . '/permissions')
224 // Check can't restrict own content
225 $this->actingAs($this->user)->visit($content['page']->getUrl())
226 ->dontSee('Permissions')
227 ->visit($content['page']->getUrl() . '/permissions')
230 $this->giveUserPermissions($this->user, ['restrictions-manage-own']);
232 // Check can't restrict other's content
233 $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
234 ->dontSee('Permissions')
235 ->visit($otherUsersPage->getUrl() . '/permissions')
237 // Check can restrict own content
238 $this->actingAs($this->user)->visit($content['page']->getUrl())
240 ->click('Permissions')
241 ->seePageIs($content['page']->getUrl() . '/permissions');
245 * Check a standard entity access permission
246 * @param string $permission
247 * @param array $accessUrls Urls that are only accessible after having the permission
248 * @param array $visibles Check this text, In the buttons toolbar, is only visible with the permission
250 private function checkAccessPermission($permission, $accessUrls = [], $visibles = [])
252 foreach ($accessUrls as $url) {
253 $this->actingAs($this->user)->visit($url)
256 foreach ($visibles as $url => $text) {
257 $this->actingAs($this->user)->visit($url)
258 ->dontSeeInElement('.action-buttons',$text);
261 $this->giveUserPermissions($this->user, [$permission]);
263 foreach ($accessUrls as $url) {
264 $this->actingAs($this->user)->visit($url)
267 foreach ($visibles as $url => $text) {
268 $this->actingAs($this->user)->visit($url)
273 public function test_bookshelves_create_all_permissions()
275 $this->checkAccessPermission('bookshelf-create-all', [
278 '/shelves' => 'New Shelf'
281 $this->visit('/create-shelf')
282 ->type('test shelf', 'name')
283 ->type('shelf desc', 'description')
284 ->press('Save Shelf')
285 ->seePageIs('/shelves/test-shelf');
288 public function test_bookshelves_edit_own_permission()
290 $otherShelf = Bookshelf::first();
291 $ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
292 $ownShelf->forceFill(['created_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
293 $this->regenEntityPermissions($ownShelf);
295 $this->checkAccessPermission('bookshelf-update-own', [
296 $ownShelf->getUrl('/edit')
298 $ownShelf->getUrl() => 'Edit'
301 $this->visit($otherShelf->getUrl())
302 ->dontSeeInElement('.action-buttons', 'Edit')
303 ->visit($otherShelf->getUrl('/edit'))
307 public function test_bookshelves_edit_all_permission()
309 $otherShelf = Bookshelf::first();
310 $this->checkAccessPermission('bookshelf-update-all', [
311 $otherShelf->getUrl('/edit')
313 $otherShelf->getUrl() => 'Edit'
317 public function test_bookshelves_delete_own_permission()
319 $this->giveUserPermissions($this->user, ['bookshelf-update-all']);
320 $otherShelf = Bookshelf::first();
321 $ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
322 $ownShelf->forceFill(['created_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
323 $this->regenEntityPermissions($ownShelf);
325 $this->checkAccessPermission('bookshelf-delete-own', [
326 $ownShelf->getUrl('/delete')
328 $ownShelf->getUrl() => 'Delete'
331 $this->visit($otherShelf->getUrl())
332 ->dontSeeInElement('.action-buttons', 'Delete')
333 ->visit($otherShelf->getUrl('/delete'))
335 $this->visit($ownShelf->getUrl())->visit($ownShelf->getUrl('/delete'))
337 ->seePageIs('/shelves')
338 ->dontSee($ownShelf->name);
341 public function test_bookshelves_delete_all_permission()
343 $this->giveUserPermissions($this->user, ['bookshelf-update-all']);
344 $otherShelf = Bookshelf::first();
345 $this->checkAccessPermission('bookshelf-delete-all', [
346 $otherShelf->getUrl('/delete')
348 $otherShelf->getUrl() => 'Delete'
351 $this->visit($otherShelf->getUrl())->visit($otherShelf->getUrl('/delete'))
353 ->seePageIs('/shelves')
354 ->dontSee($otherShelf->name);
357 public function test_books_create_all_permissions()
359 $this->checkAccessPermission('book-create-all', [
362 '/books' => 'Create New Book'
365 $this->visit('/create-book')
366 ->type('test book', 'name')
367 ->type('book desc', 'description')
369 ->seePageIs('/books/test-book');
372 public function test_books_edit_own_permission()
374 $otherBook = Book::take(1)->get()->first();
375 $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
376 $this->checkAccessPermission('book-update-own', [
377 $ownBook->getUrl() . '/edit'
379 $ownBook->getUrl() => 'Edit'
382 $this->visit($otherBook->getUrl())
383 ->dontSeeInElement('.action-buttons', 'Edit')
384 ->visit($otherBook->getUrl() . '/edit')
388 public function test_books_edit_all_permission()
390 $otherBook = Book::take(1)->get()->first();
391 $this->checkAccessPermission('book-update-all', [
392 $otherBook->getUrl() . '/edit'
394 $otherBook->getUrl() => 'Edit'
398 public function test_books_delete_own_permission()
400 $this->giveUserPermissions($this->user, ['book-update-all']);
401 $otherBook = Book::take(1)->get()->first();
402 $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
403 $this->checkAccessPermission('book-delete-own', [
404 $ownBook->getUrl() . '/delete'
406 $ownBook->getUrl() => 'Delete'
409 $this->visit($otherBook->getUrl())
410 ->dontSeeInElement('.action-buttons', 'Delete')
411 ->visit($otherBook->getUrl() . '/delete')
413 $this->visit($ownBook->getUrl())->visit($ownBook->getUrl() . '/delete')
415 ->seePageIs('/books')
416 ->dontSee($ownBook->name);
419 public function test_books_delete_all_permission()
421 $this->giveUserPermissions($this->user, ['book-update-all']);
422 $otherBook = Book::take(1)->get()->first();
423 $this->checkAccessPermission('book-delete-all', [
424 $otherBook->getUrl() . '/delete'
426 $otherBook->getUrl() => 'Delete'
429 $this->visit($otherBook->getUrl())->visit($otherBook->getUrl() . '/delete')
431 ->seePageIs('/books')
432 ->dontSee($otherBook->name);
435 public function test_chapter_create_own_permissions()
437 $book = Book::take(1)->get()->first();
438 $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
439 $this->checkAccessPermission('chapter-create-own', [
440 $ownBook->getUrl('/create-chapter')
442 $ownBook->getUrl() => 'New Chapter'
445 $this->visit($ownBook->getUrl('/create-chapter'))
446 ->type('test chapter', 'name')
447 ->type('chapter desc', 'description')
448 ->press('Save Chapter')
449 ->seePageIs($ownBook->getUrl('/chapter/test-chapter'));
451 $this->visit($book->getUrl())
452 ->dontSeeInElement('.action-buttons', 'New Chapter')
453 ->visit($book->getUrl('/create-chapter'))
457 public function test_chapter_create_all_permissions()
459 $book = Book::take(1)->get()->first();
460 $this->checkAccessPermission('chapter-create-all', [
461 $book->getUrl('/create-chapter')
463 $book->getUrl() => 'New Chapter'
466 $this->visit($book->getUrl('/create-chapter'))
467 ->type('test chapter', 'name')
468 ->type('chapter desc', 'description')
469 ->press('Save Chapter')
470 ->seePageIs($book->getUrl('/chapter/test-chapter'));
473 public function test_chapter_edit_own_permission()
475 $otherChapter = Chapter::take(1)->get()->first();
476 $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
477 $this->checkAccessPermission('chapter-update-own', [
478 $ownChapter->getUrl() . '/edit'
480 $ownChapter->getUrl() => 'Edit'
483 $this->visit($otherChapter->getUrl())
484 ->dontSeeInElement('.action-buttons', 'Edit')
485 ->visit($otherChapter->getUrl() . '/edit')
489 public function test_chapter_edit_all_permission()
491 $otherChapter = Chapter::take(1)->get()->first();
492 $this->checkAccessPermission('chapter-update-all', [
493 $otherChapter->getUrl() . '/edit'
495 $otherChapter->getUrl() => 'Edit'
499 public function test_chapter_delete_own_permission()
501 $this->giveUserPermissions($this->user, ['chapter-update-all']);
502 $otherChapter = Chapter::take(1)->get()->first();
503 $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
504 $this->checkAccessPermission('chapter-delete-own', [
505 $ownChapter->getUrl() . '/delete'
507 $ownChapter->getUrl() => 'Delete'
510 $bookUrl = $ownChapter->book->getUrl();
511 $this->visit($otherChapter->getUrl())
512 ->dontSeeInElement('.action-buttons', 'Delete')
513 ->visit($otherChapter->getUrl() . '/delete')
515 $this->visit($ownChapter->getUrl())->visit($ownChapter->getUrl() . '/delete')
517 ->seePageIs($bookUrl)
518 ->dontSeeInElement('.book-content', $ownChapter->name);
521 public function test_chapter_delete_all_permission()
523 $this->giveUserPermissions($this->user, ['chapter-update-all']);
524 $otherChapter = Chapter::take(1)->get()->first();
525 $this->checkAccessPermission('chapter-delete-all', [
526 $otherChapter->getUrl() . '/delete'
528 $otherChapter->getUrl() => 'Delete'
531 $bookUrl = $otherChapter->book->getUrl();
532 $this->visit($otherChapter->getUrl())->visit($otherChapter->getUrl() . '/delete')
534 ->seePageIs($bookUrl)
535 ->dontSeeInElement('.book-content', $otherChapter->name);
538 public function test_page_create_own_permissions()
540 $book = Book::first();
541 $chapter = Chapter::first();
543 $entities = $this->createEntityChainBelongingToUser($this->user);
544 $ownBook = $entities['book'];
545 $ownChapter = $entities['chapter'];
547 $createUrl = $ownBook->getUrl('/create-page');
548 $createUrlChapter = $ownChapter->getUrl('/create-page');
549 $accessUrls = [$createUrl, $createUrlChapter];
551 foreach ($accessUrls as $url) {
552 $this->actingAs($this->user)->visit($url)
556 $this->checkAccessPermission('page-create-own', [], [
557 $ownBook->getUrl() => 'New Page',
558 $ownChapter->getUrl() => 'New Page'
561 $this->giveUserPermissions($this->user, ['page-create-own']);
563 foreach ($accessUrls as $index => $url) {
564 $this->actingAs($this->user)->visit($url);
565 $expectedUrl = Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
566 $this->seePageIs($expectedUrl);
569 $this->visit($createUrl)
570 ->type('test page', 'name')
571 ->type('page desc', 'html')
573 ->seePageIs($ownBook->getUrl('/page/test-page'));
575 $this->visit($book->getUrl())
576 ->dontSeeInElement('.action-buttons', 'New Page')
577 ->visit($book->getUrl() . '/create-page')
579 $this->visit($chapter->getUrl())
580 ->dontSeeInElement('.action-buttons', 'New Page')
581 ->visit($chapter->getUrl() . '/create-page')
585 public function test_page_create_all_permissions()
587 $book = Book::take(1)->get()->first();
588 $chapter = Chapter::take(1)->get()->first();
589 $baseUrl = $book->getUrl() . '/page';
590 $createUrl = $book->getUrl('/create-page');
592 $createUrlChapter = $chapter->getUrl('/create-page');
593 $accessUrls = [$createUrl, $createUrlChapter];
595 foreach ($accessUrls as $url) {
596 $this->actingAs($this->user)->visit($url)
600 $this->checkAccessPermission('page-create-all', [], [
601 $book->getUrl() => 'New Page',
602 $chapter->getUrl() => 'New Page'
605 $this->giveUserPermissions($this->user, ['page-create-all']);
607 foreach ($accessUrls as $index => $url) {
608 $this->actingAs($this->user)->visit($url);
609 $expectedUrl = Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
610 $this->seePageIs($expectedUrl);
613 $this->visit($createUrl)
614 ->type('test page', 'name')
615 ->type('page desc', 'html')
617 ->seePageIs($book->getUrl('/page/test-page'));
619 $this->visit($chapter->getUrl('/create-page'))
620 ->type('new test page', 'name')
621 ->type('page desc', 'html')
623 ->seePageIs($book->getUrl('/page/new-test-page'));
626 public function test_page_edit_own_permission()
628 $otherPage = Page::take(1)->get()->first();
629 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
630 $this->checkAccessPermission('page-update-own', [
631 $ownPage->getUrl() . '/edit'
633 $ownPage->getUrl() => 'Edit'
636 $this->visit($otherPage->getUrl())
637 ->dontSeeInElement('.action-buttons', 'Edit')
638 ->visit($otherPage->getUrl() . '/edit')
642 public function test_page_edit_all_permission()
644 $otherPage = Page::take(1)->get()->first();
645 $this->checkAccessPermission('page-update-all', [
646 $otherPage->getUrl() . '/edit'
648 $otherPage->getUrl() => 'Edit'
652 public function test_page_delete_own_permission()
654 $this->giveUserPermissions($this->user, ['page-update-all']);
655 $otherPage = Page::take(1)->get()->first();
656 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
657 $this->checkAccessPermission('page-delete-own', [
658 $ownPage->getUrl() . '/delete'
660 $ownPage->getUrl() => 'Delete'
663 $parent = $ownPage->chapter ?? $ownPage->book;
664 $this->visit($otherPage->getUrl())
665 ->dontSeeInElement('.action-buttons', 'Delete')
666 ->visit($otherPage->getUrl() . '/delete')
668 $this->visit($ownPage->getUrl())->visit($ownPage->getUrl() . '/delete')
670 ->seePageIs($parent->getUrl())
671 ->dontSeeInElement('.book-content', $ownPage->name);
674 public function test_page_delete_all_permission()
676 $this->giveUserPermissions($this->user, ['page-update-all']);
677 $otherPage = Page::take(1)->get()->first();
678 $this->checkAccessPermission('page-delete-all', [
679 $otherPage->getUrl() . '/delete'
681 $otherPage->getUrl() => 'Delete'
684 $parent = $otherPage->chapter ?? $otherPage->book;
685 $this->visit($otherPage->getUrl())->visit($otherPage->getUrl() . '/delete')
687 ->seePageIs($parent->getUrl())
688 ->dontSeeInElement('.book-content', $otherPage->name);
691 public function test_public_role_visible_in_user_edit_screen()
693 $user = User::first();
694 $adminRole = Role::getSystemRole('admin');
695 $publicRole = Role::getSystemRole('public');
696 $this->asAdmin()->visit('/settings/users/' . $user->id)
697 ->seeElement('[name="roles['.$adminRole->id.']"]')
698 ->seeElement('[name="roles['.$publicRole->id.']"]');
701 public function test_public_role_visible_in_role_listing()
703 $this->asAdmin()->visit('/settings/roles')
708 public function test_public_role_visible_in_default_role_setting()
710 $this->asAdmin()->visit('/settings')
711 ->seeElement('[data-system-role-name="admin"]')
712 ->seeElement('[data-system-role-name="public"]');
715 public function test_public_role_not_deleteable()
717 $this->asAdmin()->visit('/settings/roles')
720 ->click('Delete Role')
723 ->see('Cannot be deleted');
726 public function test_image_delete_own_permission()
728 $this->giveUserPermissions($this->user, ['image-update-all']);
729 $page = Page::first();
730 $image = factory(Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $this->user->id, 'updated_by' => $this->user->id]);
732 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
733 ->seeStatusCode(403);
735 $this->giveUserPermissions($this->user, ['image-delete-own']);
737 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
739 ->dontSeeInDatabase('images', ['id' => $image->id]);
742 public function test_image_delete_all_permission()
744 $this->giveUserPermissions($this->user, ['image-update-all']);
745 $admin = $this->getAdmin();
746 $page = Page::first();
747 $image = factory(Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $admin->id, 'updated_by' => $admin->id]);
749 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
750 ->seeStatusCode(403);
752 $this->giveUserPermissions($this->user, ['image-delete-own']);
754 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
755 ->seeStatusCode(403);
757 $this->giveUserPermissions($this->user, ['image-delete-all']);
759 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
761 ->dontSeeInDatabase('images', ['id' => $image->id]);
764 public function test_role_permission_removal()
766 // To cover issue fixed in f99c8ff99aee9beb8c692f36d4b84dc6e651e50a.
767 $page = Page::first();
768 $viewerRole = Role::getRole('viewer');
769 $viewer = $this->getViewer();
770 $this->actingAs($viewer)->visit($page->getUrl())->assertResponseStatus(200);
772 $this->asAdmin()->put('/settings/roles/' . $viewerRole->id, [
773 'display_name' => $viewerRole->display_name,
774 'description' => $viewerRole->description,
776 ])->assertResponseStatus(302);
778 $this->expectException(HttpException::class);
779 $this->actingAs($viewer)->visit($page->getUrl())->assertResponseStatus(404);
782 public function test_empty_state_actions_not_visible_without_permission()
784 $admin = $this->getAdmin();
786 $book = factory(Book::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id]);
787 $this->updateEntityPermissions($book);
788 $this->actingAs($this->getViewer())->visit($book->getUrl())
789 ->dontSee('Create a new page')
790 ->dontSee('Add a chapter');
793 $chapter = factory(Chapter::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id, 'book_id' => $book->id]);
794 $this->updateEntityPermissions($chapter);
795 $this->actingAs($this->getViewer())->visit($chapter->getUrl())
796 ->dontSee('Create a new page')
797 ->dontSee('Sort the current book');
800 public function test_comment_create_permission () {
801 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
803 $this->actingAs($this->user)->addComment($ownPage);
805 $this->assertResponseStatus(403);
807 $this->giveUserPermissions($this->user, ['comment-create-all']);
809 $this->actingAs($this->user)->addComment($ownPage);
810 $this->assertResponseStatus(200);
814 public function test_comment_update_own_permission () {
815 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
816 $this->giveUserPermissions($this->user, ['comment-create-all']);
817 $commentId = $this->actingAs($this->user)->addComment($ownPage);
819 // no comment-update-own
820 $this->actingAs($this->user)->updateComment($commentId);
821 $this->assertResponseStatus(403);
823 $this->giveUserPermissions($this->user, ['comment-update-own']);
825 // now has comment-update-own
826 $this->actingAs($this->user)->updateComment($commentId);
827 $this->assertResponseStatus(200);
830 public function test_comment_update_all_permission () {
831 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
832 $commentId = $this->asAdmin()->addComment($ownPage);
834 // no comment-update-all
835 $this->actingAs($this->user)->updateComment($commentId);
836 $this->assertResponseStatus(403);
838 $this->giveUserPermissions($this->user, ['comment-update-all']);
840 // now has comment-update-all
841 $this->actingAs($this->user)->updateComment($commentId);
842 $this->assertResponseStatus(200);
845 public function test_comment_delete_own_permission () {
846 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
847 $this->giveUserPermissions($this->user, ['comment-create-all']);
848 $commentId = $this->actingAs($this->user)->addComment($ownPage);
850 // no comment-delete-own
851 $this->actingAs($this->user)->deleteComment($commentId);
852 $this->assertResponseStatus(403);
854 $this->giveUserPermissions($this->user, ['comment-delete-own']);
856 // now has comment-update-own
857 $this->actingAs($this->user)->deleteComment($commentId);
858 $this->assertResponseStatus(200);
861 public function test_comment_delete_all_permission () {
862 $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
863 $commentId = $this->asAdmin()->addComment($ownPage);
865 // no comment-delete-all
866 $this->actingAs($this->user)->deleteComment($commentId);
867 $this->assertResponseStatus(403);
869 $this->giveUserPermissions($this->user, ['comment-delete-all']);
871 // now has comment-delete-all
872 $this->actingAs($this->user)->deleteComment($commentId);
873 $this->assertResponseStatus(200);
876 private function addComment($page) {
877 $comment = factory(Comment::class)->make();
878 $url = "/comment/$page->id";
880 'text' => $comment->text,
881 'html' => $comment->html
884 $this->postJson($url, $request);
885 $comment = $page->comments()->first();
886 return $comment === null ? null : $comment->id;
889 private function updateComment($commentId) {
890 $comment = factory(Comment::class)->make();
891 $url = "/comment/$commentId";
893 'text' => $comment->text,
894 'html' => $comment->html
897 return $this->putJson($url, $request);
900 private function deleteComment($commentId) {
901 $url = '/comment/' . $commentId;
902 return $this->json('DELETE', $url);