]> BookStack Code Mirror - bookstack/blob - tests/Activity/CommentsApiTest.php
Testing: Extracted copy tests to their own class
[bookstack] / tests / Activity / CommentsApiTest.php
1 <?php
2
3 namespace Tests\Activity;
4
5 use BookStack\Activity\Models\Comment;
6 use BookStack\Permissions\Permission;
7 use Tests\Api\TestsApi;
8 use Tests\TestCase;
9
10 class CommentsApiTest extends TestCase
11 {
12     use TestsApi;
13
14     public function test_endpoint_permission_controls()
15     {
16         $user = $this->users->editor();
17         $this->permissions->grantUserRolePermissions($user, [Permission::CommentDeleteAll, Permission::CommentUpdateAll]);
18
19         $page = $this->entities->page();
20         $comment = Comment::factory()->make();
21         $page->comments()->save($comment);
22         $this->actingAsForApi($user);
23
24         $actions = [
25             ['GET', '/api/comments'],
26             ['GET', "/api/comments/{$comment->id}"],
27             ['POST', "/api/comments"],
28             ['PUT', "/api/comments/{$comment->id}"],
29             ['DELETE', "/api/comments/{$comment->id}"],
30         ];
31
32         foreach ($actions as [$method, $endpoint]) {
33             $resp = $this->call($method, $endpoint);
34             $this->assertNotPermissionError($resp);
35         }
36
37         $comment = Comment::factory()->make();
38         $page->comments()->save($comment);
39         $this->getJson("/api/comments")->assertSee(['id' => $comment->id]);
40
41         $this->permissions->removeUserRolePermissions($user, [
42             Permission::CommentDeleteAll, Permission::CommentDeleteOwn,
43             Permission::CommentUpdateAll, Permission::CommentUpdateOwn,
44             Permission::CommentCreateAll
45         ]);
46
47         $this->assertPermissionError($this->json('delete', "/api/comments/{$comment->id}"));
48         $this->assertPermissionError($this->json('put', "/api/comments/{$comment->id}"));
49         $this->assertPermissionError($this->json('post', "/api/comments"));
50         $this->assertNotPermissionError($this->json('get', "/api/comments/{$comment->id}"));
51
52         $this->permissions->disableEntityInheritedPermissions($page);
53         $this->json('get', "/api/comments/{$comment->id}")->assertStatus(404);
54         $this->getJson("/api/comments")->assertDontSee(['id' => $comment->id]);
55     }
56
57     public function test_index()
58     {
59         $page = $this->entities->page();
60         Comment::query()->delete();
61
62         $comments = Comment::factory()->count(10)->make();
63         $page->comments()->saveMany($comments);
64
65         $firstComment = $comments->first();
66         $resp = $this->actingAsApiEditor()->getJson('/api/comments');
67         $resp->assertJson([
68             'data' => [
69                 [
70                     'id' => $firstComment->id,
71                     'commentable_id' => $page->id,
72                     'commentable_type' => 'page',
73                     'parent_id' => null,
74                     'local_id' => $firstComment->local_id,
75                 ],
76             ],
77         ]);
78         $resp->assertJsonCount(10, 'data');
79         $resp->assertJson(['total' => 10]);
80
81         $filtered = $this->getJson("/api/comments?filter[id]={$firstComment->id}");
82         $filtered->assertJsonCount(1, 'data');
83         $filtered->assertJson(['total' => 1]);
84     }
85
86     public function test_create()
87     {
88         $page = $this->entities->page();
89
90         $resp = $this->actingAsApiEditor()->postJson('/api/comments', [
91             'page_id' => $page->id,
92             'html' => '<p>My wonderful comment</p>',
93             'content_ref' => 'test-content-ref',
94         ]);
95         $resp->assertOk();
96         $id = $resp->json('id');
97
98         $this->assertDatabaseHas('comments', [
99             'id' => $id,
100             'commentable_id' => $page->id,
101             'commentable_type' => 'page',
102             'html' => '<p>My wonderful comment</p>',
103         ]);
104
105         $comment = Comment::query()->findOrFail($id);
106         $this->assertIsInt($comment->local_id);
107
108         $reply = $this->actingAsApiEditor()->postJson('/api/comments', [
109             'page_id' => $page->id,
110             'html' => '<p>My wonderful reply</p>',
111             'content_ref' => 'test-content-ref',
112             'reply_to' => $comment->local_id,
113         ]);
114         $reply->assertOk();
115
116         $this->assertDatabaseHas('comments', [
117             'id' => $reply->json('id'),
118             'commentable_id' => $page->id,
119             'commentable_type' => 'page',
120             'html' => '<p>My wonderful reply</p>',
121             'parent_id' => $comment->local_id,
122         ]);
123     }
124
125     public function test_read()
126     {
127         $page = $this->entities->page();
128         $user = $this->users->viewer();
129         $comment = Comment::factory()->make([
130             'html' => '<p>A lovely comment <script>hello</script></p>',
131             'created_by' => $user->id,
132             'updated_by' => $user->id,
133         ]);
134         $page->comments()->save($comment);
135         $comment->refresh();
136         $reply = Comment::factory()->make([
137             'parent_id' => $comment->local_id,
138             'html' => '<p>A lovely<script>angry</script>reply</p>',
139         ]);
140         $page->comments()->save($reply);
141
142         $resp = $this->actingAsApiEditor()->getJson("/api/comments/{$comment->id}");
143         $resp->assertJson([
144             'id' => $comment->id,
145             'commentable_id' => $page->id,
146             'commentable_type' => 'page',
147             'html' => '<p>A lovely comment </p>',
148             'archived' => false,
149             'created_by' => [
150                 'id' => $user->id,
151                 'name' => $user->name,
152             ],
153             'updated_by' => [
154                 'id' => $user->id,
155                 'name' => $user->name,
156             ],
157             'replies' => [
158                 [
159                     'id' => $reply->id,
160                     'html' => '<p>A lovelyreply</p>'
161                 ]
162             ]
163         ]);
164     }
165
166     public function test_update()
167     {
168         $page = $this->entities->page();
169         $user = $this->users->editor();
170         $this->permissions->grantUserRolePermissions($user, [Permission::CommentUpdateAll]);
171         $comment = Comment::factory()->make([
172             'html' => '<p>A lovely comment</p>',
173             'created_by' => $this->users->viewer()->id,
174             'updated_by' => $this->users->viewer()->id,
175             'parent_id' => null,
176         ]);
177         $page->comments()->save($comment);
178
179         $this->actingAsForApi($user)->putJson("/api/comments/{$comment->id}", [
180            'html' => '<p>A lovely updated comment</p>',
181         ])->assertOk();
182
183         $this->assertDatabaseHas('comments', [
184             'id' => $comment->id,
185             'html' => '<p>A lovely updated comment</p>',
186             'archived' => 0,
187         ]);
188
189         $this->putJson("/api/comments/{$comment->id}", [
190             'archived' => true,
191         ]);
192
193         $this->assertDatabaseHas('comments', [
194             'id' => $comment->id,
195             'html' => '<p>A lovely updated comment</p>',
196             'archived' => 1,
197         ]);
198
199         $this->putJson("/api/comments/{$comment->id}", [
200             'archived' => false,
201             'html' => '<p>A lovely updated again comment</p>',
202         ]);
203
204         $this->assertDatabaseHas('comments', [
205             'id' => $comment->id,
206             'html' => '<p>A lovely updated again comment</p>',
207             'archived' => 0,
208         ]);
209     }
210
211     public function test_update_cannot_archive_replies()
212     {
213         $page = $this->entities->page();
214         $user = $this->users->editor();
215         $this->permissions->grantUserRolePermissions($user, [Permission::CommentUpdateAll]);
216         $comment = Comment::factory()->make([
217             'html' => '<p>A lovely comment</p>',
218             'created_by' => $this->users->viewer()->id,
219             'updated_by' => $this->users->viewer()->id,
220             'parent_id' => 90,
221         ]);
222         $page->comments()->save($comment);
223
224         $resp = $this->actingAsForApi($user)->putJson("/api/comments/{$comment->id}", [
225             'archived' => true,
226         ]);
227
228         $this->assertEquals($this->errorResponse('Only top-level comments can be archived.', 400), $resp->json());
229         $this->assertDatabaseHas('comments', [
230             'id' => $comment->id,
231             'archived' => 0,
232         ]);
233     }
234
235     public function test_destroy()
236     {
237         $page = $this->entities->page();
238         $user = $this->users->editor();
239         $this->permissions->grantUserRolePermissions($user, [Permission::CommentDeleteAll]);
240         $comment = Comment::factory()->make([
241             'html' => '<p>A lovely comment</p>',
242         ]);
243         $page->comments()->save($comment);
244
245         $this->actingAsForApi($user)->deleteJson("/api/comments/{$comment->id}")->assertStatus(204);
246         $this->assertDatabaseMissing('comments', [
247             'id' => $comment->id,
248         ]);
249     }
250 }