]> BookStack Code Mirror - bookstack/blob - tests/Permissions/RolesTest.php
add missing @param in method comment
[bookstack] / tests / Permissions / RolesTest.php
1 <?php namespace Tests;
2
3 use BookStack\Page;
4 use BookStack\Repos\PermissionsRepo;
5 use BookStack\Role;
6 use Laravel\BrowserKitTesting\HttpException;
7 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
8
9 class RolesTest extends BrowserKitTest
10 {
11     protected $user;
12
13     public function setUp()
14     {
15         parent::setUp();
16         $this->user = $this->getViewer();
17     }
18
19     /**
20      * Give the given user some permissions.
21      * @param \BookStack\User $user
22      * @param array $permissions
23      */
24     protected function giveUserPermissions(\BookStack\User $user, $permissions = [])
25     {
26         $newRole = $this->createNewRole($permissions);
27         $user->attachRole($newRole);
28         $user->load('roles');
29         $user->permissions(false);
30     }
31
32     /**
33      * Create a new basic role for testing purposes.
34      * @param array $permissions
35      * @return Role
36      */
37     protected function createNewRole($permissions = [])
38     {
39         $permissionRepo = app(PermissionsRepo::class);
40         $roleData = factory(\BookStack\Role::class)->make()->toArray();
41         $roleData['permissions'] = array_flip($permissions);
42         return $permissionRepo->saveNewRole($roleData);
43     }
44
45     public function test_admin_can_see_settings()
46     {
47         $this->asAdmin()->visit('/settings')->see('Settings');
48     }
49
50     public function test_cannot_delete_admin_role()
51     {
52         $adminRole = \BookStack\Role::getRole('admin');
53         $deletePageUrl = '/settings/roles/delete/' . $adminRole->id;
54         $this->asAdmin()->visit($deletePageUrl)
55             ->press('Confirm')
56             ->seePageIs($deletePageUrl)
57             ->see('cannot be deleted');
58     }
59
60     public function test_role_cannot_be_deleted_if_default()
61     {
62         $newRole = $this->createNewRole();
63         $this->setSettings(['registration-role' => $newRole->id]);
64
65         $deletePageUrl = '/settings/roles/delete/' . $newRole->id;
66         $this->asAdmin()->visit($deletePageUrl)
67             ->press('Confirm')
68             ->seePageIs($deletePageUrl)
69             ->see('cannot be deleted');
70     }
71
72     public function test_role_create_update_delete_flow()
73     {
74         $testRoleName = 'Test Role';
75         $testRoleDesc = 'a little test description';
76         $testRoleUpdateName = 'An Super Updated role';
77
78         // Creation
79         $this->asAdmin()->visit('/settings')
80             ->click('Roles')
81             ->seePageIs('/settings/roles')
82             ->click('Create New Role')
83             ->type('Test Role', 'display_name')
84             ->type('A little test description', 'description')
85             ->press('Save Role')
86             ->seeInDatabase('roles', ['display_name' => $testRoleName, 'name' => 'test-role', 'description' => $testRoleDesc])
87             ->seePageIs('/settings/roles');
88         // Updating
89         $this->asAdmin()->visit('/settings/roles')
90             ->see($testRoleDesc)
91             ->click($testRoleName)
92             ->type($testRoleUpdateName, '#display_name')
93             ->press('Save Role')
94             ->seeInDatabase('roles', ['display_name' => $testRoleUpdateName, 'name' => 'test-role', 'description' => $testRoleDesc])
95             ->seePageIs('/settings/roles');
96         // Deleting
97         $this->asAdmin()->visit('/settings/roles')
98             ->click($testRoleUpdateName)
99             ->click('Delete Role')
100             ->see($testRoleUpdateName)
101             ->press('Confirm')
102             ->seePageIs('/settings/roles')
103             ->dontSee($testRoleUpdateName);
104     }
105
106     public function test_manage_user_permission()
107     {
108         $this->actingAs($this->user)->visit('/settings/users')
109             ->seePageIs('/');
110         $this->giveUserPermissions($this->user, ['users-manage']);
111         $this->actingAs($this->user)->visit('/settings/users')
112             ->seePageIs('/settings/users');
113     }
114
115     public function test_user_roles_manage_permission()
116     {
117         $this->actingAs($this->user)->visit('/settings/roles')
118             ->seePageIs('/')->visit('/settings/roles/1')->seePageIs('/');
119         $this->giveUserPermissions($this->user, ['user-roles-manage']);
120         $this->actingAs($this->user)->visit('/settings/roles')
121             ->seePageIs('/settings/roles')->click('Admin')
122             ->see('Edit Role');
123     }
124
125     public function test_settings_manage_permission()
126     {
127         $this->actingAs($this->user)->visit('/settings')
128             ->seePageIs('/');
129         $this->giveUserPermissions($this->user, ['settings-manage']);
130         $this->actingAs($this->user)->visit('/settings')
131             ->seePageIs('/settings')->press('Save Settings')->see('Settings Saved');
132     }
133
134     public function test_restrictions_manage_all_permission()
135     {
136         $page = \BookStack\Page::take(1)->get()->first();
137         $this->actingAs($this->user)->visit($page->getUrl())
138             ->dontSee('Permissions')
139             ->visit($page->getUrl() . '/permissions')
140             ->seePageIs('/');
141         $this->giveUserPermissions($this->user, ['restrictions-manage-all']);
142         $this->actingAs($this->user)->visit($page->getUrl())
143             ->see('Permissions')
144             ->click('Permissions')
145             ->see('Page Permissions')->seePageIs($page->getUrl() . '/permissions');
146     }
147
148     public function test_restrictions_manage_own_permission()
149     {
150         $otherUsersPage = \BookStack\Page::first();
151         $content = $this->createEntityChainBelongingToUser($this->user);
152         // Check can't restrict other's content
153         $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
154             ->dontSee('Permissions')
155             ->visit($otherUsersPage->getUrl() . '/permissions')
156             ->seePageIs('/');
157         // Check can't restrict own content
158         $this->actingAs($this->user)->visit($content['page']->getUrl())
159             ->dontSee('Permissions')
160             ->visit($content['page']->getUrl() . '/permissions')
161             ->seePageIs('/');
162
163         $this->giveUserPermissions($this->user, ['restrictions-manage-own']);
164
165         // Check can't restrict other's content
166         $this->actingAs($this->user)->visit($otherUsersPage->getUrl())
167             ->dontSee('Permissions')
168             ->visit($otherUsersPage->getUrl() . '/permissions')
169             ->seePageIs('/');
170         // Check can restrict own content
171         $this->actingAs($this->user)->visit($content['page']->getUrl())
172             ->see('Permissions')
173             ->click('Permissions')
174             ->seePageIs($content['page']->getUrl() . '/permissions');
175     }
176
177     /**
178      * Check a standard entity access permission
179      * @param string $permission
180      * @param array $accessUrls Urls that are only accessible after having the permission
181      * @param array $visibles Check this text, In the buttons toolbar, is only visible with the permission
182      */
183     private function checkAccessPermission($permission, $accessUrls = [], $visibles = [])
184     {
185         foreach ($accessUrls as $url) {
186             $this->actingAs($this->user)->visit($url)
187                 ->seePageIs('/');
188         }
189         foreach ($visibles as $url => $text) {
190             $this->actingAs($this->user)->visit($url)
191                 ->dontSeeInElement('.action-buttons',$text);
192         }
193
194         $this->giveUserPermissions($this->user, [$permission]);
195
196         foreach ($accessUrls as $url) {
197             $this->actingAs($this->user)->visit($url)
198                 ->seePageIs($url);
199         }
200         foreach ($visibles as $url => $text) {
201             $this->actingAs($this->user)->visit($url)
202                 ->see($text);
203         }
204     }
205
206     public function test_books_create_all_permissions()
207     {
208         $this->checkAccessPermission('book-create-all', [
209             '/create-book'
210         ], [
211             '/books' => 'Create New Book'
212         ]);
213
214         $this->visit('/create-book')
215             ->type('test book', 'name')
216             ->type('book desc', 'description')
217             ->press('Save Book')
218             ->seePageIs('/books/test-book');
219     }
220
221     public function test_books_edit_own_permission()
222     {
223         $otherBook = \BookStack\Book::take(1)->get()->first();
224         $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
225         $this->checkAccessPermission('book-update-own', [
226             $ownBook->getUrl() . '/edit'
227         ], [
228             $ownBook->getUrl() => 'Edit'
229         ]);
230
231         $this->visit($otherBook->getUrl())
232             ->dontSeeInElement('.action-buttons', 'Edit')
233             ->visit($otherBook->getUrl() . '/edit')
234             ->seePageIs('/');
235     }
236
237     public function test_books_edit_all_permission()
238     {
239         $otherBook = \BookStack\Book::take(1)->get()->first();
240         $this->checkAccessPermission('book-update-all', [
241             $otherBook->getUrl() . '/edit'
242         ], [
243             $otherBook->getUrl() => 'Edit'
244         ]);
245     }
246
247     public function test_books_delete_own_permission()
248     {
249         $this->giveUserPermissions($this->user, ['book-update-all']);
250         $otherBook = \BookStack\Book::take(1)->get()->first();
251         $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
252         $this->checkAccessPermission('book-delete-own', [
253             $ownBook->getUrl() . '/delete'
254         ], [
255             $ownBook->getUrl() => 'Delete'
256         ]);
257
258         $this->visit($otherBook->getUrl())
259             ->dontSeeInElement('.action-buttons', 'Delete')
260             ->visit($otherBook->getUrl() . '/delete')
261             ->seePageIs('/');
262         $this->visit($ownBook->getUrl())->visit($ownBook->getUrl() . '/delete')
263             ->press('Confirm')
264             ->seePageIs('/books')
265             ->dontSee($ownBook->name);
266     }
267
268     public function test_books_delete_all_permission()
269     {
270         $this->giveUserPermissions($this->user, ['book-update-all']);
271         $otherBook = \BookStack\Book::take(1)->get()->first();
272         $this->checkAccessPermission('book-delete-all', [
273             $otherBook->getUrl() . '/delete'
274         ], [
275             $otherBook->getUrl() => 'Delete'
276         ]);
277
278         $this->visit($otherBook->getUrl())->visit($otherBook->getUrl() . '/delete')
279             ->press('Confirm')
280             ->seePageIs('/books')
281             ->dontSee($otherBook->name);
282     }
283
284     public function test_chapter_create_own_permissions()
285     {
286         $book = \BookStack\Book::take(1)->get()->first();
287         $ownBook = $this->createEntityChainBelongingToUser($this->user)['book'];
288         $this->checkAccessPermission('chapter-create-own', [
289             $ownBook->getUrl('/create-chapter')
290         ], [
291             $ownBook->getUrl() => 'New Chapter'
292         ]);
293
294         $this->visit($ownBook->getUrl('/create-chapter'))
295             ->type('test chapter', 'name')
296             ->type('chapter desc', 'description')
297             ->press('Save Chapter')
298             ->seePageIs($ownBook->getUrl('/chapter/test-chapter'));
299
300         $this->visit($book->getUrl())
301             ->dontSeeInElement('.action-buttons', 'New Chapter')
302             ->visit($book->getUrl('/create-chapter'))
303             ->seePageIs('/');
304     }
305
306     public function test_chapter_create_all_permissions()
307     {
308         $book = \BookStack\Book::take(1)->get()->first();
309         $this->checkAccessPermission('chapter-create-all', [
310             $book->getUrl('/create-chapter')
311         ], [
312             $book->getUrl() => 'New Chapter'
313         ]);
314
315         $this->visit($book->getUrl('/create-chapter'))
316             ->type('test chapter', 'name')
317             ->type('chapter desc', 'description')
318             ->press('Save Chapter')
319             ->seePageIs($book->getUrl('/chapter/test-chapter'));
320     }
321
322     public function test_chapter_edit_own_permission()
323     {
324         $otherChapter = \BookStack\Chapter::take(1)->get()->first();
325         $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
326         $this->checkAccessPermission('chapter-update-own', [
327             $ownChapter->getUrl() . '/edit'
328         ], [
329             $ownChapter->getUrl() => 'Edit'
330         ]);
331
332         $this->visit($otherChapter->getUrl())
333             ->dontSeeInElement('.action-buttons', 'Edit')
334             ->visit($otherChapter->getUrl() . '/edit')
335             ->seePageIs('/');
336     }
337
338     public function test_chapter_edit_all_permission()
339     {
340         $otherChapter = \BookStack\Chapter::take(1)->get()->first();
341         $this->checkAccessPermission('chapter-update-all', [
342             $otherChapter->getUrl() . '/edit'
343         ], [
344             $otherChapter->getUrl() => 'Edit'
345         ]);
346     }
347
348     public function test_chapter_delete_own_permission()
349     {
350         $this->giveUserPermissions($this->user, ['chapter-update-all']);
351         $otherChapter = \BookStack\Chapter::take(1)->get()->first();
352         $ownChapter = $this->createEntityChainBelongingToUser($this->user)['chapter'];
353         $this->checkAccessPermission('chapter-delete-own', [
354             $ownChapter->getUrl() . '/delete'
355         ], [
356             $ownChapter->getUrl() => 'Delete'
357         ]);
358
359         $bookUrl = $ownChapter->book->getUrl();
360         $this->visit($otherChapter->getUrl())
361             ->dontSeeInElement('.action-buttons', 'Delete')
362             ->visit($otherChapter->getUrl() . '/delete')
363             ->seePageIs('/');
364         $this->visit($ownChapter->getUrl())->visit($ownChapter->getUrl() . '/delete')
365             ->press('Confirm')
366             ->seePageIs($bookUrl)
367             ->dontSeeInElement('.book-content', $ownChapter->name);
368     }
369
370     public function test_chapter_delete_all_permission()
371     {
372         $this->giveUserPermissions($this->user, ['chapter-update-all']);
373         $otherChapter = \BookStack\Chapter::take(1)->get()->first();
374         $this->checkAccessPermission('chapter-delete-all', [
375             $otherChapter->getUrl() . '/delete'
376         ], [
377             $otherChapter->getUrl() => 'Delete'
378         ]);
379
380         $bookUrl = $otherChapter->book->getUrl();
381         $this->visit($otherChapter->getUrl())->visit($otherChapter->getUrl() . '/delete')
382             ->press('Confirm')
383             ->seePageIs($bookUrl)
384             ->dontSeeInElement('.book-content', $otherChapter->name);
385     }
386
387     public function test_page_create_own_permissions()
388     {
389         $book = \BookStack\Book::first();
390         $chapter = \BookStack\Chapter::first();
391
392         $entities = $this->createEntityChainBelongingToUser($this->user);
393         $ownBook = $entities['book'];
394         $ownChapter = $entities['chapter'];
395
396         $createUrl = $ownBook->getUrl('/create-page');
397         $createUrlChapter = $ownChapter->getUrl('/create-page');
398         $accessUrls = [$createUrl, $createUrlChapter];
399
400         foreach ($accessUrls as $url) {
401             $this->actingAs($this->user)->visit($url)
402                 ->seePageIs('/');
403         }
404
405         $this->checkAccessPermission('page-create-own', [], [
406             $ownBook->getUrl() => 'New Page',
407             $ownChapter->getUrl() => 'New Page'
408         ]);
409
410         $this->giveUserPermissions($this->user, ['page-create-own']);
411
412         foreach ($accessUrls as $index => $url) {
413             $this->actingAs($this->user)->visit($url);
414             $expectedUrl = \BookStack\Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
415             $this->seePageIs($expectedUrl);
416         }
417
418         $this->visit($createUrl)
419             ->type('test page', 'name')
420             ->type('page desc', 'html')
421             ->press('Save Page')
422             ->seePageIs($ownBook->getUrl('/page/test-page'));
423
424         $this->visit($book->getUrl())
425             ->dontSeeInElement('.action-buttons', 'New Page')
426             ->visit($book->getUrl() . '/create-page')
427             ->seePageIs('/');
428         $this->visit($chapter->getUrl())
429             ->dontSeeInElement('.action-buttons', 'New Page')
430             ->visit($chapter->getUrl() . '/create-page')
431             ->seePageIs('/');
432     }
433
434     public function test_page_create_all_permissions()
435     {
436         $book = \BookStack\Book::take(1)->get()->first();
437         $chapter = \BookStack\Chapter::take(1)->get()->first();
438         $baseUrl = $book->getUrl() . '/page';
439         $createUrl = $book->getUrl('/create-page');
440
441         $createUrlChapter = $chapter->getUrl('/create-page');
442         $accessUrls = [$createUrl, $createUrlChapter];
443
444         foreach ($accessUrls as $url) {
445             $this->actingAs($this->user)->visit($url)
446                 ->seePageIs('/');
447         }
448
449         $this->checkAccessPermission('page-create-all', [], [
450             $book->getUrl() => 'New Page',
451             $chapter->getUrl() => 'New Page'
452         ]);
453
454         $this->giveUserPermissions($this->user, ['page-create-all']);
455
456         foreach ($accessUrls as $index => $url) {
457             $this->actingAs($this->user)->visit($url);
458             $expectedUrl = \BookStack\Page::where('draft', '=', true)->orderBy('id', 'desc')->first()->getUrl();
459             $this->seePageIs($expectedUrl);
460         }
461
462         $this->visit($createUrl)
463             ->type('test page', 'name')
464             ->type('page desc', 'html')
465             ->press('Save Page')
466             ->seePageIs($book->getUrl('/page/test-page'));
467
468         $this->visit($chapter->getUrl('/create-page'))
469             ->type('new test page', 'name')
470             ->type('page desc', 'html')
471             ->press('Save Page')
472             ->seePageIs($book->getUrl('/page/new-test-page'));
473     }
474
475     public function test_page_edit_own_permission()
476     {
477         $otherPage = \BookStack\Page::take(1)->get()->first();
478         $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
479         $this->checkAccessPermission('page-update-own', [
480             $ownPage->getUrl() . '/edit'
481         ], [
482             $ownPage->getUrl() => 'Edit'
483         ]);
484
485         $this->visit($otherPage->getUrl())
486             ->dontSeeInElement('.action-buttons', 'Edit')
487             ->visit($otherPage->getUrl() . '/edit')
488             ->seePageIs('/');
489     }
490
491     public function test_page_edit_all_permission()
492     {
493         $otherPage = \BookStack\Page::take(1)->get()->first();
494         $this->checkAccessPermission('page-update-all', [
495             $otherPage->getUrl() . '/edit'
496         ], [
497             $otherPage->getUrl() => 'Edit'
498         ]);
499     }
500
501     public function test_page_delete_own_permission()
502     {
503         $this->giveUserPermissions($this->user, ['page-update-all']);
504         $otherPage = \BookStack\Page::take(1)->get()->first();
505         $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
506         $this->checkAccessPermission('page-delete-own', [
507             $ownPage->getUrl() . '/delete'
508         ], [
509             $ownPage->getUrl() => 'Delete'
510         ]);
511
512         $bookUrl = $ownPage->book->getUrl();
513         $this->visit($otherPage->getUrl())
514             ->dontSeeInElement('.action-buttons', 'Delete')
515             ->visit($otherPage->getUrl() . '/delete')
516             ->seePageIs('/');
517         $this->visit($ownPage->getUrl())->visit($ownPage->getUrl() . '/delete')
518             ->press('Confirm')
519             ->seePageIs($bookUrl)
520             ->dontSeeInElement('.book-content', $ownPage->name);
521     }
522
523     public function test_page_delete_all_permission()
524     {
525         $this->giveUserPermissions($this->user, ['page-update-all']);
526         $otherPage = \BookStack\Page::take(1)->get()->first();
527         $this->checkAccessPermission('page-delete-all', [
528             $otherPage->getUrl() . '/delete'
529         ], [
530             $otherPage->getUrl() => 'Delete'
531         ]);
532
533         $bookUrl = $otherPage->book->getUrl();
534         $this->visit($otherPage->getUrl())->visit($otherPage->getUrl() . '/delete')
535             ->press('Confirm')
536             ->seePageIs($bookUrl)
537             ->dontSeeInElement('.book-content', $otherPage->name);
538     }
539
540     public function test_public_role_visible_in_user_edit_screen()
541     {
542         $user = \BookStack\User::first();
543         $this->asAdmin()->visit('/settings/users/' . $user->id)
544             ->seeElement('#roles-admin')
545             ->seeElement('#roles-public');
546     }
547
548     public function test_public_role_visible_in_role_listing()
549     {
550         $this->asAdmin()->visit('/settings/roles')
551             ->see('Admin')
552             ->see('Public');
553     }
554
555     public function test_public_role_visible_in_default_role_setting()
556     {
557         $this->asAdmin()->visit('/settings')
558             ->seeElement('[data-role-name="admin"]')
559             ->seeElement('[data-role-name="public"]');
560
561     }
562
563     public function test_public_role_not_deleteable()
564     {
565         $this->asAdmin()->visit('/settings/roles')
566             ->click('Public')
567             ->see('Edit Role')
568             ->click('Delete Role')
569             ->press('Confirm')
570             ->see('Delete Role')
571             ->see('Cannot be deleted');
572     }
573
574     public function test_image_delete_own_permission()
575     {
576         $this->giveUserPermissions($this->user, ['image-update-all']);
577         $page = \BookStack\Page::first();
578         $image = factory(\BookStack\Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $this->user->id, 'updated_by' => $this->user->id]);
579
580         $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
581             ->seeStatusCode(403);
582
583         $this->giveUserPermissions($this->user, ['image-delete-own']);
584
585         $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
586             ->seeStatusCode(200)
587             ->dontSeeInDatabase('images', ['id' => $image->id]);
588     }
589
590     public function test_image_delete_all_permission()
591     {
592         $this->giveUserPermissions($this->user, ['image-update-all']);
593         $admin = $this->getAdmin();
594         $page = \BookStack\Page::first();
595         $image = factory(\BookStack\Image::class)->create(['uploaded_to' => $page->id, 'created_by' => $admin->id, 'updated_by' => $admin->id]);
596
597         $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
598             ->seeStatusCode(403);
599
600         $this->giveUserPermissions($this->user, ['image-delete-own']);
601
602         $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
603             ->seeStatusCode(403);
604
605         $this->giveUserPermissions($this->user, ['image-delete-all']);
606
607         $this->actingAs($this->user)->json('delete', '/images/' . $image->id)
608             ->seeStatusCode(200)
609             ->dontSeeInDatabase('images', ['id' => $image->id]);
610     }
611
612     public function test_role_permission_removal()
613     {
614         // To cover issue fixed in f99c8ff99aee9beb8c692f36d4b84dc6e651e50a.
615         $page = Page::first();
616         $viewerRole = \BookStack\Role::getRole('viewer');
617         $viewer = $this->getViewer();
618         $this->actingAs($viewer)->visit($page->getUrl())->assertResponseStatus(200);
619
620         $this->asAdmin()->put('/settings/roles/' . $viewerRole->id, [
621             'display_name' => $viewerRole->display_name,
622             'description' => $viewerRole->description,
623             'permission' => []
624         ])->assertResponseStatus(302);
625
626         $this->expectException(HttpException::class);
627         $this->actingAs($viewer)->visit($page->getUrl())->assertResponseStatus(404);
628     }
629
630     public function test_empty_state_actions_not_visible_without_permission()
631     {
632         $admin = $this->getAdmin();
633         // Book links
634         $book = factory(\BookStack\Book::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id]);
635         $this->updateEntityPermissions($book);
636         $this->actingAs($this->getViewer())->visit($book->getUrl())
637             ->dontSee('Create a new page')
638             ->dontSee('Add a chapter');
639
640         // Chapter links
641         $chapter = factory(\BookStack\Chapter::class)->create(['created_by' => $admin->id, 'updated_by' => $admin->id, 'book_id' => $book->id]);
642         $this->updateEntityPermissions($chapter);
643         $this->actingAs($this->getViewer())->visit($chapter->getUrl())
644             ->dontSee('Create a new page')
645             ->dontSee('Sort the current book');
646     }
647
648     public function test_comment_create_permission () {
649         $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
650
651         $this->actingAs($this->user)->addComment($ownPage);
652
653         $this->assertResponseStatus(403);
654
655         $this->giveUserPermissions($this->user, ['comment-create-all']);
656
657         $this->actingAs($this->user)->addComment($ownPage);
658         $this->assertResponseStatus(200);
659     }
660
661
662     public function test_comment_update_own_permission () {
663         $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
664         $this->giveUserPermissions($this->user, ['comment-create-all']);
665         $commentId = $this->actingAs($this->user)->addComment($ownPage);
666
667         // no comment-update-own
668         $this->actingAs($this->user)->updateComment($commentId);
669         $this->assertResponseStatus(403);
670
671         $this->giveUserPermissions($this->user, ['comment-update-own']);
672
673         // now has comment-update-own
674         $this->actingAs($this->user)->updateComment($commentId);
675         $this->assertResponseStatus(200);
676     }
677
678     public function test_comment_update_all_permission () {
679         $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
680         $commentId = $this->asAdmin()->addComment($ownPage);
681
682         // no comment-update-all
683         $this->actingAs($this->user)->updateComment($commentId);
684         $this->assertResponseStatus(403);
685
686         $this->giveUserPermissions($this->user, ['comment-update-all']);
687
688         // now has comment-update-all
689         $this->actingAs($this->user)->updateComment($commentId);
690         $this->assertResponseStatus(200);
691     }
692
693     public function test_comment_delete_own_permission () {
694         $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
695         $this->giveUserPermissions($this->user, ['comment-create-all']);
696         $commentId = $this->actingAs($this->user)->addComment($ownPage);
697
698         // no comment-delete-own
699         $this->actingAs($this->user)->deleteComment($commentId);
700         $this->assertResponseStatus(403);
701
702         $this->giveUserPermissions($this->user, ['comment-delete-own']);
703
704         // now has comment-update-own
705         $this->actingAs($this->user)->deleteComment($commentId);
706         $this->assertResponseStatus(200);
707     }
708
709     public function test_comment_delete_all_permission () {
710         $ownPage = $this->createEntityChainBelongingToUser($this->user)['page'];
711         $commentId = $this->asAdmin()->addComment($ownPage);
712
713         // no comment-delete-all
714         $this->actingAs($this->user)->deleteComment($commentId);
715         $this->assertResponseStatus(403);
716
717         $this->giveUserPermissions($this->user, ['comment-delete-all']);
718
719         // now has comment-delete-all
720         $this->actingAs($this->user)->deleteComment($commentId);
721         $this->assertResponseStatus(200);
722     }
723
724     private function addComment($page) {
725         $comment = factory(\BookStack\Comment::class)->make();
726         $url = "/ajax/page/$page->id/comment";
727         $request = [
728             'text' => $comment->text,
729             'html' => $comment->html
730         ];
731
732         $this->postJson($url, $request);
733         $comment = $page->comments()->first();
734         return $comment === null ? null : $comment->id;
735     }
736
737     private function updateComment($commentId) {
738         $comment = factory(\BookStack\Comment::class)->make();
739         $url = "/ajax/comment/$commentId";
740         $request = [
741             'text' => $comment->text,
742             'html' => $comment->html
743         ];
744
745         return $this->putJson($url, $request);
746     }
747
748     private function deleteComment($commentId) {
749          $url = '/ajax/comment/' . $commentId;
750          return $this->json('DELETE', $url);
751     }
752
753 }