3 namespace Tests\Activity;
5 use BookStack\Activity\Models\Comment;
6 use BookStack\Permissions\Permission;
7 use Tests\Api\TestsApi;
10 class CommentsApiTest extends TestCase
14 public function test_endpoint_permission_controls()
16 $user = $this->users->editor();
17 $this->permissions->grantUserRolePermissions($user, [Permission::CommentDeleteAll, Permission::CommentUpdateAll]);
19 $page = $this->entities->page();
20 $comment = Comment::factory()->make();
21 $page->comments()->save($comment);
22 $this->actingAsForApi($user);
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}"],
32 foreach ($actions as [$method, $endpoint]) {
33 $resp = $this->call($method, $endpoint);
34 $this->assertNotPermissionError($resp);
37 $comment = Comment::factory()->make();
38 $page->comments()->save($comment);
39 $this->getJson("/api/comments")->assertSee(['id' => $comment->id]);
41 $this->permissions->removeUserRolePermissions($user, [
42 Permission::CommentDeleteAll, Permission::CommentDeleteOwn,
43 Permission::CommentUpdateAll, Permission::CommentUpdateOwn,
44 Permission::CommentCreateAll
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}"));
52 $this->permissions->disableEntityInheritedPermissions($page);
53 $this->json('get', "/api/comments/{$comment->id}")->assertStatus(404);
54 $this->getJson("/api/comments")->assertDontSee(['id' => $comment->id]);
57 public function test_index()
59 $page = $this->entities->page();
60 Comment::query()->delete();
62 $comments = Comment::factory()->count(10)->make();
63 $page->comments()->saveMany($comments);
65 $firstComment = $comments->first();
66 $resp = $this->actingAsApiEditor()->getJson('/api/comments');
70 'id' => $firstComment->id,
71 'commentable_id' => $page->id,
72 'commentable_type' => 'page',
74 'local_id' => $firstComment->local_id,
78 $resp->assertJsonCount(10, 'data');
79 $resp->assertJson(['total' => 10]);
81 $filtered = $this->getJson("/api/comments?filter[id]={$firstComment->id}");
82 $filtered->assertJsonCount(1, 'data');
83 $filtered->assertJson(['total' => 1]);
86 public function test_create()
88 $page = $this->entities->page();
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',
96 $id = $resp->json('id');
98 $this->assertDatabaseHas('comments', [
100 'commentable_id' => $page->id,
101 'commentable_type' => 'page',
102 'html' => '<p>My wonderful comment</p>',
105 $comment = Comment::query()->findOrFail($id);
106 $this->assertIsInt($comment->local_id);
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,
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,
125 public function test_read()
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,
134 $page->comments()->save($comment);
136 $reply = Comment::factory()->make([
137 'parent_id' => $comment->local_id,
138 'html' => '<p>A lovely<script>angry</script>reply</p>',
140 $page->comments()->save($reply);
142 $resp = $this->actingAsApiEditor()->getJson("/api/comments/{$comment->id}");
144 'id' => $comment->id,
145 'commentable_id' => $page->id,
146 'commentable_type' => 'page',
147 'html' => '<p>A lovely comment </p>',
151 'name' => $user->name,
155 'name' => $user->name,
160 'html' => '<p>A lovelyreply</p>'
166 public function test_update()
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,
177 $page->comments()->save($comment);
179 $this->actingAsForApi($user)->putJson("/api/comments/{$comment->id}", [
180 'html' => '<p>A lovely updated comment</p>',
183 $this->assertDatabaseHas('comments', [
184 'id' => $comment->id,
185 'html' => '<p>A lovely updated comment</p>',
189 $this->putJson("/api/comments/{$comment->id}", [
193 $this->assertDatabaseHas('comments', [
194 'id' => $comment->id,
195 'html' => '<p>A lovely updated comment</p>',
199 $this->putJson("/api/comments/{$comment->id}", [
201 'html' => '<p>A lovely updated again comment</p>',
204 $this->assertDatabaseHas('comments', [
205 'id' => $comment->id,
206 'html' => '<p>A lovely updated again comment</p>',
211 public function test_update_cannot_archive_replies()
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,
222 $page->comments()->save($comment);
224 $resp = $this->actingAsForApi($user)->putJson("/api/comments/{$comment->id}", [
228 $this->assertEquals($this->errorResponse('Only top-level comments can be archived.', 400), $resp->json());
229 $this->assertDatabaseHas('comments', [
230 'id' => $comment->id,
235 public function test_destroy()
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>',
243 $page->comments()->save($comment);
245 $this->actingAsForApi($user)->deleteJson("/api/comments/{$comment->id}")->assertStatus(204);
246 $this->assertDatabaseMissing('comments', [
247 'id' => $comment->id,