aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/controllers/api/videos/comment.ts2
-rw-r--r--server/models/video/video-comment.ts52
-rw-r--r--server/tests/api/users/blocklist.ts8
3 files changed, 48 insertions, 14 deletions
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts
index bdd3cf9e2..2dcb85ecf 100644
--- a/server/controllers/api/videos/comment.ts
+++ b/server/controllers/api/videos/comment.ts
@@ -178,5 +178,5 @@ async function removeVideoComment (req: express.Request, res: express.Response)
178 178
179 auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON())) 179 auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON()))
180 180
181 return res.type('json').status(204) 181 return res.type('json').status(204).end()
182} 182}
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts
index 7c890ce6d..dfeb1c4e7 100644
--- a/server/models/video/video-comment.ts
+++ b/server/models/video/video-comment.ts
@@ -24,13 +24,14 @@ import {
24 MCommentOwnerVideoReply 24 MCommentOwnerVideoReply
25} from '../../typings/models/video' 25} from '../../typings/models/video'
26import { AccountModel } from '../account/account' 26import { AccountModel } from '../account/account'
27import { ActorModel } from '../activitypub/actor' 27import { ActorModel, unusedActorAttributesForAPI } from '../activitypub/actor'
28import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getCommentSort, throwIfNotValid } from '../utils' 28import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getCommentSort, throwIfNotValid } from '../utils'
29import { VideoModel } from './video' 29import { VideoModel } from './video'
30import { VideoChannelModel } from './video-channel' 30import { VideoChannelModel } from './video-channel'
31 31
32enum ScopeNames { 32enum ScopeNames {
33 WITH_ACCOUNT = 'WITH_ACCOUNT', 33 WITH_ACCOUNT = 'WITH_ACCOUNT',
34 WITH_ACCOUNT_FOR_API = 'WITH_ACCOUNT_FOR_API',
34 WITH_IN_REPLY_TO = 'WITH_IN_REPLY_TO', 35 WITH_IN_REPLY_TO = 'WITH_IN_REPLY_TO',
35 WITH_VIDEO = 'WITH_VIDEO', 36 WITH_VIDEO = 'WITH_VIDEO',
36 ATTRIBUTES_FOR_API = 'ATTRIBUTES_FOR_API' 37 ATTRIBUTES_FOR_API = 'ATTRIBUTES_FOR_API'
@@ -82,6 +83,22 @@ enum ScopeNames {
82 } 83 }
83 ] 84 ]
84 }, 85 },
86 [ScopeNames.WITH_ACCOUNT_FOR_API]: {
87 include: [
88 {
89 model: AccountModel.unscoped(),
90 include: [
91 {
92 attributes: {
93 exclude: unusedActorAttributesForAPI
94 },
95 model: ActorModel, // Default scope includes avatar and server
96 required: true
97 }
98 ]
99 }
100 ]
101 },
85 [ScopeNames.WITH_IN_REPLY_TO]: { 102 [ScopeNames.WITH_IN_REPLY_TO]: {
86 include: [ 103 include: [
87 { 104 {
@@ -275,18 +292,33 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
275 limit: count, 292 limit: count,
276 order: getCommentSort(sort), 293 order: getCommentSort(sort),
277 where: { 294 where: {
278 videoId, 295 [Op.and]: [
279 inReplyToCommentId: null, 296 {
280 accountId: { 297 videoId
281 [Op.notIn]: Sequelize.literal( 298 },
282 '(' + buildBlockedAccountSQL(serverAccountId, userAccountId) + ')' 299 {
283 ) 300 inReplyToCommentId: null
284 } 301 },
302 {
303 [Op.or]: [
304 {
305 accountId: {
306 [Op.notIn]: Sequelize.literal(
307 '(' + buildBlockedAccountSQL(serverAccountId, userAccountId) + ')'
308 )
309 }
310 },
311 {
312 accountId: null
313 }
314 ]
315 }
316 ]
285 } 317 }
286 } 318 }
287 319
288 const scopes: (string | ScopeOptions)[] = [ 320 const scopes: (string | ScopeOptions)[] = [
289 ScopeNames.WITH_ACCOUNT, 321 ScopeNames.WITH_ACCOUNT_FOR_API,
290 { 322 {
291 method: [ ScopeNames.ATTRIBUTES_FOR_API, serverAccountId, userAccountId ] 323 method: [ ScopeNames.ATTRIBUTES_FOR_API, serverAccountId, userAccountId ]
292 } 324 }
@@ -328,7 +360,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
328 } 360 }
329 361
330 const scopes: any[] = [ 362 const scopes: any[] = [
331 ScopeNames.WITH_ACCOUNT, 363 ScopeNames.WITH_ACCOUNT_FOR_API,
332 { 364 {
333 method: [ ScopeNames.ATTRIBUTES_FOR_API, serverAccountId, userAccountId ] 365 method: [ ScopeNames.ATTRIBUTES_FOR_API, serverAccountId, userAccountId ]
334 } 366 }
diff --git a/server/tests/api/users/blocklist.ts b/server/tests/api/users/blocklist.ts
index 21b9ae4f8..e37dbb5a4 100644
--- a/server/tests/api/users/blocklist.ts
+++ b/server/tests/api/users/blocklist.ts
@@ -195,7 +195,7 @@ describe('Test blocklist', function () {
195 }) 195 })
196 196
197 it('Should hide its comments', async function () { 197 it('Should hide its comments', async function () {
198 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 5, '-createdAt', servers[0].accessToken) 198 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 25, '-createdAt', servers[0].accessToken)
199 199
200 const threads: VideoComment[] = resThreads.body.data 200 const threads: VideoComment[] = resThreads.body.data
201 expect(threads).to.have.lengthOf(1) 201 expect(threads).to.have.lengthOf(1)
@@ -467,9 +467,11 @@ describe('Test blocklist', function () {
467 467
468 it('Should hide its comments', async function () { 468 it('Should hide its comments', async function () {
469 for (const token of [ userModeratorToken, servers[0].accessToken ]) { 469 for (const token of [ userModeratorToken, servers[0].accessToken ]) {
470 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 5, '-createdAt', token) 470 const resThreads = await getVideoCommentThreads(servers[0].url, videoUUID1, 0, 20, '-createdAt', token)
471
472 let threads: VideoComment[] = resThreads.body.data
473 threads = threads.filter(t => t.isDeleted === false)
471 474
472 const threads: VideoComment[] = resThreads.body.data
473 expect(threads).to.have.lengthOf(1) 475 expect(threads).to.have.lengthOf(1)
474 expect(threads[0].totalReplies).to.equal(0) 476 expect(threads[0].totalReplies).to.equal(0)
475 477