From 4635f59d7c3fea4b97029f10886c62fdf38b2084 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 27 Dec 2017 16:11:53 +0100 Subject: Add video comment components --- server/controllers/api/videos/comment.ts | 12 +++------ server/lib/video-comment.ts | 12 ++++++--- server/middlewares/validators/pagination.ts | 4 +-- server/models/video/video-comment.ts | 42 +++++++++++++++++++++++++---- server/tests/api/video-comments.ts | 18 ++++++++++++- 5 files changed, 68 insertions(+), 20 deletions(-) (limited to 'server') diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts index e9dbb6d1b..276948098 100644 --- a/server/controllers/api/videos/comment.ts +++ b/server/controllers/api/videos/comment.ts @@ -66,9 +66,7 @@ async function addVideoCommentThreadRetryWrapper (req: express.Request, res: exp const comment = await retryTransactionWrapper(addVideoCommentThread, options) res.json({ - comment: { - id: comment.id - } + comment: comment.toFormattedJSON() }).end() } @@ -80,7 +78,7 @@ function addVideoCommentThread (req: express.Request, res: express.Response) { text: videoCommentInfo.text, inReplyToComment: null, video: res.locals.video, - accountId: res.locals.oauth.token.User.Account.id + account: res.locals.oauth.token.User.Account }, t) }) } @@ -94,9 +92,7 @@ async function addVideoCommentReplyRetryWrapper (req: express.Request, res: expr const comment = await retryTransactionWrapper(addVideoCommentReply, options) res.json({ - comment: { - id: comment.id - } + comment: comment.toFormattedJSON() }).end() } @@ -108,7 +104,7 @@ function addVideoCommentReply (req: express.Request, res: express.Response, next text: videoCommentInfo.text, inReplyToComment: res.locals.videoComment, video: res.locals.video, - accountId: res.locals.oauth.token.User.Account.id + account: res.locals.oauth.token.User.Account }, t) }) } diff --git a/server/lib/video-comment.ts b/server/lib/video-comment.ts index ef6a8f097..0d744c526 100644 --- a/server/lib/video-comment.ts +++ b/server/lib/video-comment.ts @@ -1,29 +1,32 @@ import * as Sequelize from 'sequelize' import { ResultList } from '../../shared/models' import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model' +import { AccountModel } from '../models/account/account' import { VideoModel } from '../models/video/video' import { VideoCommentModel } from '../models/video/video-comment' -import { getVideoCommentActivityPubUrl, sendVideoRateChangeToFollowers } from './activitypub' +import { getVideoCommentActivityPubUrl } from './activitypub' import { sendCreateVideoCommentToOrigin, sendCreateVideoCommentToVideoFollowers } from './activitypub/send' async function createVideoComment (obj: { text: string, inReplyToComment: VideoCommentModel, video: VideoModel - accountId: number + account: AccountModel }, t: Sequelize.Transaction) { let originCommentId: number = null + let inReplyToCommentId: number = null if (obj.inReplyToComment) { originCommentId = obj.inReplyToComment.originCommentId || obj.inReplyToComment.id + inReplyToCommentId = obj.inReplyToComment.id } const comment = await VideoCommentModel.create({ text: obj.text, originCommentId, - inReplyToCommentId: obj.inReplyToComment.id, + inReplyToCommentId, videoId: obj.video.id, - accountId: obj.accountId, + accountId: obj.account.id, url: 'fake url' }, { transaction: t, validate: false }) @@ -32,6 +35,7 @@ async function createVideoComment (obj: { const savedComment = await comment.save({ transaction: t }) savedComment.InReplyToVideoComment = obj.inReplyToComment savedComment.Video = obj.video + savedComment.Account = obj.account if (savedComment.Video.isOwned()) { await sendCreateVideoCommentToVideoFollowers(savedComment, t) diff --git a/server/middlewares/validators/pagination.ts b/server/middlewares/validators/pagination.ts index 0895b4eb8..25debfa6e 100644 --- a/server/middlewares/validators/pagination.ts +++ b/server/middlewares/validators/pagination.ts @@ -4,8 +4,8 @@ import { logger } from '../../helpers' import { areValidationErrors } from './utils' const paginationValidator = [ - query('start').optional().isInt().withMessage('Should have a number start'), - query('count').optional().isInt().withMessage('Should have a number count'), + query('start').optional().isInt({ min: 0 }).withMessage('Should have a number start'), + query('count').optional().isInt({ min: 0 }).withMessage('Should have a number count'), (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug('Checking pagination parameters', { parameters: req.query }) diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 25cd6d563..a3e8c48d4 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts @@ -8,18 +8,48 @@ import { VideoComment } from '../../../shared/models/videos/video-comment.model' import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub' import { CONSTRAINTS_FIELDS } from '../../initializers' import { AccountModel } from '../account/account' +import { ActorModel } from '../activitypub/actor' +import { ServerModel } from '../server/server' import { getSort, throwIfNotValid } from '../utils' import { VideoModel } from './video' enum ScopeNames { WITH_ACCOUNT = 'WITH_ACCOUNT', - WITH_IN_REPLY_TO = 'WITH_IN_REPLY_TO' + WITH_IN_REPLY_TO = 'WITH_IN_REPLY_TO', + ATTRIBUTES_FOR_API = 'ATTRIBUTES_FOR_API' } @Scopes({ + [ScopeNames.ATTRIBUTES_FOR_API]: { + attributes: { + include: [ + [ + Sequelize.literal( + '(SELECT COUNT("replies"."id") ' + + 'FROM "videoComment" AS "replies" ' + + 'WHERE "replies"."originCommentId" = "VideoCommentModel"."id")' + ), + 'totalReplies' + ] + ] + } + }, [ScopeNames.WITH_ACCOUNT]: { include: [ - () => AccountModel + { + model: () => AccountModel, + include: [ + { + model: () => ActorModel, + include: [ + { + model: () => ServerModel, + required: false + } + ] + } + ] + } ] }, [ScopeNames.WITH_IN_REPLY_TO]: { @@ -149,7 +179,7 @@ export class VideoCommentModel extends Model { } return VideoCommentModel - .scope([ ScopeNames.WITH_ACCOUNT ]) + .scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.ATTRIBUTES_FOR_API ]) .findAndCountAll(query) .then(({ rows, count }) => { return { total: count, data: rows } @@ -169,7 +199,7 @@ export class VideoCommentModel extends Model { } return VideoCommentModel - .scope([ ScopeNames.WITH_ACCOUNT ]) + .scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.ATTRIBUTES_FOR_API ]) .findAndCountAll(query) .then(({ rows, count }) => { return { total: count, data: rows } @@ -186,8 +216,10 @@ export class VideoCommentModel extends Model { videoId: this.videoId, createdAt: this.createdAt, updatedAt: this.updatedAt, + totalReplies: this.get('totalReplies') || 0, account: { - name: this.Account.name + name: this.Account.name, + host: this.Account.Actor.getHost() } } as VideoComment } diff --git a/server/tests/api/video-comments.ts b/server/tests/api/video-comments.ts index 2f1e6260a..2c7d1c6e2 100644 --- a/server/tests/api/video-comments.ts +++ b/server/tests/api/video-comments.ts @@ -39,7 +39,18 @@ describe('Test video comments', function () { it('Should create a thread in this video', async function () { const text = 'my super first comment' - await addVideoCommentThread(server.url, server.accessToken, videoUUID, text) + const res = await addVideoCommentThread(server.url, server.accessToken, videoUUID, text) + const comment = res.body + + expect(comment.inReplyToCommentId).to.be.null + expect(comment.text).equal('my super first comment') + expect(comment.videoId).to.equal(videoId) + expect(comment.id).to.equal(comment.threadId) + expect(comment.account.name).to.equal('root') + expect(comment.account.host).to.equal('localhost:9001') + expect(comment.totalReplies).to.equal(0) + expect(dateIsValid(comment.createdAt as string)).to.be.true + expect(dateIsValid(comment.updatedAt as string)).to.be.true }) it('Should list threads of this video', async function () { @@ -55,6 +66,8 @@ describe('Test video comments', function () { expect(comment.videoId).to.equal(videoId) expect(comment.id).to.equal(comment.threadId) expect(comment.account.name).to.equal('root') + expect(comment.account.host).to.equal('localhost:9001') + expect(comment.totalReplies).to.equal(0) expect(dateIsValid(comment.createdAt as string)).to.be.true expect(dateIsValid(comment.updatedAt as string)).to.be.true @@ -120,8 +133,11 @@ describe('Test video comments', function () { expect(res.body.data).to.have.lengthOf(3) expect(res.body.data[0].text).to.equal('my super first comment') + expect(res.body.data[0].totalReplies).to.equal(2) expect(res.body.data[1].text).to.equal('super thread 2') + expect(res.body.data[1].totalReplies).to.equal(1) expect(res.body.data[2].text).to.equal('super thread 3') + expect(res.body.data[2].totalReplies).to.equal(0) }) after(async function () { -- cgit v1.2.3