3 namespace Tests\Permissions;
5 use BookStack\Activity\ActivityType;
6 use BookStack\Activity\Models\Comment;
7 use BookStack\Entities\Models\Book;
8 use BookStack\Entities\Models\Bookshelf;
9 use BookStack\Entities\Models\Chapter;
10 use BookStack\Entities\Models\Entity;
11 use BookStack\Entities\Models\Page;
12 use BookStack\Uploads\Image;
13 use BookStack\Users\Models\Role;
14 use BookStack\Users\Models\User;
15 use Illuminate\Testing\TestResponse;
18 class RolePermissionsTest extends TestCase
22 protected function setUp(): void
25 $this->user = $this->users->viewer();
28 public function test_manage_user_permission()
30 $this->actingAs($this->user)->get('/settings/users')->assertRedirect('/');
31 $this->permissions->grantUserRolePermissions($this->user, ['users-manage']);
32 $this->actingAs($this->user)->get('/settings/users')->assertOk();
35 public function test_manage_users_permission_shows_link_in_header_if_does_not_have_settings_manage_permision()
37 $usersLink = 'href="' . url('/settings/users') . '"';
38 $this->actingAs($this->user)->get('/')->assertDontSee($usersLink, false);
39 $this->permissions->grantUserRolePermissions($this->user, ['users-manage']);
40 $this->actingAs($this->user)->get('/')->assertSee($usersLink, false);
41 $this->permissions->grantUserRolePermissions($this->user, ['settings-manage', 'users-manage']);
42 $this->actingAs($this->user)->get('/')->assertDontSee($usersLink, false);
45 public function test_user_cannot_change_email_unless_they_have_manage_users_permission()
47 $originalEmail = $this->user->email;
48 $this->actingAs($this->user);
50 $resp = $this->get('/my-account/profile')->assertOk();
51 $this->withHtml($resp)->assertElementExists('input[name=email][disabled]');
52 $resp->assertSee('Unfortunately you don\'t have permission to change your email address.');
53 $this->put('/my-account/profile', [
54 'name' => 'my_new_name',
57 $this->assertDatabaseHas('users', [
58 'id' => $this->user->id,
59 'email' => $originalEmail,
60 'name' => 'my_new_name',
63 $this->permissions->grantUserRolePermissions($this->user, ['users-manage']);
65 $resp = $this->get('/my-account/profile')->assertOk();
66 $this->withHtml($resp)
67 ->assertElementNotExists('input[name=email][disabled]')
68 ->assertElementExists('input[name=email]');
70 $this->put('/my-account/profile', [
71 'name' => 'my_new_name_2',
75 $this->assertDatabaseHas('users', [
76 'id' => $this->user->id,
78 'name' => 'my_new_name_2',
82 public function test_user_roles_manage_permission()
84 $this->actingAs($this->user)->get('/settings/roles')->assertRedirect('/');
85 $this->get('/settings/roles/1')->assertRedirect('/');
86 $this->permissions->grantUserRolePermissions($this->user, ['user-roles-manage']);
87 $this->actingAs($this->user)->get('/settings/roles')->assertOk();
88 $this->get('/settings/roles/1')
93 public function test_settings_manage_permission()
95 $this->actingAs($this->user)->get('/settings/features')->assertRedirect('/');
96 $this->permissions->grantUserRolePermissions($this->user, ['settings-manage']);
97 $this->get('/settings/features')->assertOk();
99 $resp = $this->post('/settings/features', []);
100 $resp->assertRedirect('/settings/features');
101 $resp = $this->get('/settings/features');
102 $resp->assertSee('Settings successfully updated');
105 public function test_restrictions_manage_all_permission()
107 $page = $this->entities->page();
109 $this->actingAs($this->user)->get($page->getUrl())->assertDontSee('Permissions');
110 $this->get($page->getUrl('/permissions'))->assertRedirect('/');
112 $this->permissions->grantUserRolePermissions($this->user, ['restrictions-manage-all']);
114 $this->actingAs($this->user)->get($page->getUrl())->assertSee('Permissions');
116 $this->get($page->getUrl('/permissions'))
118 ->assertSee('Page Permissions');
121 public function test_restrictions_manage_own_permission()
123 $otherUsersPage = $this->entities->page();
124 $content = $this->entities->createChainBelongingToUser($this->user);
126 // Set a different creator on the page we're checking to ensure
127 // that the owner fields are checked
128 $page = $content['page']; /** @var Page $page */
129 $page->created_by = $otherUsersPage->id;
130 $page->owned_by = $this->user->id;
133 // Check can't restrict other's content
134 $this->actingAs($this->user)->get($otherUsersPage->getUrl())->assertDontSee('Permissions');
135 $this->get($otherUsersPage->getUrl('/permissions'))->assertRedirect('/');
137 // Check can't restrict own content
138 $this->actingAs($this->user)->get($page->getUrl())->assertDontSee('Permissions');
139 $this->get($page->getUrl('/permissions'))->assertRedirect('/');
141 $this->permissions->grantUserRolePermissions($this->user, ['restrictions-manage-own']);
143 // Check can't restrict other's content
144 $this->actingAs($this->user)->get($otherUsersPage->getUrl())->assertDontSee('Permissions');
145 $this->get($otherUsersPage->getUrl('/permissions'))->assertRedirect();
147 // Check can restrict own content
148 $this->actingAs($this->user)->get($page->getUrl())->assertSee('Permissions');
149 $this->get($page->getUrl('/permissions'))->assertOk();
153 * Check a standard entity access permission.
155 private function checkAccessPermission(string $permission, array $accessUrls = [], array $visibles = [])
157 foreach ($accessUrls as $url) {
158 $this->actingAs($this->user)->get($url)->assertRedirect('/');
161 foreach ($visibles as $url => $text) {
162 $resp = $this->actingAs($this->user)->get($url);
163 $this->withHtml($resp)->assertElementNotContains('.action-buttons', $text);
166 $this->permissions->grantUserRolePermissions($this->user, [$permission]);
168 foreach ($accessUrls as $url) {
169 $this->actingAs($this->user)->get($url)->assertOk();
171 foreach ($visibles as $url => $text) {
172 $this->actingAs($this->user)->get($url)->assertSee($text);
176 public function test_bookshelves_create_all_permissions()
178 $this->checkAccessPermission('bookshelf-create-all', [
181 '/shelves' => 'New Shelf',
184 $this->post('/shelves', [
185 'name' => 'test shelf',
186 'description' => 'shelf desc',
187 ])->assertRedirect('/shelves/test-shelf');
190 public function test_bookshelves_edit_own_permission()
192 /** @var Bookshelf $otherShelf */
193 $otherShelf = Bookshelf::query()->first();
194 $ownShelf = $this->entities->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
195 $ownShelf->forceFill(['owned_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
196 $this->permissions->regenerateForEntity($ownShelf);
198 $this->checkAccessPermission('bookshelf-update-own', [
199 $ownShelf->getUrl('/edit'),
201 $ownShelf->getUrl() => 'Edit',
204 $resp = $this->get($otherShelf->getUrl());
205 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Edit');
206 $this->get($otherShelf->getUrl('/edit'))->assertRedirect('/');
209 public function test_bookshelves_edit_all_permission()
211 /** @var Bookshelf $otherShelf */
212 $otherShelf = Bookshelf::query()->first();
213 $this->checkAccessPermission('bookshelf-update-all', [
214 $otherShelf->getUrl('/edit'),
216 $otherShelf->getUrl() => 'Edit',
220 public function test_bookshelves_delete_own_permission()
222 $this->permissions->grantUserRolePermissions($this->user, ['bookshelf-update-all']);
223 /** @var Bookshelf $otherShelf */
224 $otherShelf = Bookshelf::query()->first();
225 $ownShelf = $this->entities->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
226 $ownShelf->forceFill(['owned_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
227 $this->permissions->regenerateForEntity($ownShelf);
229 $this->checkAccessPermission('bookshelf-delete-own', [
230 $ownShelf->getUrl('/delete'),
232 $ownShelf->getUrl() => 'Delete',
235 $resp = $this->get($otherShelf->getUrl());
236 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Delete');
237 $this->get($otherShelf->getUrl('/delete'))->assertRedirect('/');
239 $this->get($ownShelf->getUrl());
240 $this->delete($ownShelf->getUrl())->assertRedirect('/shelves');
241 $this->get('/shelves')->assertDontSee($ownShelf->name);
244 public function test_bookshelves_delete_all_permission()
246 $this->permissions->grantUserRolePermissions($this->user, ['bookshelf-update-all']);
247 /** @var Bookshelf $otherShelf */
248 $otherShelf = Bookshelf::query()->first();
249 $this->checkAccessPermission('bookshelf-delete-all', [
250 $otherShelf->getUrl('/delete'),
252 $otherShelf->getUrl() => 'Delete',
255 $this->delete($otherShelf->getUrl())->assertRedirect('/shelves');
256 $this->get('/shelves')->assertDontSee($otherShelf->name);
259 public function test_books_create_all_permissions()
261 $this->checkAccessPermission('book-create-all', [
264 '/books' => 'Create New Book',
267 $this->post('/books', [
268 'name' => 'test book',
269 'description' => 'book desc',
270 ])->assertRedirect('/books/test-book');
273 public function test_books_edit_own_permission()
275 /** @var Book $otherBook */
276 $otherBook = Book::query()->take(1)->get()->first();
277 $ownBook = $this->entities->createChainBelongingToUser($this->user)['book'];
278 $this->checkAccessPermission('book-update-own', [
279 $ownBook->getUrl() . '/edit',
281 $ownBook->getUrl() => 'Edit',
284 $resp = $this->get($otherBook->getUrl());
285 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Edit');
286 $this->get($otherBook->getUrl('/edit'))->assertRedirect('/');
289 public function test_books_edit_all_permission()
291 /** @var Book $otherBook */
292 $otherBook = Book::query()->take(1)->get()->first();
293 $this->checkAccessPermission('book-update-all', [
294 $otherBook->getUrl() . '/edit',
296 $otherBook->getUrl() => 'Edit',
300 public function test_books_delete_own_permission()
302 $this->permissions->grantUserRolePermissions($this->user, ['book-update-all']);
303 /** @var Book $otherBook */
304 $otherBook = Book::query()->take(1)->get()->first();
305 $ownBook = $this->entities->createChainBelongingToUser($this->user)['book'];
306 $this->checkAccessPermission('book-delete-own', [
307 $ownBook->getUrl() . '/delete',
309 $ownBook->getUrl() => 'Delete',
312 $resp = $this->get($otherBook->getUrl());
313 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Delete');
314 $this->get($otherBook->getUrl('/delete'))->assertRedirect('/');
315 $this->get($ownBook->getUrl());
316 $this->delete($ownBook->getUrl())->assertRedirect('/books');
317 $this->get('/books')->assertDontSee($ownBook->name);
320 public function test_books_delete_all_permission()
322 $this->permissions->grantUserRolePermissions($this->user, ['book-update-all']);
323 /** @var Book $otherBook */
324 $otherBook = Book::query()->take(1)->get()->first();
325 $this->checkAccessPermission('book-delete-all', [
326 $otherBook->getUrl() . '/delete',
328 $otherBook->getUrl() => 'Delete',
331 $this->get($otherBook->getUrl());
332 $this->delete($otherBook->getUrl())->assertRedirect('/books');
333 $this->get('/books')->assertDontSee($otherBook->name);
336 public function test_chapter_create_own_permissions()
338 /** @var Book $book */
339 $book = Book::query()->take(1)->get()->first();
340 $ownBook = $this->entities->createChainBelongingToUser($this->user)['book'];
341 $this->checkAccessPermission('chapter-create-own', [
342 $ownBook->getUrl('/create-chapter'),
344 $ownBook->getUrl() => 'New Chapter',
347 $this->post($ownBook->getUrl('/create-chapter'), [
348 'name' => 'test chapter',
349 'description' => 'chapter desc',
350 ])->assertRedirect($ownBook->getUrl('/chapter/test-chapter'));
352 $resp = $this->get($book->getUrl());
353 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'New Chapter');
354 $this->get($book->getUrl('/create-chapter'))->assertRedirect('/');
357 public function test_chapter_create_all_permissions()
359 $book = $this->entities->book();
360 $this->checkAccessPermission('chapter-create-all', [
361 $book->getUrl('/create-chapter'),
363 $book->getUrl() => 'New Chapter',
366 $this->post($book->getUrl('/create-chapter'), [
367 'name' => 'test chapter',
368 'description' => 'chapter desc',
369 ])->assertRedirect($book->getUrl('/chapter/test-chapter'));
372 public function test_chapter_edit_own_permission()
374 /** @var Chapter $otherChapter */
375 $otherChapter = Chapter::query()->first();
376 $ownChapter = $this->entities->createChainBelongingToUser($this->user)['chapter'];
377 $this->checkAccessPermission('chapter-update-own', [
378 $ownChapter->getUrl() . '/edit',
380 $ownChapter->getUrl() => 'Edit',
383 $resp = $this->get($otherChapter->getUrl());
384 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Edit');
385 $this->get($otherChapter->getUrl('/edit'))->assertRedirect('/');
388 public function test_chapter_edit_all_permission()
390 /** @var Chapter $otherChapter */
391 $otherChapter = Chapter::query()->take(1)->get()->first();
392 $this->checkAccessPermission('chapter-update-all', [
393 $otherChapter->getUrl() . '/edit',
395 $otherChapter->getUrl() => 'Edit',
399 public function test_chapter_delete_own_permission()
401 $this->permissions->grantUserRolePermissions($this->user, ['chapter-update-all']);
402 /** @var Chapter $otherChapter */
403 $otherChapter = Chapter::query()->first();
404 $ownChapter = $this->entities->createChainBelongingToUser($this->user)['chapter'];
405 $this->checkAccessPermission('chapter-delete-own', [
406 $ownChapter->getUrl() . '/delete',
408 $ownChapter->getUrl() => 'Delete',
411 $bookUrl = $ownChapter->book->getUrl();
412 $resp = $this->get($otherChapter->getUrl());
413 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Delete');
414 $this->get($otherChapter->getUrl('/delete'))->assertRedirect('/');
415 $this->get($ownChapter->getUrl());
416 $this->delete($ownChapter->getUrl())->assertRedirect($bookUrl);
417 $resp = $this->get($bookUrl);
418 $this->withHtml($resp)->assertElementNotContains('.book-content', $ownChapter->name);
421 public function test_chapter_delete_all_permission()
423 $this->permissions->grantUserRolePermissions($this->user, ['chapter-update-all']);
424 /** @var Chapter $otherChapter */
425 $otherChapter = Chapter::query()->first();
426 $this->checkAccessPermission('chapter-delete-all', [
427 $otherChapter->getUrl() . '/delete',
429 $otherChapter->getUrl() => 'Delete',
432 $bookUrl = $otherChapter->book->getUrl();
433 $this->get($otherChapter->getUrl());
434 $this->delete($otherChapter->getUrl())->assertRedirect($bookUrl);
435 $resp = $this->get($bookUrl);
436 $this->withHtml($resp)->assertElementNotContains('.book-content', $otherChapter->name);
439 public function test_page_create_own_permissions()
441 $book = $this->entities->book();
442 $chapter = $this->entities->chapter();
444 $entities = $this->entities->createChainBelongingToUser($this->user);
445 $ownBook = $entities['book'];
446 $ownChapter = $entities['chapter'];
448 $createUrl = $ownBook->getUrl('/create-page');
449 $createUrlChapter = $ownChapter->getUrl('/create-page');
450 $accessUrls = [$createUrl, $createUrlChapter];
452 foreach ($accessUrls as $url) {
453 $this->actingAs($this->user)->get($url)->assertRedirect('/');
456 $this->checkAccessPermission('page-create-own', [], [
457 $ownBook->getUrl() => 'New Page',
458 $ownChapter->getUrl() => 'New Page',
461 $this->permissions->grantUserRolePermissions($this->user, ['page-create-own']);
463 foreach ($accessUrls as $index => $url) {
464 $resp = $this->actingAs($this->user)->get($url);
465 $expectedUrl = Page::query()->where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
466 $resp->assertRedirect($expectedUrl);
469 $this->get($createUrl);
470 /** @var Page $draft */
471 $draft = Page::query()->where('draft', '=', true)->orderBy('id', 'desc')->first();
472 $this->post($draft->getUrl(), [
473 'name' => 'test page',
474 'html' => 'page desc',
475 ])->assertRedirect($ownBook->getUrl('/page/test-page'));
477 $resp = $this->get($book->getUrl());
478 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'New Page');
479 $this->get($book->getUrl('/create-page'))->assertRedirect('/');
481 $resp = $this->get($chapter->getUrl());
482 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'New Page');
483 $this->get($chapter->getUrl('/create-page'))->assertRedirect('/');
486 public function test_page_create_all_permissions()
488 $book = $this->entities->book();
489 $chapter = $this->entities->chapter();
490 $createUrl = $book->getUrl('/create-page');
492 $createUrlChapter = $chapter->getUrl('/create-page');
493 $accessUrls = [$createUrl, $createUrlChapter];
495 foreach ($accessUrls as $url) {
496 $this->actingAs($this->user)->get($url)->assertRedirect('/');
499 $this->checkAccessPermission('page-create-all', [], [
500 $book->getUrl() => 'New Page',
501 $chapter->getUrl() => 'New Page',
504 $this->permissions->grantUserRolePermissions($this->user, ['page-create-all']);
506 foreach ($accessUrls as $index => $url) {
507 $resp = $this->actingAs($this->user)->get($url);
508 $expectedUrl = Page::query()->where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
509 $resp->assertRedirect($expectedUrl);
512 $this->get($createUrl);
513 /** @var Page $draft */
514 $draft = Page::query()->where('draft', '=', true)->orderByDesc('id')->first();
515 $this->post($draft->getUrl(), [
516 'name' => 'test page',
517 'html' => 'page desc',
518 ])->assertRedirect($book->getUrl('/page/test-page'));
520 $this->get($chapter->getUrl('/create-page'));
521 /** @var Page $draft */
522 $draft = Page::query()->where('draft', '=', true)->orderByDesc('id')->first();
523 $this->post($draft->getUrl(), [
524 'name' => 'new test page',
525 'html' => 'page desc',
526 ])->assertRedirect($book->getUrl('/page/new-test-page'));
529 public function test_page_edit_own_permission()
531 /** @var Page $otherPage */
532 $otherPage = Page::query()->first();
533 $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
534 $this->checkAccessPermission('page-update-own', [
535 $ownPage->getUrl() . '/edit',
537 $ownPage->getUrl() => 'Edit',
540 $resp = $this->get($otherPage->getUrl());
541 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Edit');
542 $this->get($otherPage->getUrl() . '/edit')->assertRedirect('/');
545 public function test_page_edit_all_permission()
547 /** @var Page $otherPage */
548 $otherPage = Page::query()->first();
549 $this->checkAccessPermission('page-update-all', [
550 $otherPage->getUrl('/edit'),
552 $otherPage->getUrl() => 'Edit',
556 public function test_page_delete_own_permission()
558 $this->permissions->grantUserRolePermissions($this->user, ['page-update-all']);
559 /** @var Page $otherPage */
560 $otherPage = Page::query()->first();
561 $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
562 $this->checkAccessPermission('page-delete-own', [
563 $ownPage->getUrl() . '/delete',
565 $ownPage->getUrl() => 'Delete',
568 $parent = $ownPage->chapter ?? $ownPage->book;
569 $resp = $this->get($otherPage->getUrl());
570 $this->withHtml($resp)->assertElementNotContains('.action-buttons', 'Delete');
571 $this->get($otherPage->getUrl('/delete'))->assertRedirect('/');
572 $this->get($ownPage->getUrl());
573 $this->delete($ownPage->getUrl())->assertRedirect($parent->getUrl());
574 $resp = $this->get($parent->getUrl());
575 $this->withHtml($resp)->assertElementNotContains('.book-content', $ownPage->name);
578 public function test_page_delete_all_permission()
580 $this->permissions->grantUserRolePermissions($this->user, ['page-update-all']);
581 /** @var Page $otherPage */
582 $otherPage = Page::query()->first();
584 $this->checkAccessPermission('page-delete-all', [
585 $otherPage->getUrl() . '/delete',
587 $otherPage->getUrl() => 'Delete',
590 /** @var Entity $parent */
591 $parent = $otherPage->chapter ?? $otherPage->book;
592 $this->get($otherPage->getUrl());
594 $this->delete($otherPage->getUrl())->assertRedirect($parent->getUrl());
595 $this->get($parent->getUrl())->assertDontSee($otherPage->name);
599 public function test_image_delete_own_permission()
601 $this->permissions->grantUserRolePermissions($this->user, ['image-update-all']);
602 $page = $this->entities->page();
603 $image = Image::factory()->create([
604 'uploaded_to' => $page->id,
605 'created_by' => $this->user->id,
606 'updated_by' => $this->user->id,
609 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)->assertStatus(403);
611 $this->permissions->grantUserRolePermissions($this->user, ['image-delete-own']);
613 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)->assertOk();
614 $this->assertDatabaseMissing('images', ['id' => $image->id]);
617 public function test_image_delete_all_permission()
619 $this->permissions->grantUserRolePermissions($this->user, ['image-update-all']);
620 $admin = $this->users->admin();
621 $page = $this->entities->page();
622 $image = Image::factory()->create(['uploaded_to' => $page->id, 'created_by' => $admin->id, 'updated_by' => $admin->id]);
624 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)->assertStatus(403);
626 $this->permissions->grantUserRolePermissions($this->user, ['image-delete-own']);
628 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)->assertStatus(403);
630 $this->permissions->grantUserRolePermissions($this->user, ['image-delete-all']);
632 $this->actingAs($this->user)->json('delete', '/images/' . $image->id)->assertOk();
633 $this->assertDatabaseMissing('images', ['id' => $image->id]);
636 public function test_empty_state_actions_not_visible_without_permission()
638 $admin = $this->users->admin();
640 $book = Book::factory()->create(['created_by' => $admin->id, 'updated_by' => $admin->id]);
641 $this->permissions->regenerateForEntity($book);
642 $this->actingAs($this->users->viewer())->get($book->getUrl())
643 ->assertDontSee('Create a new page')
644 ->assertDontSee('Add a chapter');
647 $chapter = Chapter::factory()->create(['created_by' => $admin->id, 'updated_by' => $admin->id, 'book_id' => $book->id]);
648 $this->permissions->regenerateForEntity($chapter);
649 $this->actingAs($this->users->viewer())->get($chapter->getUrl())
650 ->assertDontSee('Create a new page')
651 ->assertDontSee('Sort the current book');
654 public function test_comment_create_permission()
656 $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
658 $this->actingAs($this->user)
659 ->addComment($ownPage)
662 $this->permissions->grantUserRolePermissions($this->user, ['comment-create-all']);
664 $this->actingAs($this->user)
665 ->addComment($ownPage)
669 public function test_comment_update_own_permission()
671 $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
672 $this->permissions->grantUserRolePermissions($this->user, ['comment-create-all']);
673 $this->actingAs($this->user)->addComment($ownPage);
674 /** @var Comment $comment */
675 $comment = $ownPage->comments()->latest()->first();
677 // no comment-update-own
678 $this->actingAs($this->user)->updateComment($comment)->assertStatus(403);
680 $this->permissions->grantUserRolePermissions($this->user, ['comment-update-own']);
682 // now has comment-update-own
683 $this->actingAs($this->user)->updateComment($comment)->assertOk();
686 public function test_comment_update_all_permission()
688 /** @var Page $ownPage */
689 $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
690 $this->asAdmin()->addComment($ownPage);
691 /** @var Comment $comment */
692 $comment = $ownPage->comments()->latest()->first();
694 // no comment-update-all
695 $this->actingAs($this->user)->updateComment($comment)->assertStatus(403);
697 $this->permissions->grantUserRolePermissions($this->user, ['comment-update-all']);
699 // now has comment-update-all
700 $this->actingAs($this->user)->updateComment($comment)->assertOk();
703 public function test_comment_delete_own_permission()
705 /** @var Page $ownPage */
706 $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
707 $this->permissions->grantUserRolePermissions($this->user, ['comment-create-all']);
708 $this->actingAs($this->user)->addComment($ownPage);
710 /** @var Comment $comment */
711 $comment = $ownPage->comments()->latest()->first();
713 // no comment-delete-own
714 $this->actingAs($this->user)->deleteComment($comment)->assertStatus(403);
716 $this->permissions->grantUserRolePermissions($this->user, ['comment-delete-own']);
718 // now has comment-update-own
719 $this->actingAs($this->user)->deleteComment($comment)->assertOk();
722 public function test_comment_delete_all_permission()
724 /** @var Page $ownPage */
725 $ownPage = $this->entities->createChainBelongingToUser($this->user)['page'];
726 $this->asAdmin()->addComment($ownPage);
727 /** @var Comment $comment */
728 $comment = $ownPage->comments()->latest()->first();
730 // no comment-delete-all
731 $this->actingAs($this->user)->deleteComment($comment)->assertStatus(403);
733 $this->permissions->grantUserRolePermissions($this->user, ['comment-delete-all']);
735 // now has comment-delete-all
736 $this->actingAs($this->user)->deleteComment($comment)->assertOk();
739 private function addComment(Page $page): TestResponse
741 return $this->postJson("/comment/$page->id", ['html' => '<p>New comment content</p>']);
744 private function updateComment(Comment $comment): TestResponse
746 return $this->putJson("/comment/{$comment->id}", ['html' => '<p>Updated comment content</p>']);
749 private function deleteComment(Comment $comment): TestResponse
751 return $this->json('DELETE', '/comment/' . $comment->id);