aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-07-09 14:15:11 +0200
committerChocobozzz <me@florianbigard.com>2021-07-20 15:27:18 +0200
commit12edc1495a36b2199f1bf1ba37f50c7b694be382 (patch)
tree3abfe2e5b54076de73fbfa25386d0313fc3b7242
parenta54618880c394ad7571f3f3222dc96ec2dd10d9a (diff)
downloadPeerTube-12edc1495a36b2199f1bf1ba37f50c7b694be382.tar.gz
PeerTube-12edc1495a36b2199f1bf1ba37f50c7b694be382.tar.zst
PeerTube-12edc1495a36b2199f1bf1ba37f50c7b694be382.zip
Introduce comments command
-rw-r--r--scripts/benchmark.ts30
-rw-r--r--server/controllers/api/videos/comment.ts6
-rw-r--r--server/lib/moderation.ts2
-rw-r--r--server/tests/api/activitypub/cleaner.ts25
-rw-r--r--server/tests/api/check-params/video-comments.ts27
-rw-r--r--server/tests/api/moderation/abuses.ts29
-rw-r--r--server/tests/api/moderation/blocklist-notification.ts7
-rw-r--r--server/tests/api/moderation/blocklist.ts196
-rw-r--r--server/tests/api/notifications/comments-notifications.ts123
-rw-r--r--server/tests/api/notifications/moderation-notifications.ts20
-rw-r--r--server/tests/api/server/bulk.ts63
-rw-r--r--server/tests/api/server/follows.ts53
-rw-r--r--server/tests/api/server/handle-down.ts69
-rw-r--r--server/tests/api/server/stats.ts3
-rw-r--r--server/tests/api/users/users.ts3
-rw-r--r--server/tests/api/videos/multiple-servers.ts99
-rw-r--r--server/tests/api/videos/video-comments.ts193
-rw-r--r--server/tests/cli/update-host.ts3
-rw-r--r--server/tests/feeds/feeds.ts9
-rw-r--r--server/tests/plugins/action-hooks.ts11
-rw-r--r--server/tests/plugins/filter-hooks.ts50
-rw-r--r--shared/extra-utils/server/servers.ts3
-rw-r--r--shared/extra-utils/videos/comments-command.ts132
-rw-r--r--shared/extra-utils/videos/index.ts3
-rw-r--r--shared/extra-utils/videos/streaming-playlists-command.ts2
-rw-r--r--shared/extra-utils/videos/video-comments.ts138
-rw-r--r--shared/models/videos/comment/index.ts1
-rw-r--r--shared/models/videos/comment/video-comment-create.model.ts3
-rw-r--r--shared/models/videos/comment/video-comment.model.ts7
29 files changed, 613 insertions, 697 deletions
diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts
index fcfc67bf7..321b07c94 100644
--- a/scripts/benchmark.ts
+++ b/scripts/benchmark.ts
@@ -1,19 +1,10 @@
1import { registerTSPaths } from '../server/helpers/register-ts-paths'
2registerTSPaths()
3
4import * as autocannon from 'autocannon' 1import * as autocannon from 'autocannon'
5import {
6 addVideoCommentReply,
7 addVideoCommentThread,
8 flushAndRunServer,
9 getVideosList,
10 killallServers,
11 ServerInfo,
12 setAccessTokensToServers,
13 uploadVideo
14} from '@shared/extra-utils'
15import { Video, VideoPrivacy } from '@shared/models'
16import { writeJson } from 'fs-extra' 2import { writeJson } from 'fs-extra'
3import { flushAndRunServer, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '@shared/extra-utils'
4import { Video, VideoPrivacy } from '@shared/models'
5import { registerTSPaths } from '../server/helpers/register-ts-paths'
6
7registerTSPaths()
17 8
18let server: ServerInfo 9let server: ServerInfo
19let video: Video 10let video: Video
@@ -228,18 +219,17 @@ async function prepare () {
228 219
229 for (let i = 0; i < 10; i++) { 220 for (let i = 0; i < 10; i++) {
230 const text = 'my super first comment' 221 const text = 'my super first comment'
231 const res = await addVideoCommentThread(server.url, server.accessToken, video.id, text) 222 const created = await server.commentsCommand.createThread({ videoId: video.id, text })
232 threadId = res.body.comment.id 223 threadId = created.id
233 224
234 const text1 = 'my super answer to thread 1' 225 const text1 = 'my super answer to thread 1'
235 const childCommentRes = await addVideoCommentReply(server.url, server.accessToken, video.id, threadId, text1) 226 const child = await server.commentsCommand.addReply({ videoId: video.id, toCommentId: threadId, text: text1 })
236 const childCommentId = childCommentRes.body.comment.id
237 227
238 const text2 = 'my super answer to answer of thread 1' 228 const text2 = 'my super answer to answer of thread 1'
239 await addVideoCommentReply(server.url, server.accessToken, video.id, childCommentId, text2) 229 await server.commentsCommand.addReply({ videoId: video.id, toCommentId: child.id, text: text2 })
240 230
241 const text3 = 'my second answer to thread 1' 231 const text3 = 'my second answer to thread 1'
242 await addVideoCommentReply(server.url, server.accessToken, video.id, threadId, text3) 232 await server.commentsCommand.addReply({ videoId: video.id, toCommentId: threadId, text: text3 })
243 } 233 }
244 234
245 for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) { 235 for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) {
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts
index e6f28c1cb..6a25511e5 100644
--- a/server/controllers/api/videos/comment.ts
+++ b/server/controllers/api/videos/comment.ts
@@ -1,7 +1,7 @@
1import * as express from 'express' 1import * as express from 'express'
2import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' 2import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
3import { ResultList, ThreadsResultList, UserRight } from '../../../../shared/models' 3import { ResultList, ThreadsResultList, UserRight, VideoCommentCreate } from '../../../../shared/models'
4import { VideoCommentCreate } from '../../../../shared/models/videos/comment/video-comment.model' 4import { VideoCommentThreads } from '../../../../shared/models/videos/comment/video-comment.model'
5import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger' 5import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger'
6import { getFormattedObjects } from '../../../helpers/utils' 6import { getFormattedObjects } from '../../../helpers/utils'
7import { sequelizeTypescript } from '../../../initializers/database' 7import { sequelizeTypescript } from '../../../initializers/database'
@@ -136,7 +136,7 @@ async function listVideoThreads (req: express.Request, res: express.Response) {
136 return res.json({ 136 return res.json({
137 ...getFormattedObjects(resultList.data, resultList.total), 137 ...getFormattedObjects(resultList.data, resultList.total),
138 totalNotDeletedComments: resultList.totalNotDeletedComments 138 totalNotDeletedComments: resultList.totalNotDeletedComments
139 }) 139 } as VideoCommentThreads)
140} 140}
141 141
142async function listVideoThreadComments (req: express.Request, res: express.Response) { 142async function listVideoThreadComments (req: express.Request, res: express.Response) {
diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts
index 14e00518e..a42ab5b7f 100644
--- a/server/lib/moderation.ts
+++ b/server/lib/moderation.ts
@@ -23,7 +23,7 @@ import { ActivityCreate } from '../../shared/models/activitypub'
23import { VideoObject } from '../../shared/models/activitypub/objects' 23import { VideoObject } from '../../shared/models/activitypub/objects'
24import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object' 24import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object'
25import { LiveVideoCreate, VideoCreate, VideoImportCreate } from '../../shared/models/videos' 25import { LiveVideoCreate, VideoCreate, VideoImportCreate } from '../../shared/models/videos'
26import { VideoCommentCreate } from '../../shared/models/videos/comment/video-comment.model' 26import { VideoCommentCreate } from '../../shared/models/videos/comment'
27import { ActorModel } from '../models/actor/actor' 27import { ActorModel } from '../models/actor/actor'
28import { UserModel } from '../models/user/user' 28import { UserModel } from '../models/user/user'
29import { VideoModel } from '../models/video/video' 29import { VideoModel } from '../models/video/video'
diff --git a/server/tests/api/activitypub/cleaner.ts b/server/tests/api/activitypub/cleaner.ts
index 75ef56ce3..27f17b4d6 100644
--- a/server/tests/api/activitypub/cleaner.ts
+++ b/server/tests/api/activitypub/cleaner.ts
@@ -7,16 +7,19 @@ import {
7 closeAllSequelize, 7 closeAllSequelize,
8 deleteAll, 8 deleteAll,
9 doubleFollow, 9 doubleFollow,
10 flushAndRunMultipleServers,
10 getCount, 11 getCount,
12 getVideo,
13 rateVideo,
11 selectQuery, 14 selectQuery,
15 ServerInfo,
16 setAccessTokensToServers,
12 setVideoField, 17 setVideoField,
13 updateQuery, 18 updateQuery,
14 wait 19 uploadVideoAndGetId,
15} from '../../../../shared/extra-utils' 20 wait,
16import { flushAndRunMultipleServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index' 21 waitJobs
17import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 22} from '@shared/extra-utils'
18import { addVideoCommentThread, getVideoCommentThreads } from '../../../../shared/extra-utils/videos/video-comments'
19import { getVideo, rateVideo, uploadVideoAndGetId } from '../../../../shared/extra-utils/videos/videos'
20 23
21const expect = chai.expect 24const expect = chai.expect
22 25
@@ -63,7 +66,7 @@ describe('Test AP cleaner', function () {
63 for (const server of servers) { 66 for (const server of servers) {
64 for (const uuid of videoUUIDs) { 67 for (const uuid of videoUUIDs) {
65 await rateVideo(server.url, server.accessToken, uuid, 'like') 68 await rateVideo(server.url, server.accessToken, uuid, 'like')
66 await addVideoCommentThread(server.url, server.accessToken, uuid, 'comment') 69 await server.commentsCommand.createThread({ videoId: uuid, text: 'comment' })
67 } 70 }
68 } 71 }
69 72
@@ -172,8 +175,8 @@ describe('Test AP cleaner', function () {
172 this.timeout(20000) 175 this.timeout(20000)
173 176
174 { 177 {
175 const res = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 5) 178 const { total } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID1 })
176 expect(res.body.total).to.equal(3) 179 expect(total).to.equal(3)
177 } 180 }
178 181
179 await deleteAll(servers[2].internalServerNumber, 'videoComment') 182 await deleteAll(servers[2].internalServerNumber, 'videoComment')
@@ -182,8 +185,8 @@ describe('Test AP cleaner', function () {
182 await waitJobs(servers) 185 await waitJobs(servers)
183 186
184 { 187 {
185 const res = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 5) 188 const { total } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID1 })
186 expect(res.body.total).to.equal(2) 189 expect(total).to.equal(2)
187 } 190 }
188 }) 191 })
189 192
diff --git a/server/tests/api/check-params/video-comments.ts b/server/tests/api/check-params/video-comments.ts
index a38420851..ff94645cb 100644
--- a/server/tests/api/check-params/video-comments.ts
+++ b/server/tests/api/check-params/video-comments.ts
@@ -2,9 +2,11 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { VideoCreateResult } from '@shared/models' 5import { HttpStatusCode } from '@shared/core-utils'
6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
7import { 6import {
7 checkBadCountPagination,
8 checkBadSortPagination,
9 checkBadStartPagination,
8 cleanupTests, 10 cleanupTests,
9 createUser, 11 createUser,
10 flushAndRunServer, 12 flushAndRunServer,
@@ -15,13 +17,8 @@ import {
15 setAccessTokensToServers, 17 setAccessTokensToServers,
16 uploadVideo, 18 uploadVideo,
17 userLogin 19 userLogin
18} from '../../../../shared/extra-utils' 20} from '@shared/extra-utils'
19import { 21import { VideoCreateResult } from '@shared/models'
20 checkBadCountPagination,
21 checkBadSortPagination,
22 checkBadStartPagination
23} from '../../../../shared/extra-utils/requests/check-api-params'
24import { addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments'
25 22
26const expect = chai.expect 23const expect = chai.expect
27 24
@@ -50,8 +47,8 @@ describe('Test video comments API validator', function () {
50 } 47 }
51 48
52 { 49 {
53 const res = await addVideoCommentThread(server.url, server.accessToken, video.uuid, 'coucou') 50 const created = await server.commentsCommand.createThread({ videoId: video.uuid, text: 'coucou' })
54 commentId = res.body.comment.id 51 commentId = created.id
55 pathComment = '/api/v1/videos/' + video.uuid + '/comments/' + commentId 52 pathComment = '/api/v1/videos/' + video.uuid + '/comments/' + commentId
56 } 53 }
57 54
@@ -281,8 +278,8 @@ describe('Test video comments API validator', function () {
281 let commentToDelete: number 278 let commentToDelete: number
282 279
283 { 280 {
284 const res = await addVideoCommentThread(server.url, userAccessToken, video.uuid, 'hello') 281 const created = await server.commentsCommand.createThread({ videoId: video.uuid, text: 'hello' })
285 commentToDelete = res.body.comment.id 282 commentToDelete = created.id
286 } 283 }
287 284
288 const path = '/api/v1/videos/' + video.uuid + '/comments/' + commentToDelete 285 const path = '/api/v1/videos/' + video.uuid + '/comments/' + commentToDelete
@@ -301,8 +298,8 @@ describe('Test video comments API validator', function () {
301 } 298 }
302 299
303 { 300 {
304 const res = await addVideoCommentThread(server.url, server.accessToken, anotherVideoUUID, 'hello') 301 const created = await server.commentsCommand.createThread({ videoId: anotherVideoUUID, text: 'hello' })
305 commentToDelete = res.body.comment.id 302 commentToDelete = created.id
306 } 303 }
307 304
308 const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete 305 const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete
diff --git a/server/tests/api/moderation/abuses.ts b/server/tests/api/moderation/abuses.ts
index a2bd07b12..e428cf1a8 100644
--- a/server/tests/api/moderation/abuses.ts
+++ b/server/tests/api/moderation/abuses.ts
@@ -4,14 +4,11 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 AbusesCommand, 6 AbusesCommand,
7 addVideoCommentThread,
8 cleanupTests, 7 cleanupTests,
9 createUser, 8 createUser,
10 deleteVideoComment,
11 doubleFollow, 9 doubleFollow,
12 flushAndRunMultipleServers, 10 flushAndRunMultipleServers,
13 generateUserAccessToken, 11 generateUserAccessToken,
14 getVideoCommentThreads,
15 getVideoIdFromUUID, 12 getVideoIdFromUUID,
16 getVideosList, 13 getVideosList,
17 removeUser, 14 removeUser,
@@ -23,7 +20,7 @@ import {
23 userLogin, 20 userLogin,
24 waitJobs 21 waitJobs
25} from '@shared/extra-utils' 22} from '@shared/extra-utils'
26import { AbuseMessage, AbusePredefinedReasonsString, AbuseState, AdminAbuse, UserAbuse, VideoComment } from '@shared/models' 23import { AbuseMessage, AbusePredefinedReasonsString, AbuseState, AdminAbuse, UserAbuse } from '@shared/models'
27 24
28const expect = chai.expect 25const expect = chai.expect
29 26
@@ -399,14 +396,14 @@ describe('Test abuses', function () {
399 396
400 describe('Comment abuses', function () { 397 describe('Comment abuses', function () {
401 398
402 async function getComment (url: string, videoIdArg: number | string) { 399 async function getComment (server: ServerInfo, videoIdArg: number | string) {
403 const videoId = typeof videoIdArg === 'string' 400 const videoId = typeof videoIdArg === 'string'
404 ? await getVideoIdFromUUID(url, videoIdArg) 401 ? await getVideoIdFromUUID(server.url, videoIdArg)
405 : videoIdArg 402 : videoIdArg
406 403
407 const res = await getVideoCommentThreads(url, videoId, 0, 5) 404 const { data } = await server.commentsCommand.listThreads({ videoId })
408 405
409 return res.body.data[0] as VideoComment 406 return data[0]
410 } 407 }
411 408
412 before(async function () { 409 before(async function () {
@@ -415,8 +412,8 @@ describe('Test abuses', function () {
415 servers[0].video = await uploadVideoAndGetId({ server: servers[0], videoName: 'server 1' }) 412 servers[0].video = await uploadVideoAndGetId({ server: servers[0], videoName: 'server 1' })
416 servers[1].video = await uploadVideoAndGetId({ server: servers[1], videoName: 'server 2' }) 413 servers[1].video = await uploadVideoAndGetId({ server: servers[1], videoName: 'server 2' })
417 414
418 await addVideoCommentThread(servers[0].url, servers[0].accessToken, servers[0].video.id, 'comment server 1') 415 await servers[0].commentsCommand.createThread({ videoId: servers[0].video.id, text: 'comment server 1' })
419 await addVideoCommentThread(servers[1].url, servers[1].accessToken, servers[1].video.id, 'comment server 2') 416 await servers[1].commentsCommand.createThread({ videoId: servers[1].video.id, text: 'comment server 2' })
420 417
421 await waitJobs(servers) 418 await waitJobs(servers)
422 }) 419 })
@@ -424,7 +421,7 @@ describe('Test abuses', function () {
424 it('Should report abuse on a comment', async function () { 421 it('Should report abuse on a comment', async function () {
425 this.timeout(15000) 422 this.timeout(15000)
426 423
427 const comment = await getComment(servers[0].url, servers[0].video.id) 424 const comment = await getComment(servers[0], servers[0].video.id)
428 425
429 const reason = 'it is a bad comment' 426 const reason = 'it is a bad comment'
430 await commands[0].report({ commentId: comment.id, reason }) 427 await commands[0].report({ commentId: comment.id, reason })
@@ -434,7 +431,7 @@ describe('Test abuses', function () {
434 431
435 it('Should have 1 comment abuse on server 1 and 0 on server 2', async function () { 432 it('Should have 1 comment abuse on server 1 and 0 on server 2', async function () {
436 { 433 {
437 const comment = await getComment(servers[0].url, servers[0].video.id) 434 const comment = await getComment(servers[0], servers[0].video.id)
438 const body = await commands[0].getAdminList({ filter: 'comment' }) 435 const body = await commands[0].getAdminList({ filter: 'comment' })
439 436
440 expect(body.total).to.equal(1) 437 expect(body.total).to.equal(1)
@@ -469,7 +466,7 @@ describe('Test abuses', function () {
469 it('Should report abuse on a remote comment', async function () { 466 it('Should report abuse on a remote comment', async function () {
470 this.timeout(10000) 467 this.timeout(10000)
471 468
472 const comment = await getComment(servers[0].url, servers[1].video.uuid) 469 const comment = await getComment(servers[0], servers[1].video.uuid)
473 470
474 const reason = 'it is a really bad comment' 471 const reason = 'it is a really bad comment'
475 await commands[0].report({ commentId: comment.id, reason }) 472 await commands[0].report({ commentId: comment.id, reason })
@@ -478,7 +475,7 @@ describe('Test abuses', function () {
478 }) 475 })
479 476
480 it('Should have 2 comment abuses on server 1 and 1 on server 2', async function () { 477 it('Should have 2 comment abuses on server 1 and 1 on server 2', async function () {
481 const commentServer2 = await getComment(servers[0].url, servers[1].video.id) 478 const commentServer2 = await getComment(servers[0], servers[1].video.id)
482 479
483 { 480 {
484 const body = await commands[0].getAdminList({ filter: 'comment' }) 481 const body = await commands[0].getAdminList({ filter: 'comment' })
@@ -537,9 +534,9 @@ describe('Test abuses', function () {
537 it('Should keep the comment abuse when deleting the comment', async function () { 534 it('Should keep the comment abuse when deleting the comment', async function () {
538 this.timeout(10000) 535 this.timeout(10000)
539 536
540 const commentServer2 = await getComment(servers[0].url, servers[1].video.id) 537 const commentServer2 = await getComment(servers[0], servers[1].video.id)
541 538
542 await deleteVideoComment(servers[0].url, servers[0].accessToken, servers[1].video.uuid, commentServer2.id) 539 await servers[0].commentsCommand.delete({ videoId: servers[1].video.uuid, commentId: commentServer2.id })
543 540
544 await waitJobs(servers) 541 await waitJobs(servers)
545 542
diff --git a/server/tests/api/moderation/blocklist-notification.ts b/server/tests/api/moderation/blocklist-notification.ts
index 5b9699816..a077d8739 100644
--- a/server/tests/api/moderation/blocklist-notification.ts
+++ b/server/tests/api/moderation/blocklist-notification.ts
@@ -3,7 +3,6 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoCommentThread,
7 cleanupTests, 6 cleanupTests,
8 createUser, 7 createUser,
9 doubleFollow, 8 doubleFollow,
@@ -59,7 +58,11 @@ describe('Test blocklist', function () {
59 } 58 }
60 59
61 { 60 {
62 await addVideoCommentThread(servers[1].url, remoteUserToken, videoUUID, '@user2@' + servers[0].host + ' hello') 61 await servers[1].commentsCommand.createThread({
62 token: remoteUserToken,
63 videoId: videoUUID,
64 text: '@user2@' + servers[0].host + ' hello'
65 })
63 } 66 }
64 67
65 { 68 {
diff --git a/server/tests/api/moderation/blocklist.ts b/server/tests/api/moderation/blocklist.ts
index 1b8860571..00cb6c65c 100644
--- a/server/tests/api/moderation/blocklist.ts
+++ b/server/tests/api/moderation/blocklist.ts
@@ -3,55 +3,47 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoCommentReply,
7 addVideoCommentThread,
8 BlocklistCommand, 6 BlocklistCommand,
9 cleanupTests, 7 cleanupTests,
8 CommentsCommand,
10 createUser, 9 createUser,
11 deleteVideoComment,
12 doubleFollow, 10 doubleFollow,
13 findCommentId,
14 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
15 getUserNotifications, 12 getUserNotifications,
16 getVideoCommentThreads,
17 getVideosList, 13 getVideosList,
18 getVideosListWithToken, 14 getVideosListWithToken,
19 getVideoThreadComments,
20 ServerInfo, 15 ServerInfo,
21 setAccessTokensToServers, 16 setAccessTokensToServers,
22 uploadVideo, 17 uploadVideo,
23 userLogin, 18 userLogin,
24 waitJobs 19 waitJobs
25} from '@shared/extra-utils' 20} from '@shared/extra-utils'
26import { UserNotification, UserNotificationType, Video, VideoComment, VideoCommentThreadTree } from '@shared/models' 21import { UserNotification, UserNotificationType, Video } from '@shared/models'
27 22
28const expect = chai.expect 23const expect = chai.expect
29 24
30async function checkAllVideos (url: string, token: string) { 25async function checkAllVideos (server: ServerInfo, token: string) {
31 { 26 {
32 const res = await getVideosListWithToken(url, token) 27 const res = await getVideosListWithToken(server.url, token)
33 28
34 expect(res.body.data).to.have.lengthOf(5) 29 expect(res.body.data).to.have.lengthOf(5)
35 } 30 }
36 31
37 { 32 {
38 const res = await getVideosList(url) 33 const res = await getVideosList(server.url)
39 34
40 expect(res.body.data).to.have.lengthOf(5) 35 expect(res.body.data).to.have.lengthOf(5)
41 } 36 }
42} 37}
43 38
44async function checkAllComments (url: string, token: string, videoUUID: string) { 39async function checkAllComments (server: ServerInfo, token: string, videoUUID: string) {
45 const resThreads = await getVideoCommentThreads(url, videoUUID, 0, 25, '-createdAt', token) 40 const { data } = await server.commentsCommand.listThreads({ videoId: videoUUID, start: 0, count: 25, sort: '-createdAt', token })
46 41
47 const allThreads: VideoComment[] = resThreads.body.data 42 const threads = data.filter(t => t.isDeleted === false)
48 const threads = allThreads.filter(t => t.isDeleted === false)
49 expect(threads).to.have.lengthOf(2) 43 expect(threads).to.have.lengthOf(2)
50 44
51 for (const thread of threads) { 45 for (const thread of threads) {
52 const res = await getVideoThreadComments(url, videoUUID, thread.id, token) 46 const tree = await server.commentsCommand.getThread({ videoId: videoUUID, threadId: thread.id, token })
53
54 const tree: VideoCommentThreadTree = res.body
55 expect(tree.children).to.have.lengthOf(1) 47 expect(tree.children).to.have.lengthOf(1)
56 } 48 }
57} 49}
@@ -61,10 +53,9 @@ async function checkCommentNotification (
61 comment: { server: ServerInfo, token: string, videoUUID: string, text: string }, 53 comment: { server: ServerInfo, token: string, videoUUID: string, text: string },
62 check: 'presence' | 'absence' 54 check: 'presence' | 'absence'
63) { 55) {
64 const resComment = await addVideoCommentThread(comment.server.url, comment.token, comment.videoUUID, comment.text) 56 const command = comment.server.commentsCommand
65 const created = resComment.body.comment as VideoComment 57
66 const threadId = created.id 58 const { threadId, createdAt } = await command.createThread({ token: comment.token, videoId: comment.videoUUID, text: comment.text })
67 const createdAt = created.createdAt
68 59
69 await waitJobs([ mainServer, comment.server ]) 60 await waitJobs([ mainServer, comment.server ])
70 61
@@ -75,7 +66,7 @@ async function checkCommentNotification (
75 if (check === 'presence') expect(commentNotifications).to.have.lengthOf(1) 66 if (check === 'presence') expect(commentNotifications).to.have.lengthOf(1)
76 else expect(commentNotifications).to.have.lengthOf(0) 67 else expect(commentNotifications).to.have.lengthOf(0)
77 68
78 await deleteVideoComment(comment.server.url, comment.token, comment.videoUUID, threadId) 69 await command.delete({ token: comment.token, videoId: comment.videoUUID, commentId: threadId })
79 70
80 await waitJobs([ mainServer, comment.server ]) 71 await waitJobs([ mainServer, comment.server ])
81} 72}
@@ -90,6 +81,7 @@ describe('Test blocklist', function () {
90 let userToken2: string 81 let userToken2: string
91 82
92 let command: BlocklistCommand 83 let command: BlocklistCommand
84 let commentsCommand: CommentsCommand[]
93 85
94 before(async function () { 86 before(async function () {
95 this.timeout(120000) 87 this.timeout(120000)
@@ -97,6 +89,9 @@ describe('Test blocklist', function () {
97 servers = await flushAndRunMultipleServers(3) 89 servers = await flushAndRunMultipleServers(3)
98 await setAccessTokensToServers(servers) 90 await setAccessTokensToServers(servers)
99 91
92 command = servers[0].blocklistCommand
93 commentsCommand = servers.map(s => s.commentsCommand)
94
100 { 95 {
101 const user = { username: 'user1', password: 'password' } 96 const user = { username: 'user1', password: 'password' }
102 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password }) 97 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
@@ -139,30 +134,33 @@ describe('Test blocklist', function () {
139 await doubleFollow(servers[0], servers[2]) 134 await doubleFollow(servers[0], servers[2])
140 135
141 { 136 {
142 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID1, 'comment root 1') 137 const created = await commentsCommand[0].createThread({ videoId: videoUUID1, text: 'comment root 1' })
143 const resReply = await addVideoCommentReply(servers[0].url, userToken1, videoUUID1, resComment.body.comment.id, 'comment user 1') 138 const reply = await commentsCommand[0].addReply({
144 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resReply.body.comment.id, 'comment root 1') 139 token: userToken1,
140 videoId: videoUUID1,
141 toCommentId: created.id,
142 text: 'comment user 1'
143 })
144 await commentsCommand[0].addReply({ videoId: videoUUID1, toCommentId: reply.id, text: 'comment root 1' })
145 } 145 }
146 146
147 { 147 {
148 const resComment = await addVideoCommentThread(servers[0].url, userToken1, videoUUID1, 'comment user 1') 148 const created = await commentsCommand[0].createThread({ token: userToken1, videoId: videoUUID1, text: 'comment user 1' })
149 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID1, resComment.body.comment.id, 'comment root 1') 149 await commentsCommand[0].addReply({ videoId: videoUUID1, toCommentId: created.id, text: 'comment root 1' })
150 } 150 }
151 151
152 await waitJobs(servers) 152 await waitJobs(servers)
153
154 command = servers[0].blocklistCommand
155 }) 153 })
156 154
157 describe('User blocklist', function () { 155 describe('User blocklist', function () {
158 156
159 describe('When managing account blocklist', function () { 157 describe('When managing account blocklist', function () {
160 it('Should list all videos', function () { 158 it('Should list all videos', function () {
161 return checkAllVideos(servers[0].url, servers[0].accessToken) 159 return checkAllVideos(servers[0], servers[0].accessToken)
162 }) 160 })
163 161
164 it('Should list the comments', function () { 162 it('Should list the comments', function () {
165 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) 163 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
166 }) 164 })
167 165
168 it('Should block a remote account', async function () { 166 it('Should block a remote account', async function () {
@@ -194,19 +192,26 @@ describe('Test blocklist', function () {
194 }) 192 })
195 193
196 it('Should hide its comments', async function () { 194 it('Should hide its comments', async function () {
197 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 25, '-createdAt', servers[0].accessToken) 195 const { data } = await commentsCommand[0].listThreads({
198 196 token: servers[0].accessToken,
199 const threads: VideoComment[] = resThreads.body.data 197 videoId: videoUUID1,
200 expect(threads).to.have.lengthOf(1) 198 start: 0,
201 expect(threads[0].totalReplies).to.equal(1) 199 count: 25,
202 200 sort: '-createdAt'
203 const t = threads.find(t => t.text === 'comment user 1') 201 })
202
203 expect(data).to.have.lengthOf(1)
204 expect(data[0].totalReplies).to.equal(1)
205
206 const t = data.find(t => t.text === 'comment user 1')
204 expect(t).to.be.undefined 207 expect(t).to.be.undefined
205 208
206 for (const thread of threads) { 209 for (const thread of data) {
207 const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, servers[0].accessToken) 210 const tree = await commentsCommand[0].getThread({
208 211 videoId: videoUUID1,
209 const tree: VideoCommentThreadTree = res.body 212 threadId: thread.id,
213 token: servers[0].accessToken
214 })
210 expect(tree.children).to.have.lengthOf(0) 215 expect(tree.children).to.have.lengthOf(0)
211 } 216 }
212 }) 217 })
@@ -231,7 +236,7 @@ describe('Test blocklist', function () {
231 }) 236 })
232 237
233 it('Should list all the videos with another user', async function () { 238 it('Should list all the videos with another user', async function () {
234 return checkAllVideos(servers[0].url, userToken1) 239 return checkAllVideos(servers[0], userToken1)
235 }) 240 })
236 241
237 it('Should list blocked accounts', async function () { 242 it('Should list blocked accounts', async function () {
@@ -264,32 +269,29 @@ describe('Test blocklist', function () {
264 this.timeout(60000) 269 this.timeout(60000)
265 270
266 { 271 {
267 await addVideoCommentThread(servers[1].url, userToken2, videoUUID3, 'comment user 2') 272 await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID3, text: 'comment user 2' })
268 await waitJobs(servers) 273 await waitJobs(servers)
269 274
270 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID3, 'uploader') 275 await commentsCommand[0].createThread({ token: servers[0].accessToken, videoId: videoUUID3, text: 'uploader' })
271 await waitJobs(servers) 276 await waitJobs(servers)
272 277
273 const commentId = await findCommentId(servers[1].url, videoUUID3, 'uploader') 278 const commentId = await commentsCommand[1].findCommentId({ videoId: videoUUID3, text: 'uploader' })
274 const message = 'reply by user 2' 279 const message = 'reply by user 2'
275 const resReply = await addVideoCommentReply(servers[1].url, userToken2, videoUUID3, commentId, message) 280 const reply = await commentsCommand[1].addReply({ token: userToken2, videoId: videoUUID3, toCommentId: commentId, text: message })
276 await addVideoCommentReply(servers[1].url, servers[1].accessToken, videoUUID3, resReply.body.comment.id, 'another reply') 281 await commentsCommand[1].addReply({ videoId: videoUUID3, toCommentId: reply.id, text: 'another reply' })
277 282
278 await waitJobs(servers) 283 await waitJobs(servers)
279 } 284 }
280 285
281 // Server 2 has all the comments 286 // Server 2 has all the comments
282 { 287 {
283 const resThreads = await getVideoCommentThreads(servers[1].url, videoUUID3, 0, 25, '-createdAt') 288 const { data } = await commentsCommand[1].listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
284 const threads: VideoComment[] = resThreads.body.data
285
286 expect(threads).to.have.lengthOf(2)
287 expect(threads[0].text).to.equal('uploader')
288 expect(threads[1].text).to.equal('comment user 2')
289 289
290 const resReplies = await getVideoThreadComments(servers[1].url, videoUUID3, threads[0].id) 290 expect(data).to.have.lengthOf(2)
291 expect(data[0].text).to.equal('uploader')
292 expect(data[1].text).to.equal('comment user 2')
291 293
292 const tree: VideoCommentThreadTree = resReplies.body 294 const tree = await commentsCommand[1].getThread({ videoId: videoUUID3, threadId: data[0].id })
293 expect(tree.children).to.have.lengthOf(1) 295 expect(tree.children).to.have.lengthOf(1)
294 expect(tree.children[0].comment.text).to.equal('reply by user 2') 296 expect(tree.children[0].comment.text).to.equal('reply by user 2')
295 expect(tree.children[0].children).to.have.lengthOf(1) 297 expect(tree.children[0].children).to.have.lengthOf(1)
@@ -298,20 +300,15 @@ describe('Test blocklist', function () {
298 300
299 // Server 1 and 3 should only have uploader comments 301 // Server 1 and 3 should only have uploader comments
300 for (const server of [ servers[0], servers[2] ]) { 302 for (const server of [ servers[0], servers[2] ]) {
301 const resThreads = await getVideoCommentThreads(server.url, videoUUID3, 0, 25, '-createdAt') 303 const { data } = await server.commentsCommand.listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
302 const threads: VideoComment[] = resThreads.body.data
303 304
304 expect(threads).to.have.lengthOf(1) 305 expect(data).to.have.lengthOf(1)
305 expect(threads[0].text).to.equal('uploader') 306 expect(data[0].text).to.equal('uploader')
306 307
307 const resReplies = await getVideoThreadComments(server.url, videoUUID3, threads[0].id) 308 const tree = await server.commentsCommand.getThread({ videoId: videoUUID3, threadId: data[0].id })
308 309
309 const tree: VideoCommentThreadTree = resReplies.body 310 if (server.serverNumber === 1) expect(tree.children).to.have.lengthOf(0)
310 if (server.serverNumber === 1) { 311 else expect(tree.children).to.have.lengthOf(1)
311 expect(tree.children).to.have.lengthOf(0)
312 } else {
313 expect(tree.children).to.have.lengthOf(1)
314 }
315 } 312 }
316 }) 313 })
317 314
@@ -331,22 +328,19 @@ describe('Test blocklist', function () {
331 328
332 it('Should display its comments on my video', async function () { 329 it('Should display its comments on my video', async function () {
333 for (const server of servers) { 330 for (const server of servers) {
334 const resThreads = await getVideoCommentThreads(server.url, videoUUID3, 0, 25, '-createdAt') 331 const { data } = await server.commentsCommand.listThreads({ videoId: videoUUID3, count: 25, sort: '-createdAt' })
335 const threads: VideoComment[] = resThreads.body.data
336 332
337 // Server 3 should not have 2 comment threads, because server 1 did not forward the server 2 comment 333 // Server 3 should not have 2 comment threads, because server 1 did not forward the server 2 comment
338 if (server.serverNumber === 3) { 334 if (server.serverNumber === 3) {
339 expect(threads).to.have.lengthOf(1) 335 expect(data).to.have.lengthOf(1)
340 continue 336 continue
341 } 337 }
342 338
343 expect(threads).to.have.lengthOf(2) 339 expect(data).to.have.lengthOf(2)
344 expect(threads[0].text).to.equal('uploader') 340 expect(data[0].text).to.equal('uploader')
345 expect(threads[1].text).to.equal('comment user 2') 341 expect(data[1].text).to.equal('comment user 2')
346
347 const resReplies = await getVideoThreadComments(server.url, videoUUID3, threads[0].id)
348 342
349 const tree: VideoCommentThreadTree = resReplies.body 343 const tree = await server.commentsCommand.getThread({ videoId: videoUUID3, threadId: data[0].id })
350 expect(tree.children).to.have.lengthOf(1) 344 expect(tree.children).to.have.lengthOf(1)
351 expect(tree.children[0].comment.text).to.equal('reply by user 2') 345 expect(tree.children[0].comment.text).to.equal('reply by user 2')
352 expect(tree.children[0].children).to.have.lengthOf(1) 346 expect(tree.children[0].children).to.have.lengthOf(1)
@@ -359,7 +353,7 @@ describe('Test blocklist', function () {
359 }) 353 })
360 354
361 it('Should display its comments', function () { 355 it('Should display its comments', function () {
362 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) 356 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
363 }) 357 })
364 358
365 it('Should have a notification from a non blocked account', async function () { 359 it('Should have a notification from a non blocked account', async function () {
@@ -385,11 +379,11 @@ describe('Test blocklist', function () {
385 describe('When managing server blocklist', function () { 379 describe('When managing server blocklist', function () {
386 380
387 it('Should list all videos', function () { 381 it('Should list all videos', function () {
388 return checkAllVideos(servers[0].url, servers[0].accessToken) 382 return checkAllVideos(servers[0], servers[0].accessToken)
389 }) 383 })
390 384
391 it('Should list the comments', function () { 385 it('Should list the comments', function () {
392 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) 386 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
393 }) 387 })
394 388
395 it('Should block a remote server', async function () { 389 it('Should block a remote server', async function () {
@@ -410,20 +404,19 @@ describe('Test blocklist', function () {
410 }) 404 })
411 405
412 it('Should list all the videos with another user', async function () { 406 it('Should list all the videos with another user', async function () {
413 return checkAllVideos(servers[0].url, userToken1) 407 return checkAllVideos(servers[0], userToken1)
414 }) 408 })
415 409
416 it('Should hide its comments', async function () { 410 it('Should hide its comments', async function () {
417 this.timeout(10000) 411 this.timeout(10000)
418 412
419 const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2') 413 const { id } = await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID1, text: 'hidden comment 2' })
420 const threadId = resThreads.body.comment.id
421 414
422 await waitJobs(servers) 415 await waitJobs(servers)
423 416
424 await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) 417 await checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
425 418
426 await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId) 419 await commentsCommand[1].delete({ token: userToken2, videoId: videoUUID1, commentId: id })
427 }) 420 })
428 421
429 it('Should not have notifications from blocked server', async function () { 422 it('Should not have notifications from blocked server', async function () {
@@ -460,11 +453,11 @@ describe('Test blocklist', function () {
460 }) 453 })
461 454
462 it('Should display its videos', function () { 455 it('Should display its videos', function () {
463 return checkAllVideos(servers[0].url, servers[0].accessToken) 456 return checkAllVideos(servers[0], servers[0].accessToken)
464 }) 457 })
465 458
466 it('Should display its comments', function () { 459 it('Should display its comments', function () {
467 return checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) 460 return checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
468 }) 461 })
469 462
470 it('Should have notification from unblocked server', async function () { 463 it('Should have notification from unblocked server', async function () {
@@ -493,13 +486,13 @@ describe('Test blocklist', function () {
493 describe('When managing account blocklist', function () { 486 describe('When managing account blocklist', function () {
494 it('Should list all videos', async function () { 487 it('Should list all videos', async function () {
495 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 488 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
496 await checkAllVideos(servers[0].url, token) 489 await checkAllVideos(servers[0], token)
497 } 490 }
498 }) 491 })
499 492
500 it('Should list the comments', async function () { 493 it('Should list the comments', async function () {
501 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 494 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
502 await checkAllComments(servers[0].url, token, videoUUID1) 495 await checkAllComments(servers[0], token, videoUUID1)
503 } 496 }
504 }) 497 })
505 498
@@ -537,10 +530,8 @@ describe('Test blocklist', function () {
537 530
538 it('Should hide its comments', async function () { 531 it('Should hide its comments', async function () {
539 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 532 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
540 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 20, '-createdAt', token) 533 const { data } = await commentsCommand[0].listThreads({ videoId: videoUUID1, count: 20, sort: '-createdAt', token })
541 534 const threads = data.filter(t => t.isDeleted === false)
542 let threads: VideoComment[] = resThreads.body.data
543 threads = threads.filter(t => t.isDeleted === false)
544 535
545 expect(threads).to.have.lengthOf(1) 536 expect(threads).to.have.lengthOf(1)
546 expect(threads[0].totalReplies).to.equal(1) 537 expect(threads[0].totalReplies).to.equal(1)
@@ -549,9 +540,7 @@ describe('Test blocklist', function () {
549 expect(t).to.be.undefined 540 expect(t).to.be.undefined
550 541
551 for (const thread of threads) { 542 for (const thread of threads) {
552 const res = await getVideoThreadComments(servers[0].url, videoUUID1, thread.id, token) 543 const tree = await commentsCommand[0].getThread({ videoId: videoUUID1, threadId: thread.id, token })
553
554 const tree: VideoCommentThreadTree = res.body
555 expect(tree.children).to.have.lengthOf(0) 544 expect(tree.children).to.have.lengthOf(0)
556 } 545 }
557 } 546 }
@@ -624,7 +613,7 @@ describe('Test blocklist', function () {
624 613
625 it('Should display its comments', async function () { 614 it('Should display its comments', async function () {
626 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 615 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
627 await checkAllComments(servers[0].url, token, videoUUID1) 616 await checkAllComments(servers[0], token, videoUUID1)
628 } 617 }
629 }) 618 })
630 619
@@ -651,13 +640,13 @@ describe('Test blocklist', function () {
651 describe('When managing server blocklist', function () { 640 describe('When managing server blocklist', function () {
652 it('Should list all videos', async function () { 641 it('Should list all videos', async function () {
653 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 642 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
654 await checkAllVideos(servers[0].url, token) 643 await checkAllVideos(servers[0], token)
655 } 644 }
656 }) 645 })
657 646
658 it('Should list the comments', async function () { 647 it('Should list the comments', async function () {
659 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 648 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
660 await checkAllComments(servers[0].url, token, videoUUID1) 649 await checkAllComments(servers[0], token, videoUUID1)
661 } 650 }
662 }) 651 })
663 652
@@ -686,14 +675,13 @@ describe('Test blocklist', function () {
686 it('Should hide its comments', async function () { 675 it('Should hide its comments', async function () {
687 this.timeout(10000) 676 this.timeout(10000)
688 677
689 const resThreads = await addVideoCommentThread(servers[1].url, userToken2, videoUUID1, 'hidden comment 2') 678 const { id } = await commentsCommand[1].createThread({ token: userToken2, videoId: videoUUID1, text: 'hidden comment 2' })
690 const threadId = resThreads.body.comment.id
691 679
692 await waitJobs(servers) 680 await waitJobs(servers)
693 681
694 await checkAllComments(servers[0].url, servers[0].accessToken, videoUUID1) 682 await checkAllComments(servers[0], servers[0].accessToken, videoUUID1)
695 683
696 await deleteVideoComment(servers[1].url, userToken2, videoUUID1, threadId) 684 await commentsCommand[1].delete({ token: userToken2, videoId: videoUUID1, commentId: id })
697 }) 685 })
698 686
699 it('Should not have notification from blocked instances by instance', async function () { 687 it('Should not have notification from blocked instances by instance', async function () {
@@ -749,13 +737,13 @@ describe('Test blocklist', function () {
749 737
750 it('Should list all videos', async function () { 738 it('Should list all videos', async function () {
751 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 739 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
752 await checkAllVideos(servers[0].url, token) 740 await checkAllVideos(servers[0], token)
753 } 741 }
754 }) 742 })
755 743
756 it('Should list the comments', async function () { 744 it('Should list the comments', async function () {
757 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 745 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
758 await checkAllComments(servers[0].url, token, videoUUID1) 746 await checkAllComments(servers[0], token, videoUUID1)
759 } 747 }
760 }) 748 })
761 749
diff --git a/server/tests/api/notifications/comments-notifications.ts b/server/tests/api/notifications/comments-notifications.ts
index 13fcee843..ea6055386 100644
--- a/server/tests/api/notifications/comments-notifications.ts
+++ b/server/tests/api/notifications/comments-notifications.ts
@@ -3,14 +3,10 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoCommentReply,
7 addVideoCommentThread,
8 checkCommentMention, 6 checkCommentMention,
9 CheckerBaseParams, 7 CheckerBaseParams,
10 checkNewCommentOnMyVideo, 8 checkNewCommentOnMyVideo,
11 cleanupTests, 9 cleanupTests,
12 getVideoCommentThreads,
13 getVideoThreadComments,
14 MockSmtpServer, 10 MockSmtpServer,
15 prepareNotificationsTest, 11 prepareNotificationsTest,
16 ServerInfo, 12 ServerInfo,
@@ -18,13 +14,13 @@ import {
18 uploadVideo, 14 uploadVideo,
19 waitJobs 15 waitJobs
20} from '@shared/extra-utils' 16} from '@shared/extra-utils'
21import { UserNotification, VideoCommentThreadTree } from '@shared/models' 17import { UserNotification } from '@shared/models'
22 18
23const expect = chai.expect 19const expect = chai.expect
24 20
25describe('Test comments notifications', function () { 21describe('Test comments notifications', function () {
26 let servers: ServerInfo[] = [] 22 let servers: ServerInfo[] = []
27 let userAccessToken: string 23 let userToken: string
28 let userNotifications: UserNotification[] = [] 24 let userNotifications: UserNotification[] = []
29 let emails: object[] = [] 25 let emails: object[] = []
30 26
@@ -38,7 +34,7 @@ describe('Test comments notifications', function () {
38 34
39 const res = await prepareNotificationsTest(2) 35 const res = await prepareNotificationsTest(2)
40 emails = res.emails 36 emails = res.emails
41 userAccessToken = res.userAccessToken 37 userToken = res.userAccessToken
42 servers = res.servers 38 servers = res.servers
43 userNotifications = res.userNotifications 39 userNotifications = res.userNotifications
44 }) 40 })
@@ -51,7 +47,7 @@ describe('Test comments notifications', function () {
51 server: servers[0], 47 server: servers[0],
52 emails, 48 emails,
53 socketNotifications: userNotifications, 49 socketNotifications: userNotifications,
54 token: userAccessToken 50 token: userToken
55 } 51 }
56 }) 52 })
57 53
@@ -61,8 +57,8 @@ describe('Test comments notifications', function () {
61 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) 57 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
62 const uuid = resVideo.body.video.uuid 58 const uuid = resVideo.body.video.uuid
63 59
64 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') 60 const created = await servers[0].commentsCommand.createThread({ videoId: uuid, text: 'comment' })
65 const commentId = resComment.body.comment.id 61 const commentId = created.id
66 62
67 await waitJobs(servers) 63 await waitJobs(servers)
68 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence') 64 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
@@ -71,11 +67,11 @@ describe('Test comments notifications', function () {
71 it('Should not send a new comment notification if I comment my own video', async function () { 67 it('Should not send a new comment notification if I comment my own video', async function () {
72 this.timeout(20000) 68 this.timeout(20000)
73 69
74 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 70 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'super video' })
75 const uuid = resVideo.body.video.uuid 71 const uuid = resVideo.body.video.uuid
76 72
77 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment') 73 const created = await servers[0].commentsCommand.createThread({ token: userToken, videoId: uuid, text: 'comment' })
78 const commentId = resComment.body.comment.id 74 const commentId = created.id
79 75
80 await waitJobs(servers) 76 await waitJobs(servers)
81 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence') 77 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
@@ -84,28 +80,28 @@ describe('Test comments notifications', function () {
84 it('Should not send a new comment notification if the account is muted', async function () { 80 it('Should not send a new comment notification if the account is muted', async function () {
85 this.timeout(20000) 81 this.timeout(20000)
86 82
87 await servers[0].blocklistCommand.addToMyBlocklist({ token: userAccessToken, account: 'root' }) 83 await servers[0].blocklistCommand.addToMyBlocklist({ token: userToken, account: 'root' })
88 84
89 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 85 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'super video' })
90 const uuid = resVideo.body.video.uuid 86 const uuid = resVideo.body.video.uuid
91 87
92 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') 88 const created = await servers[0].commentsCommand.createThread({ videoId: uuid, text: 'comment' })
93 const commentId = resComment.body.comment.id 89 const commentId = created.id
94 90
95 await waitJobs(servers) 91 await waitJobs(servers)
96 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence') 92 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
97 93
98 await servers[0].blocklistCommand.removeFromMyBlocklist({ token: userAccessToken, account: 'root' }) 94 await servers[0].blocklistCommand.removeFromMyBlocklist({ token: userToken, account: 'root' })
99 }) 95 })
100 96
101 it('Should send a new comment notification after a local comment on my video', async function () { 97 it('Should send a new comment notification after a local comment on my video', async function () {
102 this.timeout(20000) 98 this.timeout(20000)
103 99
104 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 100 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'super video' })
105 const uuid = resVideo.body.video.uuid 101 const uuid = resVideo.body.video.uuid
106 102
107 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') 103 const created = await servers[0].commentsCommand.createThread({ videoId: uuid, text: 'comment' })
108 const commentId = resComment.body.comment.id 104 const commentId = created.id
109 105
110 await waitJobs(servers) 106 await waitJobs(servers)
111 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence') 107 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
@@ -114,33 +110,31 @@ describe('Test comments notifications', function () {
114 it('Should send a new comment notification after a remote comment on my video', async function () { 110 it('Should send a new comment notification after a remote comment on my video', async function () {
115 this.timeout(20000) 111 this.timeout(20000)
116 112
117 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 113 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'super video' })
118 const uuid = resVideo.body.video.uuid 114 const uuid = resVideo.body.video.uuid
119 115
120 await waitJobs(servers) 116 await waitJobs(servers)
121 117
122 await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment') 118 await servers[1].commentsCommand.createThread({ videoId: uuid, text: 'comment' })
123 119
124 await waitJobs(servers) 120 await waitJobs(servers)
125 121
126 const resComment = await getVideoCommentThreads(servers[0].url, uuid, 0, 5) 122 const { data } = await servers[0].commentsCommand.listThreads({ videoId: uuid })
127 expect(resComment.body.data).to.have.lengthOf(1) 123 expect(data).to.have.lengthOf(1)
128 const commentId = resComment.body.data[0].id
129 124
125 const commentId = data[0].id
130 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence') 126 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
131 }) 127 })
132 128
133 it('Should send a new comment notification after a local reply on my video', async function () { 129 it('Should send a new comment notification after a local reply on my video', async function () {
134 this.timeout(20000) 130 this.timeout(20000)
135 131
136 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 132 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'super video' })
137 const uuid = resVideo.body.video.uuid 133 const uuid = resVideo.body.video.uuid
138 134
139 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') 135 const { id: threadId } = await servers[0].commentsCommand.createThread({ videoId: uuid, text: 'comment' })
140 const threadId = resThread.body.comment.id
141 136
142 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply') 137 const { id: commentId } = await servers[0].commentsCommand.addReply({ videoId: uuid, toCommentId: threadId, text: 'reply' })
143 const commentId = resComment.body.comment.id
144 138
145 await waitJobs(servers) 139 await waitJobs(servers)
146 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence') 140 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
@@ -149,24 +143,23 @@ describe('Test comments notifications', function () {
149 it('Should send a new comment notification after a remote reply on my video', async function () { 143 it('Should send a new comment notification after a remote reply on my video', async function () {
150 this.timeout(20000) 144 this.timeout(20000)
151 145
152 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 146 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'super video' })
153 const uuid = resVideo.body.video.uuid 147 const uuid = resVideo.body.video.uuid
154 await waitJobs(servers) 148 await waitJobs(servers)
155 149
156 { 150 {
157 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment') 151 const created = await servers[1].commentsCommand.createThread({ videoId: uuid, text: 'comment' })
158 const threadId = resThread.body.comment.id 152 const threadId = created.id
159 await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply') 153 await servers[1].commentsCommand.addReply({ videoId: uuid, toCommentId: threadId, text: 'reply' })
160 } 154 }
161 155
162 await waitJobs(servers) 156 await waitJobs(servers)
163 157
164 const resThread = await getVideoCommentThreads(servers[0].url, uuid, 0, 5) 158 const { data } = await servers[0].commentsCommand.listThreads({ videoId: uuid })
165 expect(resThread.body.data).to.have.lengthOf(1) 159 expect(data).to.have.lengthOf(1)
166 const threadId = resThread.body.data[0].id
167 160
168 const resComments = await getVideoThreadComments(servers[0].url, uuid, threadId) 161 const threadId = data[0].id
169 const tree = resComments.body as VideoCommentThreadTree 162 const tree = await servers[0].commentsCommand.getThread({ videoId: uuid, threadId })
170 163
171 expect(tree.children).to.have.lengthOf(1) 164 expect(tree.children).to.have.lengthOf(1)
172 const commentId = tree.children[0].comment.id 165 const commentId = tree.children[0].comment.id
@@ -177,10 +170,10 @@ describe('Test comments notifications', function () {
177 it('Should convert markdown in comment to html', async function () { 170 it('Should convert markdown in comment to html', async function () {
178 this.timeout(20000) 171 this.timeout(20000)
179 172
180 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'cool video' }) 173 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'cool video' })
181 const uuid = resVideo.body.video.uuid 174 const uuid = resVideo.body.video.uuid
182 175
183 await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, commentText) 176 await servers[0].commentsCommand.createThread({ videoId: uuid, text: commentText })
184 177
185 await waitJobs(servers) 178 await waitJobs(servers)
186 179
@@ -197,7 +190,7 @@ describe('Test comments notifications', function () {
197 server: servers[0], 190 server: servers[0],
198 emails, 191 emails,
199 socketNotifications: userNotifications, 192 socketNotifications: userNotifications,
200 token: userAccessToken 193 token: userToken
201 } 194 }
202 195
203 await updateMyUser({ 196 await updateMyUser({
@@ -216,11 +209,10 @@ describe('Test comments notifications', function () {
216 it('Should not send a new mention comment notification if I mention the video owner', async function () { 209 it('Should not send a new mention comment notification if I mention the video owner', async function () {
217 this.timeout(10000) 210 this.timeout(10000)
218 211
219 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) 212 const resVideo = await uploadVideo(servers[0].url, userToken, { name: 'super video' })
220 const uuid = resVideo.body.video.uuid 213 const uuid = resVideo.body.video.uuid
221 214
222 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello') 215 const { id: commentId } = await servers[0].commentsCommand.createThread({ videoId: uuid, text: '@user_1 hello' })
223 const commentId = resComment.body.comment.id
224 216
225 await waitJobs(servers) 217 await waitJobs(servers)
226 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence') 218 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
@@ -232,8 +224,7 @@ describe('Test comments notifications', function () {
232 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) 224 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
233 const uuid = resVideo.body.video.uuid 225 const uuid = resVideo.body.video.uuid
234 226
235 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, '@user_1 hello') 227 const { id: commentId } = await servers[0].commentsCommand.createThread({ token: userToken, videoId: uuid, text: '@user_1 hello' })
236 const commentId = resComment.body.comment.id
237 228
238 await waitJobs(servers) 229 await waitJobs(servers)
239 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence') 230 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
@@ -242,18 +233,17 @@ describe('Test comments notifications', function () {
242 it('Should not send a new mention notification if the account is muted', async function () { 233 it('Should not send a new mention notification if the account is muted', async function () {
243 this.timeout(10000) 234 this.timeout(10000)
244 235
245 await servers[0].blocklistCommand.addToMyBlocklist({ token: userAccessToken, account: 'root' }) 236 await servers[0].blocklistCommand.addToMyBlocklist({ token: userToken, account: 'root' })
246 237
247 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) 238 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
248 const uuid = resVideo.body.video.uuid 239 const uuid = resVideo.body.video.uuid
249 240
250 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello') 241 const { id: commentId } = await servers[0].commentsCommand.createThread({ videoId: uuid, text: '@user_1 hello' })
251 const commentId = resComment.body.comment.id
252 242
253 await waitJobs(servers) 243 await waitJobs(servers)
254 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence') 244 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
255 245
256 await servers[0].blocklistCommand.removeFromMyBlocklist({ token: userAccessToken, account: 'root' }) 246 await servers[0].blocklistCommand.removeFromMyBlocklist({ token: userToken, account: 'root' })
257 }) 247 })
258 248
259 it('Should not send a new mention notification if the remote account mention a local account', async function () { 249 it('Should not send a new mention notification if the remote account mention a local account', async function () {
@@ -263,8 +253,7 @@ describe('Test comments notifications', function () {
263 const uuid = resVideo.body.video.uuid 253 const uuid = resVideo.body.video.uuid
264 254
265 await waitJobs(servers) 255 await waitJobs(servers)
266 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, '@user_1 hello') 256 const { id: threadId } = await servers[1].commentsCommand.createThread({ videoId: uuid, text: '@user_1 hello' })
267 const threadId = resThread.body.comment.id
268 257
269 await waitJobs(servers) 258 await waitJobs(servers)
270 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'absence') 259 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'absence')
@@ -276,14 +265,12 @@ describe('Test comments notifications', function () {
276 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) 265 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
277 const uuid = resVideo.body.video.uuid 266 const uuid = resVideo.body.video.uuid
278 267
279 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello 1') 268 const { id: threadId } = await servers[0].commentsCommand.createThread({ videoId: uuid, text: '@user_1 hellotext: 1' })
280 const threadId = resThread.body.comment.id
281 269
282 await waitJobs(servers) 270 await waitJobs(servers)
283 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root name', 'presence') 271 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root name', 'presence')
284 272
285 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'hello 2 @user_1') 273 const { id: commentId } = await servers[0].commentsCommand.addReply({ videoId: uuid, toCommentId: threadId, text: 'hello 2 @user_1' })
286 const commentId = resComment.body.comment.id
287 274
288 await waitJobs(servers) 275 await waitJobs(servers)
289 await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root name', 'presence') 276 await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root name', 'presence')
@@ -298,23 +285,22 @@ describe('Test comments notifications', function () {
298 await waitJobs(servers) 285 await waitJobs(servers)
299 286
300 const text1 = `hello @user_1@localhost:${servers[0].port} 1` 287 const text1 = `hello @user_1@localhost:${servers[0].port} 1`
301 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, text1) 288 const { id: server2ThreadId } = await servers[1].commentsCommand.createThread({ videoId: uuid, text: text1 })
302 const server2ThreadId = resThread.body.comment.id
303 289
304 await waitJobs(servers) 290 await waitJobs(servers)
305 291
306 const resThread2 = await getVideoCommentThreads(servers[0].url, uuid, 0, 5) 292 const { data } = await servers[0].commentsCommand.listThreads({ videoId: uuid })
307 expect(resThread2.body.data).to.have.lengthOf(1) 293 expect(data).to.have.lengthOf(1)
308 const server1ThreadId = resThread2.body.data[0].id 294
295 const server1ThreadId = data[0].id
309 await checkCommentMention(baseParams, uuid, server1ThreadId, server1ThreadId, 'super root 2 name', 'presence') 296 await checkCommentMention(baseParams, uuid, server1ThreadId, server1ThreadId, 'super root 2 name', 'presence')
310 297
311 const text2 = `@user_1@localhost:${servers[0].port} hello 2 @root@localhost:${servers[0].port}` 298 const text2 = `@user_1@localhost:${servers[0].port} hello 2 @root@localhost:${servers[0].port}`
312 await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, server2ThreadId, text2) 299 await servers[1].commentsCommand.addReply({ videoId: uuid, toCommentId: server2ThreadId, text: text2 })
313 300
314 await waitJobs(servers) 301 await waitJobs(servers)
315 302
316 const resComments = await getVideoThreadComments(servers[0].url, uuid, server1ThreadId) 303 const tree = await servers[0].commentsCommand.getThread({ videoId: uuid, threadId: server1ThreadId })
317 const tree = resComments.body as VideoCommentThreadTree
318 304
319 expect(tree.children).to.have.lengthOf(1) 305 expect(tree.children).to.have.lengthOf(1)
320 const commentId = tree.children[0].comment.id 306 const commentId = tree.children[0].comment.id
@@ -328,10 +314,9 @@ describe('Test comments notifications', function () {
328 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) 314 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
329 const uuid = resVideo.body.video.uuid 315 const uuid = resVideo.body.video.uuid
330 316
331 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello 1') 317 const { id: threadId } = await servers[0].commentsCommand.createThread({ videoId: uuid, text: '@user_1 hello 1' })
332 const threadId = resThread.body.comment.id
333 318
334 await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, '@user_1 ' + commentText) 319 await servers[0].commentsCommand.addReply({ videoId: uuid, toCommentId: threadId, text: '@user_1 ' + commentText })
335 320
336 await waitJobs(servers) 321 await waitJobs(servers)
337 322
diff --git a/server/tests/api/notifications/moderation-notifications.ts b/server/tests/api/notifications/moderation-notifications.ts
index 52ade0548..229f78811 100644
--- a/server/tests/api/notifications/moderation-notifications.ts
+++ b/server/tests/api/notifications/moderation-notifications.ts
@@ -3,7 +3,6 @@
3import 'mocha' 3import 'mocha'
4import { buildUUID } from '@server/helpers/uuid' 4import { buildUUID } from '@server/helpers/uuid'
5import { 5import {
6 addVideoCommentThread,
7 checkAbuseStateChange, 6 checkAbuseStateChange,
8 checkAutoInstanceFollowing, 7 checkAutoInstanceFollowing,
9 CheckerBaseParams, 8 CheckerBaseParams,
@@ -20,7 +19,6 @@ import {
20 cleanupTests, 19 cleanupTests,
21 createUser, 20 createUser,
22 generateUserAccessToken, 21 generateUserAccessToken,
23 getVideoCommentThreads,
24 getVideoIdFromUUID, 22 getVideoIdFromUUID,
25 immutableAssign, 23 immutableAssign,
26 MockInstancesIndex, 24 MockInstancesIndex,
@@ -101,8 +99,11 @@ describe('Test moderation notifications', function () {
101 const name = 'video for abuse ' + buildUUID() 99 const name = 'video for abuse ' + buildUUID()
102 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name }) 100 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
103 const video = resVideo.body.video 101 const video = resVideo.body.video
104 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + buildUUID()) 102 const comment = await servers[0].commentsCommand.createThread({
105 const comment = resComment.body.comment 103 token: userAccessToken,
104 videoId: video.id,
105 text: 'comment abuse ' + buildUUID()
106 })
106 107
107 await waitJobs(servers) 108 await waitJobs(servers)
108 109
@@ -118,12 +119,17 @@ describe('Test moderation notifications', function () {
118 const name = 'video for abuse ' + buildUUID() 119 const name = 'video for abuse ' + buildUUID()
119 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name }) 120 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
120 const video = resVideo.body.video 121 const video = resVideo.body.video
121 await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + buildUUID()) 122
123 await servers[0].commentsCommand.createThread({
124 token: userAccessToken,
125 videoId: video.id,
126 text: 'comment abuse ' + buildUUID()
127 })
122 128
123 await waitJobs(servers) 129 await waitJobs(servers)
124 130
125 const resComments = await getVideoCommentThreads(servers[1].url, video.uuid, 0, 5) 131 const { data } = await servers[1].commentsCommand.listThreads({ videoId: video.uuid })
126 const commentId = resComments.body.data[0].id 132 const commentId = data[0].id
127 await servers[1].abusesCommand.report({ commentId, reason: 'super reason' }) 133 await servers[1].abusesCommand.report({ commentId, reason: 'super reason' })
128 134
129 await waitJobs(servers) 135 await waitJobs(servers)
diff --git a/server/tests/api/server/bulk.ts b/server/tests/api/server/bulk.ts
index ca98a2eb2..5c8673e00 100644
--- a/server/tests/api/server/bulk.ts
+++ b/server/tests/api/server/bulk.ts
@@ -2,16 +2,13 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { Video, VideoComment } from '@shared/models' 5import { Video } from '@shared/models'
6import { 6import {
7 addVideoCommentReply,
8 addVideoCommentThread,
9 BulkCommand, 7 BulkCommand,
10 cleanupTests, 8 cleanupTests,
11 createUser, 9 createUser,
12 doubleFollow, 10 doubleFollow,
13 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
14 getVideoCommentThreads,
15 getVideosList, 12 getVideosList,
16 ServerInfo, 13 ServerInfo,
17 setAccessTokensToServers, 14 setAccessTokensToServers,
@@ -26,9 +23,9 @@ describe('Test bulk actions', function () {
26 const commentsUser3: { videoId: number, commentId: number }[] = [] 23 const commentsUser3: { videoId: number, commentId: number }[] = []
27 24
28 let servers: ServerInfo[] = [] 25 let servers: ServerInfo[] = []
29 let user1AccessToken: string 26 let user1Token: string
30 let user2AccessToken: string 27 let user2Token: string
31 let user3AccessToken: string 28 let user3Token: string
32 29
33 let bulkCommand: BulkCommand 30 let bulkCommand: BulkCommand
34 31
@@ -44,21 +41,21 @@ describe('Test bulk actions', function () {
44 const user = { username: 'user1', password: 'password' } 41 const user = { username: 'user1', password: 'password' }
45 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password }) 42 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
46 43
47 user1AccessToken = await userLogin(servers[0], user) 44 user1Token = await userLogin(servers[0], user)
48 } 45 }
49 46
50 { 47 {
51 const user = { username: 'user2', password: 'password' } 48 const user = { username: 'user2', password: 'password' }
52 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password }) 49 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
53 50
54 user2AccessToken = await userLogin(servers[0], user) 51 user2Token = await userLogin(servers[0], user)
55 } 52 }
56 53
57 { 54 {
58 const user = { username: 'user3', password: 'password' } 55 const user = { username: 'user3', password: 'password' }
59 await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password }) 56 await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password })
60 57
61 user3AccessToken = await userLogin(servers[1], user) 58 user3Token = await userLogin(servers[1], user)
62 } 59 }
63 60
64 await doubleFollow(servers[0], servers[1]) 61 await doubleFollow(servers[0], servers[1])
@@ -74,9 +71,8 @@ describe('Test bulk actions', function () {
74 71
75 // Server 1 should not have these comments anymore 72 // Server 1 should not have these comments anymore
76 for (const video of videos) { 73 for (const video of videos) {
77 const resThreads = await getVideoCommentThreads(servers[0].url, video.id, 0, 10) 74 const { data } = await servers[0].commentsCommand.listThreads({ videoId: video.id })
78 const comments = resThreads.body.data as VideoComment[] 75 const comment = data.find(c => c.text === 'comment by user 3')
79 const comment = comments.find(c => c.text === 'comment by user 3')
80 76
81 expect(comment).to.not.exist 77 expect(comment).to.not.exist
82 } 78 }
@@ -88,9 +84,8 @@ describe('Test bulk actions', function () {
88 84
89 // Server 1 should not have these comments on videos of server 1 85 // Server 1 should not have these comments on videos of server 1
90 for (const video of videos) { 86 for (const video of videos) {
91 const resThreads = await getVideoCommentThreads(servers[1].url, video.id, 0, 10) 87 const { data } = await servers[1].commentsCommand.listThreads({ videoId: video.id })
92 const comments = resThreads.body.data as VideoComment[] 88 const comment = data.find(c => c.text === 'comment by user 3')
93 const comment = comments.find(c => c.text === 'comment by user 3')
94 89
95 if (video.account.host === 'localhost:' + servers[0].port) { 90 if (video.account.host === 'localhost:' + servers[0].port) {
96 expect(comment).to.not.exist 91 expect(comment).to.not.exist
@@ -106,7 +101,7 @@ describe('Test bulk actions', function () {
106 101
107 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 1 server 1' }) 102 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 1 server 1' })
108 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 2 server 1' }) 103 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 2 server 1' })
109 await uploadVideo(servers[0].url, user1AccessToken, { name: 'video 3 server 1' }) 104 await uploadVideo(servers[0].url, user1Token, { name: 'video 3 server 1' })
110 105
111 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' }) 106 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' })
112 107
@@ -115,19 +110,20 @@ describe('Test bulk actions', function () {
115 { 110 {
116 const res = await getVideosList(servers[0].url) 111 const res = await getVideosList(servers[0].url)
117 for (const video of res.body.data) { 112 for (const video of res.body.data) {
118 await addVideoCommentThread(servers[0].url, servers[0].accessToken, video.id, 'comment by root server 1') 113 await servers[0].commentsCommand.createThread({ videoId: video.id, text: 'comment by root server 1' })
119 await addVideoCommentThread(servers[0].url, user1AccessToken, video.id, 'comment by user 1') 114 await servers[0].commentsCommand.createThread({ token: user1Token, videoId: video.id, text: 'comment by user 1' })
120 await addVideoCommentThread(servers[0].url, user2AccessToken, video.id, 'comment by user 2') 115 await servers[0].commentsCommand.createThread({ token: user2Token, videoId: video.id, text: 'comment by user 2' })
121 } 116 }
122 } 117 }
123 118
124 { 119 {
125 const res = await getVideosList(servers[1].url) 120 const res = await getVideosList(servers[1].url)
121
126 for (const video of res.body.data) { 122 for (const video of res.body.data) {
127 await addVideoCommentThread(servers[1].url, servers[1].accessToken, video.id, 'comment by root server 2') 123 await servers[1].commentsCommand.createThread({ videoId: video.id, text: 'comment by root server 2' })
128 124
129 const res = await addVideoCommentThread(servers[1].url, user3AccessToken, video.id, 'comment by user 3') 125 const comment = await servers[1].commentsCommand.createThread({ token: user3Token, videoId: video.id, text: 'comment by user 3' })
130 commentsUser3.push({ videoId: video.id, commentId: res.body.comment.id }) 126 commentsUser3.push({ videoId: video.id, commentId: comment.id })
131 } 127 }
132 } 128 }
133 129
@@ -138,7 +134,7 @@ describe('Test bulk actions', function () {
138 this.timeout(60000) 134 this.timeout(60000)
139 135
140 await bulkCommand.removeCommentsOf({ 136 await bulkCommand.removeCommentsOf({
141 token: user1AccessToken, 137 token: user1Token,
142 attributes: { 138 attributes: {
143 accountName: 'user2', 139 accountName: 'user2',
144 scope: 'my-videos' 140 scope: 'my-videos'
@@ -151,15 +147,11 @@ describe('Test bulk actions', function () {
151 const res = await getVideosList(server.url) 147 const res = await getVideosList(server.url)
152 148
153 for (const video of res.body.data) { 149 for (const video of res.body.data) {
154 const resThreads = await getVideoCommentThreads(server.url, video.id, 0, 10) 150 const { data } = await server.commentsCommand.listThreads({ videoId: video.id })
155 const comments = resThreads.body.data as VideoComment[] 151 const comment = data.find(c => c.text === 'comment by user 2')
156 const comment = comments.find(c => c.text === 'comment by user 2')
157 152
158 if (video.name === 'video 3 server 1') { 153 if (video.name === 'video 3 server 1') expect(comment).to.not.exist
159 expect(comment).to.not.exist 154 else expect(comment).to.exist
160 } else {
161 expect(comment).to.exist
162 }
163 } 155 }
164 } 156 }
165 }) 157 })
@@ -183,7 +175,12 @@ describe('Test bulk actions', function () {
183 this.timeout(60000) 175 this.timeout(60000)
184 176
185 for (const obj of commentsUser3) { 177 for (const obj of commentsUser3) {
186 await addVideoCommentReply(servers[1].url, user3AccessToken, obj.videoId, obj.commentId, 'comment by user 3 bis') 178 await servers[1].commentsCommand.addReply({
179 token: user3Token,
180 videoId: obj.videoId,
181 toCommentId: obj.commentId,
182 text: 'comment by user 3 bis'
183 })
187 } 184 }
188 185
189 await waitJobs(servers) 186 await waitJobs(servers)
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index 520442c6e..4a9ed2d05 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -3,19 +3,14 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoCommentReply,
7 addVideoCommentThread,
8 cleanupTests, 6 cleanupTests,
9 completeVideoCheck, 7 completeVideoCheck,
10 createUser, 8 createUser,
11 dateIsValid, 9 dateIsValid,
12 deleteVideoComment,
13 expectAccountFollows, 10 expectAccountFollows,
14 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
15 FollowsCommand, 12 FollowsCommand,
16 getVideoCommentThreads,
17 getVideosList, 13 getVideosList,
18 getVideoThreadComments,
19 rateVideo, 14 rateVideo,
20 ServerInfo, 15 ServerInfo,
21 setAccessTokensToServers, 16 setAccessTokensToServers,
@@ -24,7 +19,7 @@ import {
24 userLogin, 19 userLogin,
25 waitJobs 20 waitJobs
26} from '@shared/extra-utils' 21} from '@shared/extra-utils'
27import { Video, VideoComment, VideoCommentThreadTree, VideoPrivacy } from '@shared/models' 22import { Video, VideoPrivacy } from '@shared/models'
28 23
29const expect = chai.expect 24const expect = chai.expect
30 25
@@ -348,37 +343,35 @@ describe('Test follows', function () {
348 { 343 {
349 { 344 {
350 const text = 'my super first comment' 345 const text = 'my super first comment'
351 const res = await addVideoCommentThread(servers[2].url, servers[2].accessToken, video4.id, text) 346 const created = await servers[2].commentsCommand.createThread({ videoId: video4.id, text })
352 const threadId = res.body.comment.id 347 const threadId = created.id
353 348
354 const text1 = 'my super answer to thread 1' 349 const text1 = 'my super answer to thread 1'
355 const childCommentRes = await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text1) 350 const childComment = await servers[2].commentsCommand.addReply({ videoId: video4.id, toCommentId: threadId, text: text1 })
356 const childCommentId = childCommentRes.body.comment.id
357 351
358 const text2 = 'my super answer to answer of thread 1' 352 const text2 = 'my super answer to answer of thread 1'
359 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, childCommentId, text2) 353 await servers[2].commentsCommand.addReply({ videoId: video4.id, toCommentId: childComment.id, text: text2 })
360 354
361 const text3 = 'my second answer to thread 1' 355 const text3 = 'my second answer to thread 1'
362 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text3) 356 await servers[2].commentsCommand.addReply({ videoId: video4.id, toCommentId: threadId, text: text3 })
363 } 357 }
364 358
365 { 359 {
366 const text = 'will be deleted' 360 const text = 'will be deleted'
367 const res = await addVideoCommentThread(servers[2].url, servers[2].accessToken, video4.id, text) 361 const created = await servers[2].commentsCommand.createThread({ videoId: video4.id, text })
368 const threadId = res.body.comment.id 362 const threadId = created.id
369 363
370 const text1 = 'answer to deleted' 364 const text1 = 'answer to deleted'
371 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text1) 365 await servers[2].commentsCommand.addReply({ videoId: video4.id, toCommentId: threadId, text: text1 })
372 366
373 const text2 = 'will also be deleted' 367 const text2 = 'will also be deleted'
374 const childCommentRes = await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, threadId, text2) 368 const childComment = await servers[2].commentsCommand.addReply({ videoId: video4.id, toCommentId: threadId, text: text2 })
375 const childCommentId = childCommentRes.body.comment.id
376 369
377 const text3 = 'my second answer to deleted' 370 const text3 = 'my second answer to deleted'
378 await addVideoCommentReply(servers[2].url, servers[2].accessToken, video4.id, childCommentId, text3) 371 await servers[2].commentsCommand.addReply({ videoId: video4.id, toCommentId: childComment.id, text: text3 })
379 372
380 await deleteVideoComment(servers[2].url, servers[2].accessToken, video4.id, threadId) 373 await servers[2].commentsCommand.delete({ videoId: video4.id, commentId: threadId })
381 await deleteVideoComment(servers[2].url, servers[2].accessToken, video4.id, childCommentId) 374 await servers[2].commentsCommand.delete({ videoId: video4.id, commentId: childComment.id })
382 } 375 }
383 } 376 }
384 377
@@ -462,14 +455,14 @@ describe('Test follows', function () {
462 }) 455 })
463 456
464 it('Should have propagated comments', async function () { 457 it('Should have propagated comments', async function () {
465 const res1 = await getVideoCommentThreads(servers[0].url, video4.id, 0, 5, 'createdAt') 458 const { total, data } = await servers[0].commentsCommand.listThreads({ videoId: video4.id, sort: 'createdAt' })
466 459
467 expect(res1.body.total).to.equal(2) 460 expect(total).to.equal(2)
468 expect(res1.body.data).to.be.an('array') 461 expect(data).to.be.an('array')
469 expect(res1.body.data).to.have.lengthOf(2) 462 expect(data).to.have.lengthOf(2)
470 463
471 { 464 {
472 const comment: VideoComment = res1.body.data[0] 465 const comment = data[0]
473 expect(comment.inReplyToCommentId).to.be.null 466 expect(comment.inReplyToCommentId).to.be.null
474 expect(comment.text).equal('my super first comment') 467 expect(comment.text).equal('my super first comment')
475 expect(comment.videoId).to.equal(video4.id) 468 expect(comment.videoId).to.equal(video4.id)
@@ -482,9 +475,7 @@ describe('Test follows', function () {
482 475
483 const threadId = comment.threadId 476 const threadId = comment.threadId
484 477
485 const res2 = await getVideoThreadComments(servers[0].url, video4.id, threadId) 478 const tree = await servers[0].commentsCommand.getThread({ videoId: video4.id, threadId })
486
487 const tree: VideoCommentThreadTree = res2.body
488 expect(tree.comment.text).equal('my super first comment') 479 expect(tree.comment.text).equal('my super first comment')
489 expect(tree.children).to.have.lengthOf(2) 480 expect(tree.children).to.have.lengthOf(2)
490 481
@@ -502,7 +493,7 @@ describe('Test follows', function () {
502 } 493 }
503 494
504 { 495 {
505 const deletedComment: VideoComment = res1.body.data[1] 496 const deletedComment = data[1]
506 expect(deletedComment).to.not.be.undefined 497 expect(deletedComment).to.not.be.undefined
507 expect(deletedComment.isDeleted).to.be.true 498 expect(deletedComment.isDeleted).to.be.true
508 expect(deletedComment.deletedAt).to.not.be.null 499 expect(deletedComment.deletedAt).to.not.be.null
@@ -512,9 +503,7 @@ describe('Test follows', function () {
512 expect(deletedComment.totalReplies).to.equal(2) 503 expect(deletedComment.totalReplies).to.equal(2)
513 expect(dateIsValid(deletedComment.deletedAt as string)).to.be.true 504 expect(dateIsValid(deletedComment.deletedAt as string)).to.be.true
514 505
515 const res2 = await getVideoThreadComments(servers[0].url, video4.id, deletedComment.threadId) 506 const tree = await servers[0].commentsCommand.getThread({ videoId: video4.id, threadId: deletedComment.threadId })
516
517 const tree: VideoCommentThreadTree = res2.body
518 const [ commentRoot, deletedChildRoot ] = tree.children 507 const [ commentRoot, deletedChildRoot ] = tree.children
519 508
520 expect(deletedChildRoot).to.not.be.undefined 509 expect(deletedChildRoot).to.not.be.undefined
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index c6202fdaa..94496a159 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -4,16 +4,13 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { HttpStatusCode } from '@shared/core-utils' 5import { HttpStatusCode } from '@shared/core-utils'
6import { 6import {
7 addVideoCommentReply,
8 addVideoCommentThread,
9 cleanupTests, 7 cleanupTests,
10 closeAllSequelize, 8 closeAllSequelize,
9 CommentsCommand,
11 completeVideoCheck, 10 completeVideoCheck,
12 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
13 getVideo, 12 getVideo,
14 getVideoCommentThreads,
15 getVideosList, 13 getVideosList,
16 getVideoThreadComments,
17 immutableAssign, 14 immutableAssign,
18 killallServers, 15 killallServers,
19 reRunServer, 16 reRunServer,
@@ -26,7 +23,7 @@ import {
26 wait, 23 wait,
27 waitJobs 24 waitJobs
28} from '@shared/extra-utils' 25} from '@shared/extra-utils'
29import { JobState, Video, VideoCommentThreadTree, VideoPrivacy } from '@shared/models' 26import { JobState, Video, VideoPrivacy } from '@shared/models'
30 27
31const expect = chai.expect 28const expect = chai.expect
32 29
@@ -62,10 +59,13 @@ describe('Test handle downs', function () {
62 let checkAttributes: any 59 let checkAttributes: any
63 let unlistedCheckAttributes: any 60 let unlistedCheckAttributes: any
64 61
62 let commentCommands: CommentsCommand[]
63
65 before(async function () { 64 before(async function () {
66 this.timeout(30000) 65 this.timeout(30000)
67 66
68 servers = await flushAndRunMultipleServers(3) 67 servers = await flushAndRunMultipleServers(3)
68 commentCommands = servers.map(s => s.commentsCommand)
69 69
70 checkAttributes = { 70 checkAttributes = {
71 name: 'my super name for server 1', 71 name: 'my super name for server 1',
@@ -154,15 +154,13 @@ describe('Test handle downs', function () {
154 // Add comments to video 2 154 // Add comments to video 2
155 { 155 {
156 const text = 'thread 1' 156 const text = 'thread 1'
157 let resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, missedVideo2.uuid, text) 157 let comment = await commentCommands[0].createThread({ videoId: missedVideo2.uuid, text })
158 let comment = resComment.body.comment
159 threadIdServer1 = comment.id 158 threadIdServer1 = comment.id
160 159
161 resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, comment.id, 'comment 1-1') 160 comment = await commentCommands[0].addReply({ videoId: missedVideo2.uuid, toCommentId: comment.id, text: 'comment 1-1' })
162 comment = resComment.body.comment
163 161
164 resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, comment.id, 'comment 1-2') 162 const created = await commentCommands[0].addReply({ videoId: missedVideo2.uuid, toCommentId: comment.id, text: 'comment 1-2' })
165 commentIdServer1 = resComment.body.comment.id 163 commentIdServer1 = created.id
166 } 164 }
167 165
168 await waitJobs(servers[0]) 166 await waitJobs(servers[0])
@@ -235,7 +233,7 @@ describe('Test handle downs', function () {
235 it('Should send comments on a video to server 3, and automatically fetch the video', async function () { 233 it('Should send comments on a video to server 3, and automatically fetch the video', async function () {
236 this.timeout(25000) 234 this.timeout(25000)
237 235
238 await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, commentIdServer1, 'comment 1-3') 236 await commentCommands[0].addReply({ videoId: missedVideo2.uuid, toCommentId: commentIdServer1, text: 'comment 1-3' })
239 237
240 await waitJobs(servers) 238 await waitJobs(servers)
241 239
@@ -243,15 +241,13 @@ describe('Test handle downs', function () {
243 expect(resVideo.body).not.to.be.undefined 241 expect(resVideo.body).not.to.be.undefined
244 242
245 { 243 {
246 let resComment = await getVideoCommentThreads(servers[2].url, missedVideo2.uuid, 0, 5) 244 const { data } = await servers[2].commentsCommand.listThreads({ videoId: missedVideo2.uuid })
247 expect(resComment.body.data).to.be.an('array') 245 expect(data).to.be.an('array')
248 expect(resComment.body.data).to.have.lengthOf(1) 246 expect(data).to.have.lengthOf(1)
249
250 threadIdServer2 = resComment.body.data[0].id
251 247
252 resComment = await getVideoThreadComments(servers[2].url, missedVideo2.uuid, threadIdServer2) 248 threadIdServer2 = data[0].id
253 249
254 const tree: VideoCommentThreadTree = resComment.body 250 const tree = await servers[2].commentsCommand.getThread({ videoId: missedVideo2.uuid, threadId: threadIdServer2 })
255 expect(tree.comment.text).equal('thread 1') 251 expect(tree.comment.text).equal('thread 1')
256 expect(tree.children).to.have.lengthOf(1) 252 expect(tree.children).to.have.lengthOf(1)
257 253
@@ -274,33 +270,30 @@ describe('Test handle downs', function () {
274 it('Should correctly reply to the comment', async function () { 270 it('Should correctly reply to the comment', async function () {
275 this.timeout(15000) 271 this.timeout(15000)
276 272
277 await addVideoCommentReply(servers[2].url, servers[2].accessToken, missedVideo2.uuid, commentIdServer2, 'comment 1-4') 273 await servers[2].commentsCommand.addReply({ videoId: missedVideo2.uuid, toCommentId: commentIdServer2, text: 'comment 1-4' })
278 274
279 await waitJobs(servers) 275 await waitJobs(servers)
280 276
281 { 277 const tree = await commentCommands[0].getThread({ videoId: missedVideo2.uuid, threadId: threadIdServer1 })
282 const resComment = await getVideoThreadComments(servers[0].url, missedVideo2.uuid, threadIdServer1)
283 278
284 const tree: VideoCommentThreadTree = resComment.body 279 expect(tree.comment.text).equal('thread 1')
285 expect(tree.comment.text).equal('thread 1') 280 expect(tree.children).to.have.lengthOf(1)
286 expect(tree.children).to.have.lengthOf(1)
287 281
288 const firstChild = tree.children[0] 282 const firstChild = tree.children[0]
289 expect(firstChild.comment.text).to.equal('comment 1-1') 283 expect(firstChild.comment.text).to.equal('comment 1-1')
290 expect(firstChild.children).to.have.lengthOf(1) 284 expect(firstChild.children).to.have.lengthOf(1)
291 285
292 const childOfFirstChild = firstChild.children[0] 286 const childOfFirstChild = firstChild.children[0]
293 expect(childOfFirstChild.comment.text).to.equal('comment 1-2') 287 expect(childOfFirstChild.comment.text).to.equal('comment 1-2')
294 expect(childOfFirstChild.children).to.have.lengthOf(1) 288 expect(childOfFirstChild.children).to.have.lengthOf(1)
295 289
296 const childOfChildFirstChild = childOfFirstChild.children[0] 290 const childOfChildFirstChild = childOfFirstChild.children[0]
297 expect(childOfChildFirstChild.comment.text).to.equal('comment 1-3') 291 expect(childOfChildFirstChild.comment.text).to.equal('comment 1-3')
298 expect(childOfChildFirstChild.children).to.have.lengthOf(1) 292 expect(childOfChildFirstChild.children).to.have.lengthOf(1)
299 293
300 const childOfChildOfChildOfFirstChild = childOfChildFirstChild.children[0] 294 const childOfChildOfChildOfFirstChild = childOfChildFirstChild.children[0]
301 expect(childOfChildOfChildOfFirstChild.comment.text).to.equal('comment 1-4') 295 expect(childOfChildOfChildOfFirstChild.comment.text).to.equal('comment 1-4')
302 expect(childOfChildOfChildOfFirstChild.children).to.have.lengthOf(0) 296 expect(childOfChildOfChildOfFirstChild.children).to.have.lengthOf(0)
303 }
304 }) 297 })
305 298
306 it('Should upload many videos on server 1', async function () { 299 it('Should upload many videos on server 1', async function () {
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts
index 9c954c347..ded305899 100644
--- a/server/tests/api/server/stats.ts
+++ b/server/tests/api/server/stats.ts
@@ -3,7 +3,6 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoCommentThread,
7 cleanupTests, 6 cleanupTests,
8 createUser, 7 createUser,
9 doubleFollow, 8 doubleFollow,
@@ -42,7 +41,7 @@ describe('Test stats (excluding redundancy)', function () {
42 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' }) 41 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' })
43 const videoUUID = resVideo.body.video.uuid 42 const videoUUID = resVideo.body.video.uuid
44 43
45 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment') 44 await servers[0].commentsCommand.createThread({ videoId: videoUUID, text: 'comment' })
46 45
47 await viewVideo(servers[0].url, videoUUID) 46 await viewVideo(servers[0].url, videoUUID)
48 47
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index ed670b3c9..4d255f340 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -4,7 +4,6 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { HttpStatusCode } from '@shared/core-utils' 5import { HttpStatusCode } from '@shared/core-utils'
6import { 6import {
7 addVideoCommentThread,
8 blockUser, 7 blockUser,
9 cleanupTests, 8 cleanupTests,
10 closeAllSequelize, 9 closeAllSequelize,
@@ -983,7 +982,7 @@ describe('Test users', function () {
983 982
984 it('Should report correct video comments for user', async function () { 983 it('Should report correct video comments for user', async function () {
985 const text = 'super comment' 984 const text = 'super comment'
986 await addVideoCommentThread(server.url, user17AccessToken, videoId, text) 985 await server.commentsCommand.createThread({ token: user17AccessToken, videoId, text })
987 986
988 const res = await getUserInformation(server.url, server.accessToken, user17Id, true) 987 const res = await getUserInformation(server.url, server.accessToken, user17Id, true)
989 const user: User = res.body 988 const user: User = res.body
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index a59d5a858..2148d8e1c 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -3,7 +3,7 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import * as request from 'supertest' 5import * as request from 'supertest'
6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' 6import { HttpStatusCode } from '@shared/core-utils'
7import { 7import {
8 buildAbsoluteFixturePath, 8 buildAbsoluteFixturePath,
9 checkTmpIsEmpty, 9 checkTmpIsEmpty,
@@ -27,18 +27,10 @@ import {
27 userLogin, 27 userLogin,
28 viewVideo, 28 viewVideo,
29 wait, 29 wait,
30 waitJobs,
30 webtorrentAdd 31 webtorrentAdd
31} from '../../../../shared/extra-utils' 32} from '@shared/extra-utils'
32import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 33import { VideoCommentThreadTree, VideoPrivacy } from '@shared/models'
33import {
34 addVideoCommentReply,
35 addVideoCommentThread,
36 deleteVideoComment,
37 findCommentId,
38 getVideoCommentThreads,
39 getVideoThreadComments
40} from '../../../../shared/extra-utils/videos/video-comments'
41import { VideoComment, VideoCommentThreadTree, VideoPrivacy } from '../../../../shared/models/videos'
42 34
43const expect = chai.expect 35const expect = chai.expect
44 36
@@ -762,36 +754,36 @@ describe('Test multiple servers', function () {
762 754
763 { 755 {
764 const text = 'my super first comment' 756 const text = 'my super first comment'
765 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, text) 757 await servers[0].commentsCommand.createThread({ videoId: videoUUID, text })
766 } 758 }
767 759
768 { 760 {
769 const text = 'my super second comment' 761 const text = 'my super second comment'
770 await addVideoCommentThread(servers[2].url, servers[2].accessToken, videoUUID, text) 762 await servers[2].commentsCommand.createThread({ videoId: videoUUID, text })
771 } 763 }
772 764
773 await waitJobs(servers) 765 await waitJobs(servers)
774 766
775 { 767 {
776 const threadId = await findCommentId(servers[1].url, videoUUID, 'my super first comment') 768 const threadId = await servers[1].commentsCommand.findCommentId({ videoId: videoUUID, text: 'my super first comment' })
777 769
778 const text = 'my super answer to thread 1' 770 const text = 'my super answer to thread 1'
779 await addVideoCommentReply(servers[1].url, servers[1].accessToken, videoUUID, threadId, text) 771 await servers[1].commentsCommand.addReply({ videoId: videoUUID, toCommentId: threadId, text })
780 } 772 }
781 773
782 await waitJobs(servers) 774 await waitJobs(servers)
783 775
784 { 776 {
785 const threadId = await findCommentId(servers[2].url, videoUUID, 'my super first comment') 777 const threadId = await servers[2].commentsCommand.findCommentId({ videoId: videoUUID, text: 'my super first comment' })
786 778
787 const res2 = await getVideoThreadComments(servers[2].url, videoUUID, threadId) 779 const body = await servers[2].commentsCommand.getThread({ videoId: videoUUID, threadId })
788 const childCommentId = res2.body.children[0].comment.id 780 const childCommentId = body.children[0].comment.id
789 781
790 const text3 = 'my second answer to thread 1' 782 const text3 = 'my second answer to thread 1'
791 await addVideoCommentReply(servers[2].url, servers[2].accessToken, videoUUID, threadId, text3) 783 await servers[2].commentsCommand.addReply({ videoId: videoUUID, toCommentId: threadId, text: text3 })
792 784
793 const text2 = 'my super answer to answer of thread 1' 785 const text2 = 'my super answer to answer of thread 1'
794 await addVideoCommentReply(servers[2].url, servers[2].accessToken, videoUUID, childCommentId, text2) 786 await servers[2].commentsCommand.addReply({ videoId: videoUUID, toCommentId: childCommentId, text: text2 })
795 } 787 }
796 788
797 await waitJobs(servers) 789 await waitJobs(servers)
@@ -799,14 +791,14 @@ describe('Test multiple servers', function () {
799 791
800 it('Should have these threads', async function () { 792 it('Should have these threads', async function () {
801 for (const server of servers) { 793 for (const server of servers) {
802 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 794 const body = await server.commentsCommand.listThreads({ videoId: videoUUID })
803 795
804 expect(res.body.total).to.equal(2) 796 expect(body.total).to.equal(2)
805 expect(res.body.data).to.be.an('array') 797 expect(body.data).to.be.an('array')
806 expect(res.body.data).to.have.lengthOf(2) 798 expect(body.data).to.have.lengthOf(2)
807 799
808 { 800 {
809 const comment: VideoComment = res.body.data.find(c => c.text === 'my super first comment') 801 const comment = body.data.find(c => c.text === 'my super first comment')
810 expect(comment).to.not.be.undefined 802 expect(comment).to.not.be.undefined
811 expect(comment.inReplyToCommentId).to.be.null 803 expect(comment.inReplyToCommentId).to.be.null
812 expect(comment.account.name).to.equal('root') 804 expect(comment.account.name).to.equal('root')
@@ -817,7 +809,7 @@ describe('Test multiple servers', function () {
817 } 809 }
818 810
819 { 811 {
820 const comment: VideoComment = res.body.data.find(c => c.text === 'my super second comment') 812 const comment = body.data.find(c => c.text === 'my super second comment')
821 expect(comment).to.not.be.undefined 813 expect(comment).to.not.be.undefined
822 expect(comment.inReplyToCommentId).to.be.null 814 expect(comment.inReplyToCommentId).to.be.null
823 expect(comment.account.name).to.equal('root') 815 expect(comment.account.name).to.equal('root')
@@ -831,12 +823,11 @@ describe('Test multiple servers', function () {
831 823
832 it('Should have these comments', async function () { 824 it('Should have these comments', async function () {
833 for (const server of servers) { 825 for (const server of servers) {
834 const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 826 const body = await server.commentsCommand.listThreads({ videoId: videoUUID })
835 const threadId = res1.body.data.find(c => c.text === 'my super first comment').id 827 const threadId = body.data.find(c => c.text === 'my super first comment').id
836 828
837 const res2 = await getVideoThreadComments(server.url, videoUUID, threadId) 829 const tree = await server.commentsCommand.getThread({ videoId: videoUUID, threadId })
838 830
839 const tree: VideoCommentThreadTree = res2.body
840 expect(tree.comment.text).equal('my super first comment') 831 expect(tree.comment.text).equal('my super first comment')
841 expect(tree.comment.account.name).equal('root') 832 expect(tree.comment.account.name).equal('root')
842 expect(tree.comment.account.host).equal('localhost:' + servers[0].port) 833 expect(tree.comment.account.host).equal('localhost:' + servers[0].port)
@@ -865,19 +856,17 @@ describe('Test multiple servers', function () {
865 it('Should delete a reply', async function () { 856 it('Should delete a reply', async function () {
866 this.timeout(10000) 857 this.timeout(10000)
867 858
868 await deleteVideoComment(servers[2].url, servers[2].accessToken, videoUUID, childOfFirstChild.comment.id) 859 await servers[2].commentsCommand.delete({ videoId: videoUUID, commentId: childOfFirstChild.comment.id })
869 860
870 await waitJobs(servers) 861 await waitJobs(servers)
871 }) 862 })
872 863
873 it('Should have this comment marked as deleted', async function () { 864 it('Should have this comment marked as deleted', async function () {
874 for (const server of servers) { 865 for (const server of servers) {
875 const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 866 const { data } = await server.commentsCommand.listThreads({ videoId: videoUUID })
876 const threadId = res1.body.data.find(c => c.text === 'my super first comment').id 867 const threadId = data.find(c => c.text === 'my super first comment').id
877
878 const res2 = await getVideoThreadComments(server.url, videoUUID, threadId)
879 868
880 const tree: VideoCommentThreadTree = res2.body 869 const tree = await server.commentsCommand.getThread({ videoId: videoUUID, threadId })
881 expect(tree.comment.text).equal('my super first comment') 870 expect(tree.comment.text).equal('my super first comment')
882 871
883 const firstChild = tree.children[0] 872 const firstChild = tree.children[0]
@@ -898,23 +887,23 @@ describe('Test multiple servers', function () {
898 it('Should delete the thread comments', async function () { 887 it('Should delete the thread comments', async function () {
899 this.timeout(10000) 888 this.timeout(10000)
900 889
901 const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5) 890 const { data } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID })
902 const threadId = res.body.data.find(c => c.text === 'my super first comment').id 891 const commentId = data.find(c => c.text === 'my super first comment').id
903 await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId) 892 await servers[0].commentsCommand.delete({ videoId: videoUUID, commentId })
904 893
905 await waitJobs(servers) 894 await waitJobs(servers)
906 }) 895 })
907 896
908 it('Should have the threads marked as deleted on other servers too', async function () { 897 it('Should have the threads marked as deleted on other servers too', async function () {
909 for (const server of servers) { 898 for (const server of servers) {
910 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 899 const body = await server.commentsCommand.listThreads({ videoId: videoUUID })
911 900
912 expect(res.body.total).to.equal(2) 901 expect(body.total).to.equal(2)
913 expect(res.body.data).to.be.an('array') 902 expect(body.data).to.be.an('array')
914 expect(res.body.data).to.have.lengthOf(2) 903 expect(body.data).to.have.lengthOf(2)
915 904
916 { 905 {
917 const comment: VideoComment = res.body.data[0] 906 const comment = body.data[0]
918 expect(comment).to.not.be.undefined 907 expect(comment).to.not.be.undefined
919 expect(comment.inReplyToCommentId).to.be.null 908 expect(comment.inReplyToCommentId).to.be.null
920 expect(comment.account.name).to.equal('root') 909 expect(comment.account.name).to.equal('root')
@@ -925,7 +914,7 @@ describe('Test multiple servers', function () {
925 } 914 }
926 915
927 { 916 {
928 const deletedComment: VideoComment = res.body.data[1] 917 const deletedComment = body.data[1]
929 expect(deletedComment).to.not.be.undefined 918 expect(deletedComment).to.not.be.undefined
930 expect(deletedComment.isDeleted).to.be.true 919 expect(deletedComment.isDeleted).to.be.true
931 expect(deletedComment.deletedAt).to.not.be.null 920 expect(deletedComment.deletedAt).to.not.be.null
@@ -943,22 +932,22 @@ describe('Test multiple servers', function () {
943 it('Should delete a remote thread by the origin server', async function () { 932 it('Should delete a remote thread by the origin server', async function () {
944 this.timeout(5000) 933 this.timeout(5000)
945 934
946 const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5) 935 const { data } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID })
947 const threadId = res.body.data.find(c => c.text === 'my super second comment').id 936 const commentId = data.find(c => c.text === 'my super second comment').id
948 await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId) 937 await servers[0].commentsCommand.delete({ videoId: videoUUID, commentId })
949 938
950 await waitJobs(servers) 939 await waitJobs(servers)
951 }) 940 })
952 941
953 it('Should have the threads marked as deleted on other servers too', async function () { 942 it('Should have the threads marked as deleted on other servers too', async function () {
954 for (const server of servers) { 943 for (const server of servers) {
955 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 944 const body = await server.commentsCommand.listThreads({ videoId: videoUUID })
956 945
957 expect(res.body.total).to.equal(2) 946 expect(body.total).to.equal(2)
958 expect(res.body.data).to.have.lengthOf(2) 947 expect(body.data).to.have.lengthOf(2)
959 948
960 { 949 {
961 const comment: VideoComment = res.body.data[0] 950 const comment = body.data[0]
962 expect(comment.text).to.equal('') 951 expect(comment.text).to.equal('')
963 expect(comment.isDeleted).to.be.true 952 expect(comment.isDeleted).to.be.true
964 expect(comment.createdAt).to.not.be.null 953 expect(comment.createdAt).to.not.be.null
@@ -968,7 +957,7 @@ describe('Test multiple servers', function () {
968 } 957 }
969 958
970 { 959 {
971 const comment: VideoComment = res.body.data[1] 960 const comment = body.data[1]
972 expect(comment.text).to.equal('') 961 expect(comment.text).to.equal('')
973 expect(comment.isDeleted).to.be.true 962 expect(comment.isDeleted).to.be.true
974 expect(comment.createdAt).to.not.be.null 963 expect(comment.createdAt).to.not.be.null
@@ -997,7 +986,7 @@ describe('Test multiple servers', function () {
997 expect(res.body.downloadEnabled).to.be.false 986 expect(res.body.downloadEnabled).to.be.false
998 987
999 const text = 'my super forbidden comment' 988 const text = 'my super forbidden comment'
1000 await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, HttpStatusCode.CONFLICT_409) 989 await server.commentsCommand.createThread({ videoId: videoUUID, text, expectedStatus: HttpStatusCode.CONFLICT_409 })
1001 } 990 }
1002 }) 991 })
1003 }) 992 })
diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts
index b6b002307..548d9fbf5 100644
--- a/server/tests/api/videos/video-comments.ts
+++ b/server/tests/api/videos/video-comments.ts
@@ -2,38 +2,33 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { VideoComment, VideoCommentAdmin, VideoCommentThreadTree } from '@shared/models'
6import { cleanupTests, testImage } from '../../../../shared/extra-utils'
7import { 5import {
6 cleanupTests,
7 CommentsCommand,
8 createUser, 8 createUser,
9 dateIsValid, 9 dateIsValid,
10 flushAndRunServer, 10 flushAndRunServer,
11 getAccessToken, 11 getAccessToken,
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 testImage,
14 updateMyAvatar, 15 updateMyAvatar,
15 uploadVideo 16 uploadVideo
16} from '../../../../shared/extra-utils/index' 17} from '@shared/extra-utils'
17import {
18 addVideoCommentReply,
19 addVideoCommentThread,
20 deleteVideoComment,
21 getAdminVideoComments,
22 getVideoCommentThreads,
23 getVideoThreadComments
24} from '../../../../shared/extra-utils/videos/video-comments'
25 18
26const expect = chai.expect 19const expect = chai.expect
27 20
28describe('Test video comments', function () { 21describe('Test video comments', function () {
29 let server: ServerInfo 22 let server: ServerInfo
30 let videoId 23 let videoId: number
31 let videoUUID 24 let videoUUID: string
32 let threadId 25 let threadId: number
33 let replyToDeleteId: number 26 let replyToDeleteId: number
34 27
35 let userAccessTokenServer1: string 28 let userAccessTokenServer1: string
36 29
30 let command: CommentsCommand
31
37 before(async function () { 32 before(async function () {
38 this.timeout(30000) 33 this.timeout(30000)
39 34
@@ -58,24 +53,25 @@ describe('Test video comments', function () {
58 password: 'password' 53 password: 'password'
59 }) 54 })
60 userAccessTokenServer1 = await getAccessToken(server.url, 'user1', 'password') 55 userAccessTokenServer1 = await getAccessToken(server.url, 'user1', 'password')
56
57 command = server.commentsCommand
61 }) 58 })
62 59
63 describe('User comments', function () { 60 describe('User comments', function () {
64 61
65 it('Should not have threads on this video', async function () { 62 it('Should not have threads on this video', async function () {
66 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 63 const body = await command.listThreads({ videoId: videoUUID })
67 64
68 expect(res.body.total).to.equal(0) 65 expect(body.total).to.equal(0)
69 expect(res.body.totalNotDeletedComments).to.equal(0) 66 expect(body.totalNotDeletedComments).to.equal(0)
70 expect(res.body.data).to.be.an('array') 67 expect(body.data).to.be.an('array')
71 expect(res.body.data).to.have.lengthOf(0) 68 expect(body.data).to.have.lengthOf(0)
72 }) 69 })
73 70
74 it('Should create a thread in this video', async function () { 71 it('Should create a thread in this video', async function () {
75 const text = 'my super first comment' 72 const text = 'my super first comment'
76 73
77 const res = await addVideoCommentThread(server.url, server.accessToken, videoUUID, text) 74 const comment = await command.createThread({ videoId: videoUUID, text })
78 const comment = res.body.comment
79 75
80 expect(comment.inReplyToCommentId).to.be.null 76 expect(comment.inReplyToCommentId).to.be.null
81 expect(comment.text).equal('my super first comment') 77 expect(comment.text).equal('my super first comment')
@@ -91,14 +87,14 @@ describe('Test video comments', function () {
91 }) 87 })
92 88
93 it('Should list threads of this video', async function () { 89 it('Should list threads of this video', async function () {
94 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 90 const body = await command.listThreads({ videoId: videoUUID })
95 91
96 expect(res.body.total).to.equal(1) 92 expect(body.total).to.equal(1)
97 expect(res.body.totalNotDeletedComments).to.equal(1) 93 expect(body.totalNotDeletedComments).to.equal(1)
98 expect(res.body.data).to.be.an('array') 94 expect(body.data).to.be.an('array')
99 expect(res.body.data).to.have.lengthOf(1) 95 expect(body.data).to.have.lengthOf(1)
100 96
101 const comment: VideoComment = res.body.data[0] 97 const comment = body.data[0]
102 expect(comment.inReplyToCommentId).to.be.null 98 expect(comment.inReplyToCommentId).to.be.null
103 expect(comment.text).equal('my super first comment') 99 expect(comment.text).equal('my super first comment')
104 expect(comment.videoId).to.equal(videoId) 100 expect(comment.videoId).to.equal(videoId)
@@ -117,9 +113,9 @@ describe('Test video comments', function () {
117 }) 113 })
118 114
119 it('Should get all the thread created', async function () { 115 it('Should get all the thread created', async function () {
120 const res = await getVideoThreadComments(server.url, videoUUID, threadId) 116 const body = await command.getThread({ videoId: videoUUID, threadId })
121 117
122 const rootComment = res.body.comment 118 const rootComment = body.comment
123 expect(rootComment.inReplyToCommentId).to.be.null 119 expect(rootComment.inReplyToCommentId).to.be.null
124 expect(rootComment.text).equal('my super first comment') 120 expect(rootComment.text).equal('my super first comment')
125 expect(rootComment.videoId).to.equal(videoId) 121 expect(rootComment.videoId).to.equal(videoId)
@@ -129,20 +125,19 @@ describe('Test video comments', function () {
129 125
130 it('Should create multiple replies in this thread', async function () { 126 it('Should create multiple replies in this thread', async function () {
131 const text1 = 'my super answer to thread 1' 127 const text1 = 'my super answer to thread 1'
132 const childCommentRes = await addVideoCommentReply(server.url, server.accessToken, videoId, threadId, text1) 128 const created = await command.addReply({ videoId, toCommentId: threadId, text: text1 })
133 const childCommentId = childCommentRes.body.comment.id 129 const childCommentId = created.id
134 130
135 const text2 = 'my super answer to answer of thread 1' 131 const text2 = 'my super answer to answer of thread 1'
136 await addVideoCommentReply(server.url, server.accessToken, videoId, childCommentId, text2) 132 await command.addReply({ videoId, toCommentId: childCommentId, text: text2 })
137 133
138 const text3 = 'my second answer to thread 1' 134 const text3 = 'my second answer to thread 1'
139 await addVideoCommentReply(server.url, server.accessToken, videoId, threadId, text3) 135 await command.addReply({ videoId, toCommentId: threadId, text: text3 })
140 }) 136 })
141 137
142 it('Should get correctly the replies', async function () { 138 it('Should get correctly the replies', async function () {
143 const res = await getVideoThreadComments(server.url, videoUUID, threadId) 139 const tree = await command.getThread({ videoId: videoUUID, threadId })
144 140
145 const tree: VideoCommentThreadTree = res.body
146 expect(tree.comment.text).equal('my super first comment') 141 expect(tree.comment.text).equal('my super first comment')
147 expect(tree.children).to.have.lengthOf(2) 142 expect(tree.children).to.have.lengthOf(2)
148 143
@@ -163,42 +158,41 @@ describe('Test video comments', function () {
163 158
164 it('Should create other threads', async function () { 159 it('Should create other threads', async function () {
165 const text1 = 'super thread 2' 160 const text1 = 'super thread 2'
166 await addVideoCommentThread(server.url, server.accessToken, videoUUID, text1) 161 await command.createThread({ videoId: videoUUID, text: text1 })
167 162
168 const text2 = 'super thread 3' 163 const text2 = 'super thread 3'
169 await addVideoCommentThread(server.url, server.accessToken, videoUUID, text2) 164 await command.createThread({ videoId: videoUUID, text: text2 })
170 }) 165 })
171 166
172 it('Should list the threads', async function () { 167 it('Should list the threads', async function () {
173 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5, 'createdAt') 168 const body = await command.listThreads({ videoId: videoUUID, sort: 'createdAt' })
174 169
175 expect(res.body.total).to.equal(3) 170 expect(body.total).to.equal(3)
176 expect(res.body.totalNotDeletedComments).to.equal(6) 171 expect(body.totalNotDeletedComments).to.equal(6)
177 expect(res.body.data).to.be.an('array') 172 expect(body.data).to.be.an('array')
178 expect(res.body.data).to.have.lengthOf(3) 173 expect(body.data).to.have.lengthOf(3)
179 174
180 expect(res.body.data[0].text).to.equal('my super first comment') 175 expect(body.data[0].text).to.equal('my super first comment')
181 expect(res.body.data[0].totalReplies).to.equal(3) 176 expect(body.data[0].totalReplies).to.equal(3)
182 expect(res.body.data[1].text).to.equal('super thread 2') 177 expect(body.data[1].text).to.equal('super thread 2')
183 expect(res.body.data[1].totalReplies).to.equal(0) 178 expect(body.data[1].totalReplies).to.equal(0)
184 expect(res.body.data[2].text).to.equal('super thread 3') 179 expect(body.data[2].text).to.equal('super thread 3')
185 expect(res.body.data[2].totalReplies).to.equal(0) 180 expect(body.data[2].totalReplies).to.equal(0)
186 }) 181 })
187 182
188 it('Should delete a reply', async function () { 183 it('Should delete a reply', async function () {
189 await deleteVideoComment(server.url, server.accessToken, videoId, replyToDeleteId) 184 await command.delete({ videoId, commentId: replyToDeleteId })
190 185
191 { 186 {
192 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5, 'createdAt') 187 const body = await command.listThreads({ videoId: videoUUID, sort: 'createdAt' })
193 188
194 expect(res.body.total).to.equal(3) 189 expect(body.total).to.equal(3)
195 expect(res.body.totalNotDeletedComments).to.equal(5) 190 expect(body.totalNotDeletedComments).to.equal(5)
196 } 191 }
197 192
198 { 193 {
199 const res = await getVideoThreadComments(server.url, videoUUID, threadId) 194 const tree = await command.getThread({ videoId: videoUUID, threadId })
200 195
201 const tree: VideoCommentThreadTree = res.body
202 expect(tree.comment.text).equal('my super first comment') 196 expect(tree.comment.text).equal('my super first comment')
203 expect(tree.children).to.have.lengthOf(2) 197 expect(tree.children).to.have.lengthOf(2)
204 198
@@ -220,99 +214,88 @@ describe('Test video comments', function () {
220 }) 214 })
221 215
222 it('Should delete a complete thread', async function () { 216 it('Should delete a complete thread', async function () {
223 await deleteVideoComment(server.url, server.accessToken, videoId, threadId) 217 await command.delete({ videoId, commentId: threadId })
224 218
225 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5, 'createdAt') 219 const body = await command.listThreads({ videoId: videoUUID, sort: 'createdAt' })
226 expect(res.body.total).to.equal(3) 220 expect(body.total).to.equal(3)
227 expect(res.body.data).to.be.an('array') 221 expect(body.data).to.be.an('array')
228 expect(res.body.data).to.have.lengthOf(3) 222 expect(body.data).to.have.lengthOf(3)
229 223
230 expect(res.body.data[0].text).to.equal('') 224 expect(body.data[0].text).to.equal('')
231 expect(res.body.data[0].isDeleted).to.be.true 225 expect(body.data[0].isDeleted).to.be.true
232 expect(res.body.data[0].deletedAt).to.not.be.null 226 expect(body.data[0].deletedAt).to.not.be.null
233 expect(res.body.data[0].account).to.be.null 227 expect(body.data[0].account).to.be.null
234 expect(res.body.data[0].totalReplies).to.equal(2) 228 expect(body.data[0].totalReplies).to.equal(2)
235 expect(res.body.data[1].text).to.equal('super thread 2') 229 expect(body.data[1].text).to.equal('super thread 2')
236 expect(res.body.data[1].totalReplies).to.equal(0) 230 expect(body.data[1].totalReplies).to.equal(0)
237 expect(res.body.data[2].text).to.equal('super thread 3') 231 expect(body.data[2].text).to.equal('super thread 3')
238 expect(res.body.data[2].totalReplies).to.equal(0) 232 expect(body.data[2].totalReplies).to.equal(0)
239 }) 233 })
240 234
241 it('Should count replies from the video author correctly', async function () { 235 it('Should count replies from the video author correctly', async function () {
242 const text = 'my super first comment' 236 await command.createThread({ videoId: videoUUID, text: 'my super first comment' })
243 await addVideoCommentThread(server.url, server.accessToken, videoUUID, text) 237
244 let res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) 238 const { data } = await command.listThreads({ videoId: videoUUID })
245 const comment: VideoComment = res.body.data[0] 239 const threadId2 = data[0].threadId
246 const threadId2 = comment.threadId
247 240
248 const text2 = 'a first answer to thread 4 by a third party' 241 const text2 = 'a first answer to thread 4 by a third party'
249 await addVideoCommentReply(server.url, userAccessTokenServer1, videoId, threadId2, text2) 242 await command.addReply({ token: userAccessTokenServer1, videoId, toCommentId: threadId2, text: text2 })
250 243
251 const text3 = 'my second answer to thread 4' 244 const text3 = 'my second answer to thread 4'
252 await addVideoCommentReply(server.url, server.accessToken, videoId, threadId2, text3) 245 await command.addReply({ videoId, toCommentId: threadId2, text: text3 })
253 246
254 res = await getVideoThreadComments(server.url, videoUUID, threadId2) 247 const tree = await command.getThread({ videoId: videoUUID, threadId: threadId2 })
255 const tree: VideoCommentThreadTree = res.body
256 expect(tree.comment.totalReplies).to.equal(tree.comment.totalRepliesFromVideoAuthor + 1) 248 expect(tree.comment.totalReplies).to.equal(tree.comment.totalRepliesFromVideoAuthor + 1)
257 }) 249 })
258 }) 250 })
259 251
260 describe('All instance comments', function () { 252 describe('All instance comments', function () {
261 async function getComments (options: any = {}) {
262 const res = await getAdminVideoComments(Object.assign({
263 url: server.url,
264 token: server.accessToken,
265 start: 0,
266 count: 10
267 }, options))
268
269 return { comments: res.body.data as VideoCommentAdmin[], total: res.body.total as number }
270 }
271 253
272 it('Should list instance comments as admin', async function () { 254 it('Should list instance comments as admin', async function () {
273 const { comments } = await getComments({ start: 0, count: 1 }) 255 const { data } = await command.listForAdmin({ start: 0, count: 1 })
274 256
275 expect(comments[0].text).to.equal('my second answer to thread 4') 257 expect(data[0].text).to.equal('my second answer to thread 4')
276 }) 258 })
277 259
278 it('Should filter instance comments by isLocal', async function () { 260 it('Should filter instance comments by isLocal', async function () {
279 const { total, comments } = await getComments({ isLocal: false }) 261 const { total, data } = await command.listForAdmin({ isLocal: false })
280 262
281 expect(comments).to.have.lengthOf(0) 263 expect(data).to.have.lengthOf(0)
282 expect(total).to.equal(0) 264 expect(total).to.equal(0)
283 }) 265 })
284 266
285 it('Should search instance comments by account', async function () { 267 it('Should search instance comments by account', async function () {
286 const { total, comments } = await getComments({ searchAccount: 'user' }) 268 const { total, data } = await command.listForAdmin({ searchAccount: 'user' })
287 269
288 expect(comments).to.have.lengthOf(1) 270 expect(data).to.have.lengthOf(1)
289 expect(total).to.equal(1) 271 expect(total).to.equal(1)
290 272
291 expect(comments[0].text).to.equal('a first answer to thread 4 by a third party') 273 expect(data[0].text).to.equal('a first answer to thread 4 by a third party')
292 }) 274 })
293 275
294 it('Should search instance comments by video', async function () { 276 it('Should search instance comments by video', async function () {
295 { 277 {
296 const { total, comments } = await getComments({ searchVideo: 'video' }) 278 const { total, data } = await command.listForAdmin({ searchVideo: 'video' })
297 279
298 expect(comments).to.have.lengthOf(7) 280 expect(data).to.have.lengthOf(7)
299 expect(total).to.equal(7) 281 expect(total).to.equal(7)
300 } 282 }
301 283
302 { 284 {
303 const { total, comments } = await getComments({ searchVideo: 'hello' }) 285 const { total, data } = await command.listForAdmin({ searchVideo: 'hello' })
304 286
305 expect(comments).to.have.lengthOf(0) 287 expect(data).to.have.lengthOf(0)
306 expect(total).to.equal(0) 288 expect(total).to.equal(0)
307 } 289 }
308 }) 290 })
309 291
310 it('Should search instance comments', async function () { 292 it('Should search instance comments', async function () {
311 const { total, comments } = await getComments({ search: 'super thread 3' }) 293 const { total, data } = await command.listForAdmin({ search: 'super thread 3' })
312 294
313 expect(comments).to.have.lengthOf(1)
314 expect(total).to.equal(1) 295 expect(total).to.equal(1)
315 expect(comments[0].text).to.equal('super thread 3') 296
297 expect(data).to.have.lengthOf(1)
298 expect(data[0].text).to.equal('super thread 3')
316 }) 299 })
317 }) 300 })
318 301
diff --git a/server/tests/cli/update-host.ts b/server/tests/cli/update-host.ts
index 09a3dd1e7..61a6c403a 100644
--- a/server/tests/cli/update-host.ts
+++ b/server/tests/cli/update-host.ts
@@ -2,7 +2,6 @@
2 2
3import 'mocha' 3import 'mocha'
4import { 4import {
5 addVideoCommentThread,
6 cleanupTests, 5 cleanupTests,
7 createUser, 6 createUser,
8 flushAndRunServer, 7 flushAndRunServer,
@@ -55,7 +54,7 @@ describe('Test update host scripts', function () {
55 54
56 // Create comments 55 // Create comments
57 const text = 'my super first comment' 56 const text = 'my super first comment'
58 await addVideoCommentThread(server.url, server.accessToken, video1UUID, text) 57 await server.commentsCommand.createThread({ videoId: video1UUID, text })
59 58
60 await waitJobs(server) 59 await waitJobs(server)
61 }) 60 })
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts
index 6ee22340b..610849105 100644
--- a/server/tests/feeds/feeds.ts
+++ b/server/tests/feeds/feeds.ts
@@ -5,7 +5,6 @@ import * as chai from 'chai'
5import * as xmlParser from 'fast-xml-parser' 5import * as xmlParser from 'fast-xml-parser'
6import { HttpStatusCode } from '@shared/core-utils' 6import { HttpStatusCode } from '@shared/core-utils'
7import { 7import {
8 addVideoCommentThread,
9 cleanupTests, 8 cleanupTests,
10 createUser, 9 createUser,
11 doubleFollow, 10 doubleFollow,
@@ -90,8 +89,8 @@ describe('Test syndication feeds', () => {
90 const res = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) 89 const res = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
91 const videoId = res.body.video.id 90 const videoId = res.body.video.id
92 91
93 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoId, 'super comment 1') 92 await servers[0].commentsCommand.createThread({ videoId, text: 'super comment 1' })
94 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoId, 'super comment 2') 93 await servers[0].commentsCommand.createThread({ videoId, text: 'super comment 2' })
95 } 94 }
96 95
97 { 96 {
@@ -99,7 +98,7 @@ describe('Test syndication feeds', () => {
99 const res = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) 98 const res = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
100 const videoId = res.body.video.id 99 const videoId = res.body.video.id
101 100
102 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoId, 'comment on unlisted video') 101 await servers[0].commentsCommand.createThread({ videoId, text: 'comment on unlisted video' })
103 } 102 }
104 103
105 await waitJobs(servers) 104 await waitJobs(servers)
@@ -277,7 +276,7 @@ describe('Test syndication feeds', () => {
277 { 276 {
278 const videoUUID = (await uploadVideoAndGetId({ server: servers[1], videoName: 'server 2' })).uuid 277 const videoUUID = (await uploadVideoAndGetId({ server: servers[1], videoName: 'server 2' })).uuid
279 await waitJobs(servers) 278 await waitJobs(servers)
280 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'super comment') 279 await servers[0].commentsCommand.createThread({ videoId: videoUUID, text: 'super comment' })
281 await waitJobs(servers) 280 await waitJobs(servers)
282 281
283 const json = await servers[1].feedCommand.getJSON({ feed: 'video-comments', query: { version: 3 } }) 282 const json = await servers[1].feedCommand.getJSON({ feed: 'video-comments', query: { version: 3 } })
diff --git a/server/tests/plugins/action-hooks.ts b/server/tests/plugins/action-hooks.ts
index fd83bf2ac..6975ca4bb 100644
--- a/server/tests/plugins/action-hooks.ts
+++ b/server/tests/plugins/action-hooks.ts
@@ -3,11 +3,8 @@
3import 'mocha' 3import 'mocha'
4import { ServerHookName, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' 4import { ServerHookName, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
5import { 5import {
6 addVideoCommentReply,
7 addVideoCommentThread,
8 blockUser, 6 blockUser,
9 createUser, 7 createUser,
10 deleteVideoComment,
11 PluginsCommand, 8 PluginsCommand,
12 registerUser, 9 registerUser,
13 removeUser, 10 removeUser,
@@ -101,20 +98,20 @@ describe('Test plugin action hooks', function () {
101 98
102 describe('Comments hooks', function () { 99 describe('Comments hooks', function () {
103 it('Should run action:api.video-thread.created', async function () { 100 it('Should run action:api.video-thread.created', async function () {
104 const res = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'thread') 101 const created = await servers[0].commentsCommand.createThread({ videoId: videoUUID, text: 'thread' })
105 threadId = res.body.comment.id 102 threadId = created.id
106 103
107 await checkHook('action:api.video-thread.created') 104 await checkHook('action:api.video-thread.created')
108 }) 105 })
109 106
110 it('Should run action:api.video-comment-reply.created', async function () { 107 it('Should run action:api.video-comment-reply.created', async function () {
111 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'reply') 108 await servers[0].commentsCommand.addReply({ videoId: videoUUID, toCommentId: threadId, text: 'reply' })
112 109
113 await checkHook('action:api.video-comment-reply.created') 110 await checkHook('action:api.video-comment-reply.created')
114 }) 111 })
115 112
116 it('Should run action:api.video-comment.deleted', async function () { 113 it('Should run action:api.video-comment.deleted', async function () {
117 await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId) 114 await servers[0].commentsCommand.delete({ videoId: videoUUID, commentId: threadId })
118 115
119 await checkHook('action:api.video-comment.deleted') 116 await checkHook('action:api.video-comment.deleted')
120 }) 117 })
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts
index a3c3c0551..c235508e8 100644
--- a/server/tests/plugins/filter-hooks.ts
+++ b/server/tests/plugins/filter-hooks.ts
@@ -4,8 +4,6 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { HttpStatusCode } from '@shared/core-utils' 5import { HttpStatusCode } from '@shared/core-utils'
6import { 6import {
7 addVideoCommentReply,
8 addVideoCommentThread,
9 cleanupTests, 7 cleanupTests,
10 doubleFollow, 8 doubleFollow,
11 flushAndRunMultipleServers, 9 flushAndRunMultipleServers,
@@ -13,10 +11,8 @@ import {
13 getMyVideos, 11 getMyVideos,
14 getVideo, 12 getVideo,
15 getVideoChannelVideos, 13 getVideoChannelVideos,
16 getVideoCommentThreads,
17 getVideosList, 14 getVideosList,
18 getVideosListPagination, 15 getVideosListPagination,
19 getVideoThreadComments,
20 getVideoWithToken, 16 getVideoWithToken,
21 ImportsCommand, 17 ImportsCommand,
22 makeRawRequest, 18 makeRawRequest,
@@ -31,7 +27,7 @@ import {
31 waitJobs, 27 waitJobs,
32 waitUntilLog 28 waitUntilLog
33} from '@shared/extra-utils' 29} from '@shared/extra-utils'
34import { VideoCommentThreadTree, VideoDetails, VideoImportState, VideoPlaylist, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' 30import { VideoDetails, VideoImportState, VideoPlaylist, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
35 31
36const expect = chai.expect 32const expect = chai.expect
37 33
@@ -226,44 +222,50 @@ describe('Test plugin filter hooks', function () {
226 }) 222 })
227 223
228 it('Should run filter:api.video-thread.create.accept.result', async function () { 224 it('Should run filter:api.video-thread.create.accept.result', async function () {
229 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment with bad word', HttpStatusCode.FORBIDDEN_403) 225 await servers[0].commentsCommand.createThread({
226 videoId: videoUUID,
227 text: 'comment with bad word',
228 expectedStatus: HttpStatusCode.FORBIDDEN_403
229 })
230 }) 230 })
231 231
232 it('Should run filter:api.video-comment-reply.create.accept.result', async function () { 232 it('Should run filter:api.video-comment-reply.create.accept.result', async function () {
233 const res = await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'thread') 233 const created = await servers[0].commentsCommand.createThread({ videoId: videoUUID, text: 'thread' })
234 threadId = res.body.comment.id 234 threadId = created.id
235 235
236 await addVideoCommentReply( 236 await servers[0].commentsCommand.addReply({
237 servers[0].url, 237 videoId: videoUUID,
238 servers[0].accessToken, 238 toCommentId: threadId,
239 videoUUID, 239 text: 'comment with bad word',
240 threadId, 240 expectedStatus: HttpStatusCode.FORBIDDEN_403
241 'comment with bad word', 241 })
242 HttpStatusCode.FORBIDDEN_403 242 await servers[0].commentsCommand.addReply({
243 ) 243 videoId: videoUUID,
244 await addVideoCommentReply(servers[0].url, servers[0].accessToken, videoUUID, threadId, 'comment with good word', HttpStatusCode.OK_200) 244 toCommentId: threadId,
245 text: 'comment with good word',
246 expectedStatus: HttpStatusCode.OK_200
247 })
245 }) 248 })
246 249
247 it('Should run filter:api.video-threads.list.params', async function () { 250 it('Should run filter:api.video-threads.list.params', async function () {
248 const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 0) 251 const { data } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID, start: 0, count: 0 })
249 252
250 // our plugin do +1 to the count parameter 253 // our plugin do +1 to the count parameter
251 expect(res.body.data).to.have.lengthOf(1) 254 expect(data).to.have.lengthOf(1)
252 }) 255 })
253 256
254 it('Should run filter:api.video-threads.list.result', async function () { 257 it('Should run filter:api.video-threads.list.result', async function () {
255 const res = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 0) 258 const { total } = await servers[0].commentsCommand.listThreads({ videoId: videoUUID, start: 0, count: 0 })
256 259
257 // Plugin do +1 to the total result 260 // Plugin do +1 to the total result
258 expect(res.body.total).to.equal(2) 261 expect(total).to.equal(2)
259 }) 262 })
260 263
261 it('Should run filter:api.video-thread-comments.list.params') 264 it('Should run filter:api.video-thread-comments.list.params')
262 265
263 it('Should run filter:api.video-thread-comments.list.result', async function () { 266 it('Should run filter:api.video-thread-comments.list.result', async function () {
264 const res = await getVideoThreadComments(servers[0].url, videoUUID, threadId) 267 const thread = await servers[0].commentsCommand.getThread({ videoId: videoUUID, threadId })
265 268
266 const thread = res.body as VideoCommentThreadTree
267 expect(thread.comment.text.endsWith(' <3')).to.be.true 269 expect(thread.comment.text.endsWith(' <3')).to.be.true
268 }) 270 })
269 271
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index 68e10af5f..8e80a9842 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -30,6 +30,7 @@ import {
30 ServicesCommand, 30 ServicesCommand,
31 StreamingPlaylistsCommand 31 StreamingPlaylistsCommand
32} from '../videos' 32} from '../videos'
33import { CommentsCommand } from '../videos/comments-command'
33import { ConfigCommand } from './config-command' 34import { ConfigCommand } from './config-command'
34import { ContactFormCommand } from './contact-form-command' 35import { ContactFormCommand } from './contact-form-command'
35import { DebugCommand } from './debug-command' 36import { DebugCommand } from './debug-command'
@@ -121,6 +122,7 @@ interface ServerInfo {
121 importsCommand?: ImportsCommand 122 importsCommand?: ImportsCommand
122 streamingPlaylistsCommand?: StreamingPlaylistsCommand 123 streamingPlaylistsCommand?: StreamingPlaylistsCommand
123 channelsCommand?: ChannelsCommand 124 channelsCommand?: ChannelsCommand
125 commentsCommand?: CommentsCommand
124} 126}
125 127
126function parallelTests () { 128function parallelTests () {
@@ -356,6 +358,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = []
356 server.importsCommand = new ImportsCommand(server) 358 server.importsCommand = new ImportsCommand(server)
357 server.streamingPlaylistsCommand = new StreamingPlaylistsCommand(server) 359 server.streamingPlaylistsCommand = new StreamingPlaylistsCommand(server)
358 server.channelsCommand = new ChannelsCommand(server) 360 server.channelsCommand = new ChannelsCommand(server)
361 server.commentsCommand = new CommentsCommand(server)
359 362
360 res(server) 363 res(server)
361 }) 364 })
diff --git a/shared/extra-utils/videos/comments-command.ts b/shared/extra-utils/videos/comments-command.ts
new file mode 100644
index 000000000..b31f3e2dd
--- /dev/null
+++ b/shared/extra-utils/videos/comments-command.ts
@@ -0,0 +1,132 @@
1import { pick } from 'lodash'
2import { ResultList, VideoComment, VideoCommentThreads, VideoCommentThreadTree } from '@shared/models'
3import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes'
4import { unwrapBody } from '../requests'
5import { AbstractCommand, OverrideCommandOptions } from '../shared'
6
7export class CommentsCommand extends AbstractCommand {
8
9 listForAdmin (options: OverrideCommandOptions & {
10 start?: number
11 count?: number
12 sort?: string
13 isLocal?: boolean
14 search?: string
15 searchAccount?: string
16 searchVideo?: string
17 } = {}) {
18 const { sort = '-createdAt' } = options
19 const path = '/api/v1/videos/comments'
20
21 const query = { sort, ...pick(options, [ 'start', 'count', 'isLocal', 'search', 'searchAccount', 'searchVideo' ]) }
22
23 return this.getRequestBody<ResultList<VideoComment>>({
24 ...options,
25
26 path,
27 query,
28 implicitToken: true,
29 defaultExpectedStatus: HttpStatusCode.OK_200
30 })
31 }
32
33 listThreads (options: OverrideCommandOptions & {
34 videoId: number | string
35 start?: number
36 count?: number
37 sort?: string
38 }) {
39 const { start, count, sort, videoId } = options
40 const path = '/api/v1/videos/' + videoId + '/comment-threads'
41
42 return this.getRequestBody<VideoCommentThreads>({
43 ...options,
44
45 path,
46 query: { start, count, sort },
47 implicitToken: false,
48 defaultExpectedStatus: HttpStatusCode.OK_200
49 })
50 }
51
52 getThread (options: OverrideCommandOptions & {
53 videoId: number | string
54 threadId: number
55 }) {
56 const { videoId, threadId } = options
57 const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
58
59 return this.getRequestBody<VideoCommentThreadTree>({
60 ...options,
61
62 path,
63 implicitToken: false,
64 defaultExpectedStatus: HttpStatusCode.OK_200
65 })
66 }
67
68 async createThread (options: OverrideCommandOptions & {
69 videoId: number | string
70 text: string
71 }) {
72 const { videoId, text } = options
73 const path = '/api/v1/videos/' + videoId + '/comment-threads'
74
75 const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({
76 ...options,
77
78 path,
79 fields: { text },
80 implicitToken: true,
81 defaultExpectedStatus: HttpStatusCode.OK_200
82 }))
83
84 return body.comment
85 }
86
87 async addReply (options: OverrideCommandOptions & {
88 videoId: number | string
89 toCommentId: number
90 text: string
91 }) {
92 const { videoId, toCommentId, text } = options
93 const path = '/api/v1/videos/' + videoId + '/comments/' + toCommentId
94
95 const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({
96 ...options,
97
98 path,
99 fields: { text },
100 implicitToken: true,
101 defaultExpectedStatus: HttpStatusCode.OK_200
102 }))
103
104 return body.comment
105 }
106
107 async findCommentId (options: OverrideCommandOptions & {
108 videoId: number | string
109 text: string
110 }) {
111 const { videoId, text } = options
112 const { data } = await this.listThreads({ videoId, count: 25, sort: '-createdAt' })
113
114 return data.find(c => c.text === text).id
115 }
116
117 delete (options: OverrideCommandOptions & {
118 videoId: number | string
119 commentId: number
120 }) {
121 const { videoId, commentId } = options
122 const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
123
124 return this.deleteRequest({
125 ...options,
126
127 path,
128 implicitToken: true,
129 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
130 })
131 }
132}
diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts
index 3bc219281..652d82842 100644
--- a/shared/extra-utils/videos/index.ts
+++ b/shared/extra-utils/videos/index.ts
@@ -4,6 +4,7 @@ export * from './captions'
4export * from './change-ownership-command' 4export * from './change-ownership-command'
5export * from './channels' 5export * from './channels'
6export * from './channels-command' 6export * from './channels-command'
7export * from './comments-command'
7export * from './history-command' 8export * from './history-command'
8export * from './imports-command' 9export * from './imports-command'
9export * from './live-command' 10export * from './live-command'
@@ -13,5 +14,5 @@ export * from './playlists'
13export * from './services-command' 14export * from './services-command'
14export * from './streaming-playlists-command' 15export * from './streaming-playlists-command'
15export * from './streaming-playlists' 16export * from './streaming-playlists'
16export * from './video-comments' 17export * from './comments-command'
17export * from './videos' 18export * from './videos'
diff --git a/shared/extra-utils/videos/streaming-playlists-command.ts b/shared/extra-utils/videos/streaming-playlists-command.ts
index 4caec7137..b109597c9 100644
--- a/shared/extra-utils/videos/streaming-playlists-command.ts
+++ b/shared/extra-utils/videos/streaming-playlists-command.ts
@@ -27,7 +27,7 @@ export class StreamingPlaylistsCommand extends AbstractCommand {
27 url: options.url, 27 url: options.url,
28 range: options.range, 28 range: options.range,
29 implicitToken: false, 29 implicitToken: false,
30 defaultExpectedStatus: HttpStatusCode.OK_200, 30 defaultExpectedStatus: HttpStatusCode.OK_200
31 })) 31 }))
32 } 32 }
33 33
diff --git a/shared/extra-utils/videos/video-comments.ts b/shared/extra-utils/videos/video-comments.ts
deleted file mode 100644
index 71b9f875a..000000000
--- a/shared/extra-utils/videos/video-comments.ts
+++ /dev/null
@@ -1,138 +0,0 @@
1/* eslint-disable @typescript-eslint/no-floating-promises */
2
3import * as request from 'supertest'
4import { makeDeleteRequest, makeGetRequest } from '../requests/requests'
5import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
6
7function getAdminVideoComments (options: {
8 url: string
9 token: string
10 start: number
11 count: number
12 sort?: string
13 isLocal?: boolean
14 search?: string
15 searchAccount?: string
16 searchVideo?: string
17}) {
18 const { url, token, start, count, sort, isLocal, search, searchAccount, searchVideo } = options
19 const path = '/api/v1/videos/comments'
20
21 const query = {
22 start,
23 count,
24 sort: sort || '-createdAt'
25 }
26
27 if (isLocal !== undefined) Object.assign(query, { isLocal })
28 if (search !== undefined) Object.assign(query, { search })
29 if (searchAccount !== undefined) Object.assign(query, { searchAccount })
30 if (searchVideo !== undefined) Object.assign(query, { searchVideo })
31
32 return makeGetRequest({
33 url,
34 path,
35 token,
36 query,
37 statusCodeExpected: HttpStatusCode.OK_200
38 })
39}
40
41function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) {
42 const path = '/api/v1/videos/' + videoId + '/comment-threads'
43
44 const req = request(url)
45 .get(path)
46 .query({ start: start })
47 .query({ count: count })
48
49 if (sort) req.query({ sort })
50 if (token) req.set('Authorization', 'Bearer ' + token)
51
52 return req.set('Accept', 'application/json')
53 .expect(HttpStatusCode.OK_200)
54 .expect('Content-Type', /json/)
55}
56
57function getVideoThreadComments (url: string, videoId: number | string, threadId: number, token?: string) {
58 const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
59
60 const req = request(url)
61 .get(path)
62 .set('Accept', 'application/json')
63
64 if (token) req.set('Authorization', 'Bearer ' + token)
65
66 return req.expect(HttpStatusCode.OK_200)
67 .expect('Content-Type', /json/)
68}
69
70function addVideoCommentThread (
71 url: string,
72 token: string,
73 videoId: number | string,
74 text: string,
75 expectedStatus = HttpStatusCode.OK_200
76) {
77 const path = '/api/v1/videos/' + videoId + '/comment-threads'
78
79 return request(url)
80 .post(path)
81 .send({ text })
82 .set('Accept', 'application/json')
83 .set('Authorization', 'Bearer ' + token)
84 .expect(expectedStatus)
85}
86
87function addVideoCommentReply (
88 url: string,
89 token: string,
90 videoId: number | string,
91 inReplyToCommentId: number,
92 text: string,
93 expectedStatus = HttpStatusCode.OK_200
94) {
95 const path = '/api/v1/videos/' + videoId + '/comments/' + inReplyToCommentId
96
97 return request(url)
98 .post(path)
99 .send({ text })
100 .set('Accept', 'application/json')
101 .set('Authorization', 'Bearer ' + token)
102 .expect(expectedStatus)
103}
104
105async function findCommentId (url: string, videoId: number | string, text: string) {
106 const res = await getVideoCommentThreads(url, videoId, 0, 25, '-createdAt')
107
108 return res.body.data.find(c => c.text === text).id as number
109}
110
111function deleteVideoComment (
112 url: string,
113 token: string,
114 videoId: number | string,
115 commentId: number,
116 statusCodeExpected = HttpStatusCode.NO_CONTENT_204
117) {
118 const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
119
120 return makeDeleteRequest({
121 url,
122 path,
123 token,
124 statusCodeExpected
125 })
126}
127
128// ---------------------------------------------------------------------------
129
130export {
131 getVideoCommentThreads,
132 getAdminVideoComments,
133 getVideoThreadComments,
134 addVideoCommentThread,
135 addVideoCommentReply,
136 findCommentId,
137 deleteVideoComment
138}
diff --git a/shared/models/videos/comment/index.ts b/shared/models/videos/comment/index.ts
index 7b9261a36..80c6c0724 100644
--- a/shared/models/videos/comment/index.ts
+++ b/shared/models/videos/comment/index.ts
@@ -1 +1,2 @@
1export * from './video-comment-create.model'
1export * from './video-comment.model' 2export * from './video-comment.model'
diff --git a/shared/models/videos/comment/video-comment-create.model.ts b/shared/models/videos/comment/video-comment-create.model.ts
new file mode 100644
index 000000000..1f0135405
--- /dev/null
+++ b/shared/models/videos/comment/video-comment-create.model.ts
@@ -0,0 +1,3 @@
1export interface VideoCommentCreate {
2 text: string
3}
diff --git a/shared/models/videos/comment/video-comment.model.ts b/shared/models/videos/comment/video-comment.model.ts
index 79c0e4c0a..5a96f9d4a 100644
--- a/shared/models/videos/comment/video-comment.model.ts
+++ b/shared/models/videos/comment/video-comment.model.ts
@@ -1,3 +1,4 @@
1import { ResultList } from '@shared/models/common'
1import { Account } from '../../actors' 2import { Account } from '../../actors'
2 3
3export interface VideoComment { 4export interface VideoComment {
@@ -36,11 +37,9 @@ export interface VideoCommentAdmin {
36 } 37 }
37} 38}
38 39
40export type VideoCommentThreads = ResultList<VideoComment> & { totalNotDeletedComments: number }
41
39export interface VideoCommentThreadTree { 42export interface VideoCommentThreadTree {
40 comment: VideoComment 43 comment: VideoComment
41 children: VideoCommentThreadTree[] 44 children: VideoCommentThreadTree[]
42} 45}
43
44export interface VideoCommentCreate {
45 text: string
46}