Add ability to disable video comments
This commit is contained in:
parent
c5911fd347
commit
47564bbe2e
|
@ -1,14 +1,10 @@
|
||||||
import { Account } from '../../../../../shared/models/actors'
|
|
||||||
import { Video } from '../../shared/video/video.model'
|
|
||||||
import { AuthUser } from '../../core'
|
|
||||||
import {
|
import {
|
||||||
VideoDetails as VideoDetailsServerModel,
|
UserRight, VideoChannel, VideoDetails as VideoDetailsServerModel, VideoFile, VideoPrivacy,
|
||||||
VideoFile,
|
VideoResolution
|
||||||
VideoChannel,
|
|
||||||
VideoResolution,
|
|
||||||
UserRight,
|
|
||||||
VideoPrivacy
|
|
||||||
} from '../../../../../shared'
|
} from '../../../../../shared'
|
||||||
|
import { Account } from '../../../../../shared/models/actors'
|
||||||
|
import { AuthUser } from '../../core'
|
||||||
|
import { Video } from '../../shared/video/video.model'
|
||||||
|
|
||||||
export class VideoDetails extends Video implements VideoDetailsServerModel {
|
export class VideoDetails extends Video implements VideoDetailsServerModel {
|
||||||
accountName: string
|
accountName: string
|
||||||
|
@ -48,6 +44,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
|
||||||
account: Account
|
account: Account
|
||||||
likesPercent: number
|
likesPercent: number
|
||||||
dislikesPercent: number
|
dislikesPercent: number
|
||||||
|
commentsEnabled: boolean
|
||||||
|
|
||||||
constructor (hash: VideoDetailsServerModel) {
|
constructor (hash: VideoDetailsServerModel) {
|
||||||
super(hash)
|
super(hash)
|
||||||
|
@ -59,6 +56,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
|
||||||
this.channel = hash.channel
|
this.channel = hash.channel
|
||||||
this.account = hash.account
|
this.account = hash.account
|
||||||
this.tags = hash.tags
|
this.tags = hash.tags
|
||||||
|
this.commentsEnabled = hash.commentsEnabled
|
||||||
|
|
||||||
this.likesPercent = (this.likes / (this.likes + this.dislikes)) * 100
|
this.likesPercent = (this.likes / (this.likes + this.dislikes)) * 100
|
||||||
this.dislikesPercent = (this.dislikes / (this.likes + this.dislikes)) * 100
|
this.dislikesPercent = (this.dislikes / (this.likes + this.dislikes)) * 100
|
||||||
|
|
|
@ -9,6 +9,7 @@ export class VideoEdit {
|
||||||
name: string
|
name: string
|
||||||
tags: string[]
|
tags: string[]
|
||||||
nsfw: boolean
|
nsfw: boolean
|
||||||
|
commentsEnabled: boolean
|
||||||
channel: number
|
channel: number
|
||||||
privacy: VideoPrivacy
|
privacy: VideoPrivacy
|
||||||
uuid?: string
|
uuid?: string
|
||||||
|
@ -25,6 +26,7 @@ export class VideoEdit {
|
||||||
this.name = videoDetails.name
|
this.name = videoDetails.name
|
||||||
this.tags = videoDetails.tags
|
this.tags = videoDetails.tags
|
||||||
this.nsfw = videoDetails.nsfw
|
this.nsfw = videoDetails.nsfw
|
||||||
|
this.commentsEnabled = videoDetails.commentsEnabled
|
||||||
this.channel = videoDetails.channel.id
|
this.channel = videoDetails.channel.id
|
||||||
this.privacy = videoDetails.privacy
|
this.privacy = videoDetails.privacy
|
||||||
}
|
}
|
||||||
|
@ -45,6 +47,7 @@ export class VideoEdit {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
tags: this.tags,
|
tags: this.tags,
|
||||||
nsfw: this.nsfw,
|
nsfw: this.nsfw,
|
||||||
|
commentsEnabled: this.commentsEnabled,
|
||||||
channelId: this.channel,
|
channelId: this.channel,
|
||||||
privacy: this.privacy
|
privacy: this.privacy
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,8 @@ export class VideoService {
|
||||||
description,
|
description,
|
||||||
privacy: video.privacy,
|
privacy: video.privacy,
|
||||||
tags: video.tags,
|
tags: video.tags,
|
||||||
nsfw: video.nsfw
|
nsfw: video.nsfw,
|
||||||
|
commentsEnabled: video.commentsEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.authHttp.put(VideoService.BASE_VIDEO_URL + video.id, body)
|
return this.authHttp.put(VideoService.BASE_VIDEO_URL + video.id, body)
|
||||||
|
|
|
@ -99,5 +99,11 @@
|
||||||
<label for="nsfw">This video contains mature or explicit content</label>
|
<label for="nsfw">This video contains mature or explicit content</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-checkbox">
|
||||||
|
<input type="checkbox" id="commentsEnabled" formControlName="commentsEnabled" />
|
||||||
|
<label for="commentsEnabled"></label>
|
||||||
|
<label for="commentsEnabled">Enable video comments</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -70,6 +70,7 @@ export class VideoEditComponent implements OnInit {
|
||||||
this.form.addControl('privacy', new FormControl('', VIDEO_PRIVACY.VALIDATORS))
|
this.form.addControl('privacy', new FormControl('', VIDEO_PRIVACY.VALIDATORS))
|
||||||
this.form.addControl('channelId', new FormControl({ value: '', disabled: true }))
|
this.form.addControl('channelId', new FormControl({ value: '', disabled: true }))
|
||||||
this.form.addControl('nsfw', new FormControl(false))
|
this.form.addControl('nsfw', new FormControl(false))
|
||||||
|
this.form.addControl('commentsEnabled', new FormControl(true))
|
||||||
this.form.addControl('category', new FormControl('', VIDEO_CATEGORY.VALIDATORS))
|
this.form.addControl('category', new FormControl('', VIDEO_CATEGORY.VALIDATORS))
|
||||||
this.form.addControl('licence', new FormControl('', VIDEO_LICENCE.VALIDATORS))
|
this.form.addControl('licence', new FormControl('', VIDEO_LICENCE.VALIDATORS))
|
||||||
this.form.addControl('language', new FormControl('', VIDEO_LANGUAGE.VALIDATORS))
|
this.form.addControl('language', new FormControl('', VIDEO_LANGUAGE.VALIDATORS))
|
||||||
|
|
|
@ -88,6 +88,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
const name = videofile.name.replace(/\.[^/.]+$/, '')
|
const name = videofile.name.replace(/\.[^/.]+$/, '')
|
||||||
const privacy = this.firstStepPrivacyId.toString()
|
const privacy = this.firstStepPrivacyId.toString()
|
||||||
const nsfw = false
|
const nsfw = false
|
||||||
|
const commentsEnabled = true
|
||||||
const channelId = this.firstStepChannelId.toString()
|
const channelId = this.firstStepChannelId.toString()
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
|
@ -95,6 +96,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
// Put the video "private" -> we wait he validates the second step
|
// Put the video "private" -> we wait he validates the second step
|
||||||
formData.append('privacy', VideoPrivacy.PRIVATE.toString())
|
formData.append('privacy', VideoPrivacy.PRIVATE.toString())
|
||||||
formData.append('nsfw', '' + nsfw)
|
formData.append('nsfw', '' + nsfw)
|
||||||
|
formData.append('commentsEnabled', '' + commentsEnabled)
|
||||||
formData.append('channelId', '' + channelId)
|
formData.append('channelId', '' + channelId)
|
||||||
formData.append('videofile', videofile)
|
formData.append('videofile', videofile)
|
||||||
|
|
||||||
|
|
|
@ -3,35 +3,43 @@
|
||||||
Comments
|
Comments
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<my-video-comment-add
|
<ng-template [ngIf]="video.commentsEnabled === true">
|
||||||
*ngIf="isUserLoggedIn()"
|
<my-video-comment-add
|
||||||
[video]="video"
|
*ngIf="isUserLoggedIn()"
|
||||||
(commentCreated)="onCommentThreadCreated($event)"
|
[video]="video"
|
||||||
></my-video-comment-add>
|
(commentCreated)="onCommentThreadCreated($event)"
|
||||||
|
></my-video-comment-add>
|
||||||
|
|
||||||
<div
|
<div *ngIf="componentPagination.totalItems === 0 && comments.length === 0">No comments.</div>
|
||||||
class="comment-threads"
|
|
||||||
infiniteScroll
|
|
||||||
[infiniteScrollUpDistance]="1.5"
|
|
||||||
[infiniteScrollDistance]="0.5"
|
|
||||||
(scrolled)="onNearOfBottom()"
|
|
||||||
>
|
|
||||||
<div *ngFor="let comment of comments">
|
|
||||||
<my-video-comment
|
|
||||||
[comment]="comment"
|
|
||||||
[video]="video"
|
|
||||||
[inReplyToCommentId]="inReplyToCommentId"
|
|
||||||
[commentTree]="threadComments[comment.id]"
|
|
||||||
(wantedToReply)="onWantedToReply($event)"
|
|
||||||
(resetReply)="onResetReply()"
|
|
||||||
></my-video-comment>
|
|
||||||
|
|
||||||
<div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment)" class="view-replies">
|
<div
|
||||||
View all {{ comment.totalReplies }} replies
|
class="comment-threads"
|
||||||
|
infiniteScroll
|
||||||
|
[infiniteScrollUpDistance]="1.5"
|
||||||
|
[infiniteScrollDistance]="0.5"
|
||||||
|
(scrolled)="onNearOfBottom()"
|
||||||
|
>
|
||||||
|
<div *ngFor="let comment of comments">
|
||||||
|
<my-video-comment
|
||||||
|
[comment]="comment"
|
||||||
|
[video]="video"
|
||||||
|
[inReplyToCommentId]="inReplyToCommentId"
|
||||||
|
[commentTree]="threadComments[comment.id]"
|
||||||
|
(wantedToReply)="onWantedToReply($event)"
|
||||||
|
(resetReply)="onResetReply()"
|
||||||
|
></my-video-comment>
|
||||||
|
|
||||||
<span *ngIf="!threadLoading[comment.id]" class="glyphicon glyphicon-menu-down"></span>
|
<div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment)" class="view-replies">
|
||||||
<my-loader class="comment-thread-loading" [loading]="threadLoading[comment.id]"></my-loader>
|
View all {{ comment.totalReplies }} replies
|
||||||
|
|
||||||
|
<span *ngIf="!threadLoading[comment.id]" class="glyphicon glyphicon-menu-down"></span>
|
||||||
|
<my-loader class="comment-thread-loading" [loading]="threadLoading[comment.id]"></my-loader>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<div *ngIf="video.commentsEnabled === false">
|
||||||
|
Comments are disabled.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { AuthService } from '../../../core/auth'
|
||||||
import { ComponentPagination } from '../../../shared/rest/component-pagination.model'
|
import { ComponentPagination } from '../../../shared/rest/component-pagination.model'
|
||||||
import { User } from '../../../shared/users'
|
import { User } from '../../../shared/users'
|
||||||
import { SortField } from '../../../shared/video/sort-field.type'
|
import { SortField } from '../../../shared/video/sort-field.type'
|
||||||
|
import { VideoDetails } from '../../../shared/video/video-details.model'
|
||||||
import { Video } from '../../../shared/video/video.model'
|
import { Video } from '../../../shared/video/video.model'
|
||||||
import { VideoComment } from './video-comment.model'
|
import { VideoComment } from './video-comment.model'
|
||||||
import { VideoCommentService } from './video-comment.service'
|
import { VideoCommentService } from './video-comment.service'
|
||||||
|
@ -15,7 +16,7 @@ import { VideoCommentService } from './video-comment.service'
|
||||||
styleUrls: ['./video-comments.component.scss']
|
styleUrls: ['./video-comments.component.scss']
|
||||||
})
|
})
|
||||||
export class VideoCommentsComponent implements OnInit {
|
export class VideoCommentsComponent implements OnInit {
|
||||||
@Input() video: Video
|
@Input() video: VideoDetails
|
||||||
@Input() user: User
|
@Input() user: User
|
||||||
|
|
||||||
comments: VideoComment[] = []
|
comments: VideoComment[] = []
|
||||||
|
@ -36,7 +37,9 @@ export class VideoCommentsComponent implements OnInit {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.loadMoreComments()
|
if (this.video.commentsEnabled === true) {
|
||||||
|
this.loadMoreComments()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewReplies (comment: VideoComment) {
|
viewReplies (comment: VideoComment) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
|
import { ResultList } from '../../../../shared/models'
|
||||||
import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model'
|
import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model'
|
||||||
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
||||||
import { getFormattedObjects } from '../../../helpers/utils'
|
import { getFormattedObjects } from '../../../helpers/utils'
|
||||||
|
@ -10,6 +11,7 @@ import {
|
||||||
addVideoCommentReplyValidator, addVideoCommentThreadValidator, listVideoCommentThreadsValidator,
|
addVideoCommentReplyValidator, addVideoCommentThreadValidator, listVideoCommentThreadsValidator,
|
||||||
listVideoThreadCommentsValidator
|
listVideoThreadCommentsValidator
|
||||||
} from '../../../middlewares/validators/video-comments'
|
} from '../../../middlewares/validators/video-comments'
|
||||||
|
import { VideoModel } from '../../../models/video/video'
|
||||||
import { VideoCommentModel } from '../../../models/video/video-comment'
|
import { VideoCommentModel } from '../../../models/video/video-comment'
|
||||||
|
|
||||||
const videoCommentRouter = express.Router()
|
const videoCommentRouter = express.Router()
|
||||||
|
@ -47,13 +49,33 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async function listVideoThreads (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function listVideoThreads (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const resultList = await VideoCommentModel.listThreadsForApi(res.locals.video.id, req.query.start, req.query.count, req.query.sort)
|
const video = res.locals.video as VideoModel
|
||||||
|
let resultList: ResultList<VideoCommentModel>
|
||||||
|
|
||||||
|
if (video.commentsEnabled === true) {
|
||||||
|
resultList = await VideoCommentModel.listThreadsForApi(video.id, req.query.start, req.query.count, req.query.sort)
|
||||||
|
} else {
|
||||||
|
resultList = {
|
||||||
|
total: 0,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function listVideoThreadComments (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function listVideoThreadComments (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const resultList = await VideoCommentModel.listThreadCommentsForApi(res.locals.video.id, res.locals.videoCommentThread.id)
|
const video = res.locals.video as VideoModel
|
||||||
|
let resultList: ResultList<VideoCommentModel>
|
||||||
|
|
||||||
|
if (video.commentsEnabled === true) {
|
||||||
|
resultList = await VideoCommentModel.listThreadCommentsForApi(res.locals.video.id, res.locals.videoCommentThread.id)
|
||||||
|
} else {
|
||||||
|
resultList = {
|
||||||
|
total: 0,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res.json(buildFormattedCommentTree(resultList))
|
return res.json(buildFormattedCommentTree(resultList))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import * as multer from 'multer'
|
|
||||||
import { extname, join } from 'path'
|
import { extname, join } from 'path'
|
||||||
import { VideoCreate, VideoPrivacy, VideoUpdate } from '../../../../shared'
|
import { VideoCreate, VideoPrivacy, VideoUpdate } from '../../../../shared'
|
||||||
import { renamePromise } from '../../../helpers/core-utils'
|
import { renamePromise } from '../../../helpers/core-utils'
|
||||||
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
||||||
import { getVideoFileHeight } from '../../../helpers/ffmpeg-utils'
|
import { getVideoFileHeight } from '../../../helpers/ffmpeg-utils'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { createReqFiles, generateRandomString, getFormattedObjects, getServerActor, resetSequelizeInstance } from '../../../helpers/utils'
|
import { createReqFiles, getFormattedObjects, getServerActor, resetSequelizeInstance } from '../../../helpers/utils'
|
||||||
import {
|
import {
|
||||||
CONFIG, sequelizeTypescript, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_MIMETYPE_EXT,
|
CONFIG, sequelizeTypescript, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_MIMETYPE_EXT,
|
||||||
VIDEO_PRIVACIES
|
VIDEO_PRIVACIES
|
||||||
|
@ -141,6 +140,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
|
||||||
category: videoInfo.category,
|
category: videoInfo.category,
|
||||||
licence: videoInfo.licence,
|
licence: videoInfo.licence,
|
||||||
language: videoInfo.language,
|
language: videoInfo.language,
|
||||||
|
commentsEnabled: videoInfo.commentsEnabled,
|
||||||
nsfw: videoInfo.nsfw,
|
nsfw: videoInfo.nsfw,
|
||||||
description: videoInfo.description,
|
description: videoInfo.description,
|
||||||
privacy: videoInfo.privacy,
|
privacy: videoInfo.privacy,
|
||||||
|
@ -248,6 +248,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw)
|
if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw)
|
||||||
if (videoInfoToUpdate.privacy !== undefined) videoInstance.set('privacy', parseInt(videoInfoToUpdate.privacy.toString(), 10))
|
if (videoInfoToUpdate.privacy !== undefined) videoInstance.set('privacy', parseInt(videoInfoToUpdate.privacy.toString(), 10))
|
||||||
if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description)
|
if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description)
|
||||||
|
if (videoInfoToUpdate.commentsEnabled !== undefined) videoInstance.set('commentsEnabled', videoInfoToUpdate.commentsEnabled)
|
||||||
|
|
||||||
const videoInstanceUpdated = await videoInstance.save(sequelizeOptions)
|
const videoInstanceUpdated = await videoInstance.save(sequelizeOptions)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { isAnnounceActivityValid } from './announce'
|
||||||
import { isActivityPubUrlValid } from './misc'
|
import { isActivityPubUrlValid } from './misc'
|
||||||
import { isDislikeActivityValid, isLikeActivityValid } from './rate'
|
import { isDislikeActivityValid, isLikeActivityValid } from './rate'
|
||||||
import { isUndoActivityValid } from './undo'
|
import { isUndoActivityValid } from './undo'
|
||||||
import { isVideoChannelDeleteActivityValid, isVideoChannelUpdateActivityValid } from './video-channels'
|
|
||||||
import { isVideoCommentCreateActivityValid } from './video-comments'
|
import { isVideoCommentCreateActivityValid } from './video-comments'
|
||||||
import {
|
import {
|
||||||
isVideoFlagValid,
|
isVideoFlagValid,
|
||||||
|
@ -65,13 +64,11 @@ function checkCreateActivity (activity: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkUpdateActivity (activity: any) {
|
function checkUpdateActivity (activity: any) {
|
||||||
return isVideoTorrentUpdateActivityValid(activity) ||
|
return isVideoTorrentUpdateActivityValid(activity)
|
||||||
isVideoChannelUpdateActivityValid(activity)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkDeleteActivity (activity: any) {
|
function checkDeleteActivity (activity: any) {
|
||||||
return isVideoTorrentDeleteActivityValid(activity) ||
|
return isVideoTorrentDeleteActivityValid(activity) ||
|
||||||
isVideoChannelDeleteActivityValid(activity) ||
|
|
||||||
isActorDeleteActivityValid(activity)
|
isActorDeleteActivityValid(activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import { isDateValid, isUUIDValid } from '../misc'
|
|
||||||
import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../video-channels'
|
|
||||||
import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
|
|
||||||
|
|
||||||
function isVideoChannelUpdateActivityValid (activity: any) {
|
|
||||||
return isBaseActivityValid(activity, 'Update') &&
|
|
||||||
isVideoChannelObjectValid(activity.object)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isVideoChannelDeleteActivityValid (activity: any) {
|
|
||||||
return isBaseActivityValid(activity, 'Delete')
|
|
||||||
}
|
|
||||||
|
|
||||||
function isVideoChannelObjectValid (videoChannel: any) {
|
|
||||||
return videoChannel.type === 'VideoChannel' &&
|
|
||||||
isActivityPubUrlValid(videoChannel.id) &&
|
|
||||||
isVideoChannelNameValid(videoChannel.name) &&
|
|
||||||
isVideoChannelDescriptionValid(videoChannel.content) &&
|
|
||||||
isDateValid(videoChannel.published) &&
|
|
||||||
isDateValid(videoChannel.updated) &&
|
|
||||||
isUUIDValid(videoChannel.uuid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
export {
|
|
||||||
isVideoChannelUpdateActivityValid,
|
|
||||||
isVideoChannelDeleteActivityValid,
|
|
||||||
isVideoChannelObjectValid
|
|
||||||
}
|
|
|
@ -1,11 +1,10 @@
|
||||||
import * as validator from 'validator'
|
import * as validator from 'validator'
|
||||||
import { ACTIVITY_PUB } from '../../../initializers'
|
import { ACTIVITY_PUB } from '../../../initializers'
|
||||||
import { exists, isDateValid, isUUIDValid } from '../misc'
|
import { exists, isBooleanValid, isDateValid, isUUIDValid } from '../misc'
|
||||||
import {
|
import {
|
||||||
isVideoAbuseReasonValid,
|
isVideoAbuseReasonValid,
|
||||||
isVideoDurationValid,
|
isVideoDurationValid,
|
||||||
isVideoNameValid,
|
isVideoNameValid,
|
||||||
isVideoNSFWValid,
|
|
||||||
isVideoTagValid,
|
isVideoTagValid,
|
||||||
isVideoTruncatedDescriptionValid,
|
isVideoTruncatedDescriptionValid,
|
||||||
isVideoViewsValid
|
isVideoViewsValid
|
||||||
|
@ -53,7 +52,8 @@ function isVideoTorrentObjectValid (video: any) {
|
||||||
(!video.licence || isRemoteIdentifierValid(video.licence)) &&
|
(!video.licence || isRemoteIdentifierValid(video.licence)) &&
|
||||||
(!video.language || isRemoteIdentifierValid(video.language)) &&
|
(!video.language || isRemoteIdentifierValid(video.language)) &&
|
||||||
isVideoViewsValid(video.views) &&
|
isVideoViewsValid(video.views) &&
|
||||||
isVideoNSFWValid(video.nsfw) &&
|
isBooleanValid(video.nsfw) &&
|
||||||
|
isBooleanValid(video.commentsEnabled) &&
|
||||||
isDateValid(video.published) &&
|
isDateValid(video.published) &&
|
||||||
isDateValid(video.updated) &&
|
isDateValid(video.updated) &&
|
||||||
(!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) &&
|
(!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) &&
|
||||||
|
|
|
@ -24,6 +24,10 @@ function isIdOrUUIDValid (value: string) {
|
||||||
return isIdValid(value) || isUUIDValid(value)
|
return isIdValid(value) || isUUIDValid(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isBooleanValid (value: string) {
|
||||||
|
return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -32,5 +36,6 @@ export {
|
||||||
isIdValid,
|
isIdValid,
|
||||||
isUUIDValid,
|
isUUIDValid,
|
||||||
isIdOrUUIDValid,
|
isIdOrUUIDValid,
|
||||||
isDateValid
|
isDateValid,
|
||||||
|
isBooleanValid
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,6 @@ function isVideoLanguageValid (value: number) {
|
||||||
return value === null || VIDEO_LANGUAGES[value] !== undefined
|
return value === null || VIDEO_LANGUAGES[value] !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVideoNSFWValid (value: any) {
|
|
||||||
return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
function isVideoDurationValid (value: string) {
|
function isVideoDurationValid (value: string) {
|
||||||
return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
|
return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
|
||||||
}
|
}
|
||||||
|
@ -131,7 +127,6 @@ export {
|
||||||
isVideoCategoryValid,
|
isVideoCategoryValid,
|
||||||
isVideoLicenceValid,
|
isVideoLicenceValid,
|
||||||
isVideoLanguageValid,
|
isVideoLanguageValid,
|
||||||
isVideoNSFWValid,
|
|
||||||
isVideoTruncatedDescriptionValid,
|
isVideoTruncatedDescriptionValid,
|
||||||
isVideoDescriptionValid,
|
isVideoDescriptionValid,
|
||||||
isVideoFileInfoHashValid,
|
isVideoFileInfoHashValid,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as multer from 'multer'
|
||||||
import { Model } from 'sequelize-typescript'
|
import { Model } from 'sequelize-typescript'
|
||||||
import { ResultList } from '../../shared'
|
import { ResultList } from '../../shared'
|
||||||
import { VideoResolution } from '../../shared/models/videos'
|
import { VideoResolution } from '../../shared/models/videos'
|
||||||
import { CONFIG, REMOTE_SCHEME, VIDEO_MIMETYPE_EXT } from '../initializers'
|
import { CONFIG, REMOTE_SCHEME } from '../initializers'
|
||||||
import { UserModel } from '../models/account/user'
|
import { UserModel } from '../models/account/user'
|
||||||
import { ActorModel } from '../models/activitypub/actor'
|
import { ActorModel } from '../models/activitypub/actor'
|
||||||
import { ApplicationModel } from '../models/application/application'
|
import { ApplicationModel } from '../models/application/application'
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { isTestInstance, root, sanitizeHost, sanitizeUrl } from '../helpers/core
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const LAST_MIGRATION_VERSION = 150
|
const LAST_MIGRATION_VERSION = 155
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import * as Sequelize from 'sequelize'
|
||||||
|
|
||||||
|
async function up (utils: {
|
||||||
|
transaction: Sequelize.Transaction,
|
||||||
|
queryInterface: Sequelize.QueryInterface,
|
||||||
|
sequelize: Sequelize.Sequelize
|
||||||
|
}): Promise<void> {
|
||||||
|
const data = {
|
||||||
|
type: Sequelize.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: true
|
||||||
|
}
|
||||||
|
await utils.queryInterface.addColumn('video', 'commentsEnabled', data)
|
||||||
|
|
||||||
|
data.defaultValue = null
|
||||||
|
return utils.queryInterface.changeColumn('video', 'commentsEnabled', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
function down (options) {
|
||||||
|
throw new Error('Not implemented.')
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
up,
|
||||||
|
down
|
||||||
|
}
|
|
@ -53,6 +53,7 @@ async function videoActivityObjectToDBAttributes (
|
||||||
language,
|
language,
|
||||||
description,
|
description,
|
||||||
nsfw: videoObject.nsfw,
|
nsfw: videoObject.nsfw,
|
||||||
|
commentsEnabled: videoObject.commentsEnabled,
|
||||||
channelId: videoChannel.id,
|
channelId: videoChannel.id,
|
||||||
duration: parseInt(duration, 10),
|
duration: parseInt(duration, 10),
|
||||||
createdAt: new Date(videoObject.published),
|
createdAt: new Date(videoObject.published),
|
||||||
|
|
|
@ -3,11 +3,10 @@ import 'express-validator'
|
||||||
import { body, param } from 'express-validator/check'
|
import { body, param } from 'express-validator/check'
|
||||||
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
|
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
|
||||||
import {
|
import {
|
||||||
isAvatarFile,
|
isAvatarFile, isUserAutoPlayVideoValid, isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid,
|
||||||
isUserAutoPlayVideoValid, isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid,
|
|
||||||
isUserVideoQuotaValid
|
isUserVideoQuotaValid
|
||||||
} from '../../helpers/custom-validators/users'
|
} from '../../helpers/custom-validators/users'
|
||||||
import { isVideoExist, isVideoFile } from '../../helpers/custom-validators/videos'
|
import { isVideoExist } from '../../helpers/custom-validators/videos'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
import { isSignupAllowed } from '../../helpers/utils'
|
import { isSignupAllowed } from '../../helpers/utils'
|
||||||
import { CONSTRAINTS_FIELDS } from '../../initializers'
|
import { CONSTRAINTS_FIELDS } from '../../initializers'
|
||||||
|
|
|
@ -45,6 +45,7 @@ const addVideoCommentThreadValidator = [
|
||||||
|
|
||||||
if (areValidationErrors(req, res)) return
|
if (areValidationErrors(req, res)) return
|
||||||
if (!await isVideoExist(req.params.videoId, res)) return
|
if (!await isVideoExist(req.params.videoId, res)) return
|
||||||
|
if (!isVideoCommentsEnabled(res.locals.video, res)) return
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
@ -60,6 +61,7 @@ const addVideoCommentReplyValidator = [
|
||||||
|
|
||||||
if (areValidationErrors(req, res)) return
|
if (areValidationErrors(req, res)) return
|
||||||
if (!await isVideoExist(req.params.videoId, res)) return
|
if (!await isVideoExist(req.params.videoId, res)) return
|
||||||
|
if (!isVideoCommentsEnabled(res.locals.video, res)) return
|
||||||
if (!await isVideoCommentExist(req.params.commentId, res.locals.video, res)) return
|
if (!await isVideoCommentExist(req.params.commentId, res.locals.video, res)) return
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
|
@ -146,3 +148,15 @@ async function isVideoCommentExist (id: number, video: VideoModel, res: express.
|
||||||
res.locals.videoComment = videoComment
|
res.locals.videoComment = videoComment
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isVideoCommentsEnabled (video: VideoModel, res: express.Response) {
|
||||||
|
if (video.commentsEnabled !== true) {
|
||||||
|
res.status(409)
|
||||||
|
.json({ error: 'Video comments are disabled for this video.' })
|
||||||
|
.end()
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@ import * as express from 'express'
|
||||||
import 'express-validator'
|
import 'express-validator'
|
||||||
import { body, param, query } from 'express-validator/check'
|
import { body, param, query } from 'express-validator/check'
|
||||||
import { UserRight, VideoPrivacy } from '../../../shared'
|
import { UserRight, VideoPrivacy } from '../../../shared'
|
||||||
import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc'
|
import { isBooleanValid, isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc'
|
||||||
import {
|
import {
|
||||||
isVideoAbuseReasonValid, isVideoCategoryValid, isVideoDescriptionValid, isVideoExist, isVideoFile, isVideoLanguageValid,
|
isVideoAbuseReasonValid, isVideoCategoryValid, isVideoDescriptionValid, isVideoExist, isVideoFile, isVideoLanguageValid,
|
||||||
isVideoLicenceValid, isVideoNameValid, isVideoNSFWValid, isVideoPrivacyValid, isVideoRatingTypeValid, isVideoTagsValid
|
isVideoLicenceValid, isVideoNameValid, isVideoPrivacyValid, isVideoRatingTypeValid, isVideoTagsValid
|
||||||
} from '../../helpers/custom-validators/videos'
|
} from '../../helpers/custom-validators/videos'
|
||||||
import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils'
|
import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
|
@ -26,11 +26,12 @@ const videosAddValidator = [
|
||||||
body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'),
|
body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'),
|
||||||
body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
||||||
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
||||||
body('nsfw').custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'),
|
body('nsfw').custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'),
|
||||||
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
||||||
body('channelId').custom(isIdValid).withMessage('Should have correct video channel id'),
|
body('channelId').custom(isIdValid).withMessage('Should have correct video channel id'),
|
||||||
body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
||||||
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
||||||
|
body('commentsEnabled').custom(isBooleanValid).withMessage('Should have comments enabled boolean'),
|
||||||
|
|
||||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
|
logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
|
||||||
|
@ -85,10 +86,11 @@ const videosUpdateValidator = [
|
||||||
body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'),
|
body('category').optional().custom(isVideoCategoryValid).withMessage('Should have a valid category'),
|
||||||
body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
|
||||||
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
|
||||||
body('nsfw').optional().custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'),
|
body('nsfw').optional().custom(isBooleanValid).withMessage('Should have a valid NSFW attribute'),
|
||||||
body('privacy').optional().custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
body('privacy').optional().custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
|
||||||
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
|
||||||
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
|
||||||
|
body('commentsEnabled').optional().custom(isBooleanValid).withMessage('Should have comments enabled boolean'),
|
||||||
|
|
||||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
logger.debug('Checking videosUpdate parameters', { parameters: req.body })
|
logger.debug('Checking videosUpdate parameters', { parameters: req.body })
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { values } from 'lodash'
|
import { values } from 'lodash'
|
||||||
import { extname, join } from 'path'
|
import { extname } from 'path'
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
import {
|
import {
|
||||||
AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, DefaultScope, ForeignKey, HasMany, HasOne, Is, IsUUID, Model, Scopes,
|
AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, DefaultScope, ForeignKey, HasMany, HasOne, Is, IsUUID, Model, Scopes,
|
||||||
|
@ -13,7 +13,7 @@ import {
|
||||||
isActorPublicKeyValid
|
isActorPublicKeyValid
|
||||||
} from '../../helpers/custom-validators/activitypub/actor'
|
} from '../../helpers/custom-validators/activitypub/actor'
|
||||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||||
import { ACTIVITY_PUB_ACTOR_TYPES, AVATARS_DIR, CONFIG, CONSTRAINTS_FIELDS } from '../../initializers'
|
import { ACTIVITY_PUB_ACTOR_TYPES, CONFIG, CONSTRAINTS_FIELDS } from '../../initializers'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { AvatarModel } from '../avatar/avatar'
|
import { AvatarModel } from '../avatar/avatar'
|
||||||
import { ServerModel } from '../server/server'
|
import { ServerModel } from '../server/server'
|
||||||
|
|
|
@ -2,9 +2,7 @@ import { join } from 'path'
|
||||||
import { AfterDestroy, AllowNull, Column, CreatedAt, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AfterDestroy, AllowNull, Column, CreatedAt, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { Avatar } from '../../../shared/models/avatars/avatar.model'
|
import { Avatar } from '../../../shared/models/avatars/avatar.model'
|
||||||
import { unlinkPromise } from '../../helpers/core-utils'
|
import { unlinkPromise } from '../../helpers/core-utils'
|
||||||
import { logger } from '../../helpers/logger'
|
|
||||||
import { CONFIG, STATIC_PATHS } from '../../initializers'
|
import { CONFIG, STATIC_PATHS } from '../../initializers'
|
||||||
import { sendDeleteVideo } from '../../lib/activitypub/send'
|
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'avatar'
|
tableName: 'avatar'
|
||||||
|
|
|
@ -15,9 +15,10 @@ import { Video, VideoDetails } from '../../../shared/models/videos'
|
||||||
import { activityPubCollection } from '../../helpers/activitypub'
|
import { activityPubCollection } from '../../helpers/activitypub'
|
||||||
import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils'
|
import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils'
|
||||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||||
|
import { isBooleanValid } from '../../helpers/custom-validators/misc'
|
||||||
import {
|
import {
|
||||||
isVideoCategoryValid, isVideoDescriptionValid, isVideoDurationValid, isVideoLanguageValid, isVideoLicenceValid, isVideoNameValid,
|
isVideoCategoryValid, isVideoDescriptionValid, isVideoDurationValid, isVideoLanguageValid, isVideoLicenceValid, isVideoNameValid,
|
||||||
isVideoNSFWValid, isVideoPrivacyValid
|
isVideoPrivacyValid
|
||||||
} from '../../helpers/custom-validators/videos'
|
} from '../../helpers/custom-validators/videos'
|
||||||
import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils'
|
import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
|
@ -185,7 +186,7 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
privacy: number
|
privacy: number
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Is('VideoNSFW', value => throwIfNotValid(value, isVideoNSFWValid, 'NSFW boolean'))
|
@Is('VideoNSFW', value => throwIfNotValid(value, isBooleanValid, 'NSFW boolean'))
|
||||||
@Column
|
@Column
|
||||||
nsfw: boolean
|
nsfw: boolean
|
||||||
|
|
||||||
|
@ -230,6 +231,10 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
@Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.URL.max))
|
@Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.URL.max))
|
||||||
url: string
|
url: string
|
||||||
|
|
||||||
|
@AllowNull(false)
|
||||||
|
@Column
|
||||||
|
commentsEnabled: boolean
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
@ -773,6 +778,7 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
channel: this.VideoChannel.toFormattedJSON(),
|
channel: this.VideoChannel.toFormattedJSON(),
|
||||||
account: this.VideoChannel.Account.toFormattedJSON(),
|
account: this.VideoChannel.Account.toFormattedJSON(),
|
||||||
tags: map<TagModel, string>(this.Tags, 'name'),
|
tags: map<TagModel, string>(this.Tags, 'name'),
|
||||||
|
commentsEnabled: this.commentsEnabled,
|
||||||
files: []
|
files: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -920,6 +926,7 @@ export class VideoModel extends Model<VideoModel> {
|
||||||
language,
|
language,
|
||||||
views: this.views,
|
views: this.views,
|
||||||
nsfw: this.nsfw,
|
nsfw: this.nsfw,
|
||||||
|
commentsEnabled: this.commentsEnabled,
|
||||||
published: this.createdAt.toISOString(),
|
published: this.createdAt.toISOString(),
|
||||||
updated: this.updatedAt.toISOString(),
|
updated: this.updatedAt.toISOString(),
|
||||||
mediaType: 'text/markdown',
|
mediaType: 'text/markdown',
|
||||||
|
|
|
@ -20,11 +20,11 @@ describe('Test activitypub', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return the account object', async function () {
|
it('Should return the account object', async function () {
|
||||||
const res = await makeActivityPubGetRequest(server.url, '/account/root')
|
const res = await makeActivityPubGetRequest(server.url, '/accounts/root')
|
||||||
const object = res.body
|
const object = res.body
|
||||||
|
|
||||||
expect(object.type).to.equal('Person')
|
expect(object.type).to.equal('Person')
|
||||||
expect(object.id).to.equal('http://localhost:9001/account/root')
|
expect(object.id).to.equal('http://localhost:9001/accounts/root')
|
||||||
expect(object.name).to.equal('root')
|
expect(object.name).to.equal('root')
|
||||||
expect(object.preferredUsername).to.equal('root')
|
expect(object.preferredUsername).to.equal('root')
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
|
|
||||||
import { omit } from 'lodash'
|
import { omit } from 'lodash'
|
||||||
import 'mocha'
|
import 'mocha'
|
||||||
import { join } from "path"
|
import { join } from 'path'
|
||||||
import { UserRole } from '../../../../shared'
|
import { UserRole } from '../../../../shared'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest,
|
createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest,
|
||||||
makePostBodyRequest, makePostUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers,
|
makePostBodyRequest, makePostUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers,
|
||||||
updateUser,
|
updateUser, uploadVideo, userLogin
|
||||||
uploadVideo, userLogin
|
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
|
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ describe('Test users API validators', function () {
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
before(async function () {
|
before(async function () {
|
||||||
this.timeout(120000)
|
this.timeout(20000)
|
||||||
|
|
||||||
await flushTests()
|
await flushTests()
|
||||||
|
|
||||||
|
@ -282,7 +281,14 @@ describe('Test users API validators', function () {
|
||||||
const attaches = {
|
const attaches = {
|
||||||
'avatarfile': join(__dirname, '..', 'fixtures', 'avatar.png')
|
'avatarfile': join(__dirname, '..', 'fixtures', 'avatar.png')
|
||||||
}
|
}
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/me/avatar/pick', token: server.accessToken, fields, attaches })
|
await makePostUploadRequest({
|
||||||
|
url: server.url,
|
||||||
|
path: path + '/me/avatar/pick',
|
||||||
|
token: server.accessToken,
|
||||||
|
fields,
|
||||||
|
attaches,
|
||||||
|
statusCodeExpected: 200
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* tslint:disable:no-unused-expression */
|
/* tslint:disable:no-unused-expression */
|
||||||
|
|
||||||
|
import * as chai from 'chai'
|
||||||
import 'mocha'
|
import 'mocha'
|
||||||
import {
|
import {
|
||||||
flushTests, killallServers, makeGetRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
|
flushTests, killallServers, makeGetRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
|
||||||
|
@ -8,6 +9,8 @@ import {
|
||||||
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
|
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
|
||||||
import { addVideoCommentThread } from '../../utils/videos/video-comments'
|
import { addVideoCommentThread } from '../../utils/videos/video-comments'
|
||||||
|
|
||||||
|
const expect = chai.expect
|
||||||
|
|
||||||
describe('Test video comments API validator', function () {
|
describe('Test video comments API validator', function () {
|
||||||
let pathThread: string
|
let pathThread: string
|
||||||
let pathComment: string
|
let pathComment: string
|
||||||
|
@ -42,17 +45,14 @@ describe('Test video comments API validator', function () {
|
||||||
describe('When listing video comment threads', function () {
|
describe('When listing video comment threads', function () {
|
||||||
it('Should fail with a bad start pagination', async function () {
|
it('Should fail with a bad start pagination', async function () {
|
||||||
await checkBadStartPagination(server.url, pathThread, server.accessToken)
|
await checkBadStartPagination(server.url, pathThread, server.accessToken)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail with a bad count pagination', async function () {
|
it('Should fail with a bad count pagination', async function () {
|
||||||
await checkBadCountPagination(server.url, pathThread, server.accessToken)
|
await checkBadCountPagination(server.url, pathThread, server.accessToken)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail with an incorrect sort', async function () {
|
it('Should fail with an incorrect sort', async function () {
|
||||||
await checkBadSortPagination(server.url, pathThread, server.accessToken)
|
await checkBadSortPagination(server.url, pathThread, server.accessToken)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fail with an incorrect video', async function () {
|
it('Should fail with an incorrect video', async function () {
|
||||||
|
@ -185,6 +185,35 @@ describe('Test video comments API validator', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('When a video has comments disabled', function () {
|
||||||
|
before(async function () {
|
||||||
|
const res = await uploadVideo(server.url, server.accessToken, { commentsEnabled: false })
|
||||||
|
videoUUID = res.body.video.uuid
|
||||||
|
pathThread = '/api/v1/videos/' + videoUUID + '/comment-threads'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should return an empty thread list', async function () {
|
||||||
|
const res = await makeGetRequest({
|
||||||
|
url: server.url,
|
||||||
|
path: pathThread,
|
||||||
|
statusCodeExpected: 200
|
||||||
|
})
|
||||||
|
expect(res.body.total).to.equal(0)
|
||||||
|
expect(res.body.data).to.have.lengthOf(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should return an thread comments list')
|
||||||
|
|
||||||
|
it('Should return conflict on thread add', async function () {
|
||||||
|
const fields = {
|
||||||
|
text: 'super comment'
|
||||||
|
}
|
||||||
|
await makePostBodyRequest({ url: server.url, path: pathThread, token: server.accessToken, fields, statusCodeExpected: 409 })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should return conflict on comment thread add')
|
||||||
|
})
|
||||||
|
|
||||||
after(async function () {
|
after(async function () {
|
||||||
killallServers([ server ])
|
killallServers([ server ])
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ describe('Test videos API validator', function () {
|
||||||
licence: 1,
|
licence: 1,
|
||||||
language: 6,
|
language: 6,
|
||||||
nsfw: false,
|
nsfw: false,
|
||||||
|
commentsEnabled: true,
|
||||||
description: 'my super description',
|
description: 'my super description',
|
||||||
tags: [ 'tag1', 'tag2' ],
|
tags: [ 'tag1', 'tag2' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
|
@ -162,6 +163,20 @@ describe('Test videos API validator', function () {
|
||||||
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should fail without commentsEnabled attribute', async function () {
|
||||||
|
const fields = omit(baseCorrectParams, 'commentsEnabled')
|
||||||
|
const attaches = baseCorrectAttaches
|
||||||
|
|
||||||
|
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a bad commentsEnabled attribute', async function () {
|
||||||
|
const fields = immutableAssign(baseCorrectParams, { commentsEnabled: 2 })
|
||||||
|
const attaches = baseCorrectAttaches
|
||||||
|
|
||||||
|
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
|
||||||
|
})
|
||||||
|
|
||||||
it('Should fail with a long description', async function () {
|
it('Should fail with a long description', async function () {
|
||||||
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(1500) })
|
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(1500) })
|
||||||
const attaches = baseCorrectAttaches
|
const attaches = baseCorrectAttaches
|
||||||
|
@ -291,6 +306,7 @@ describe('Test videos API validator', function () {
|
||||||
licence: 2,
|
licence: 2,
|
||||||
language: 6,
|
language: 6,
|
||||||
nsfw: false,
|
nsfw: false,
|
||||||
|
commentsEnabled: false,
|
||||||
description: 'my super description',
|
description: 'my super description',
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
tags: [ 'tag1', 'tag2' ]
|
tags: [ 'tag1', 'tag2' ]
|
||||||
|
@ -354,6 +370,12 @@ describe('Test videos API validator', function () {
|
||||||
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should fail with a bad commentsEnabled attribute', async function () {
|
||||||
|
const fields = immutableAssign(baseCorrectParams, { commentsEnabled: 2 })
|
||||||
|
|
||||||
|
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
|
||||||
|
})
|
||||||
|
|
||||||
it('Should fail with a long description', async function () {
|
it('Should fail with a long description', async function () {
|
||||||
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(1500) })
|
const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(1500) })
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,7 @@ describe('Test follows', function () {
|
||||||
host: 'localhost:9003',
|
host: 'localhost:9003',
|
||||||
account: 'root',
|
account: 'root',
|
||||||
isLocal,
|
isLocal,
|
||||||
|
commentsEnabled: true,
|
||||||
duration: 5,
|
duration: 5,
|
||||||
tags: [ 'tag1', 'tag2', 'tag3' ],
|
tags: [ 'tag1', 'tag2', 'tag3' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
|
|
|
@ -93,6 +93,7 @@ describe('Test multiple servers', function () {
|
||||||
duration: 10,
|
duration: 10,
|
||||||
tags: [ 'tag1p1', 'tag2p1' ],
|
tags: [ 'tag1p1', 'tag2p1' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
|
commentsEnabled: true,
|
||||||
channel: {
|
channel: {
|
||||||
name: 'my channel',
|
name: 'my channel',
|
||||||
description: 'super channel',
|
description: 'super channel',
|
||||||
|
@ -155,6 +156,7 @@ describe('Test multiple servers', function () {
|
||||||
host: 'localhost:9002',
|
host: 'localhost:9002',
|
||||||
account: 'user1',
|
account: 'user1',
|
||||||
isLocal,
|
isLocal,
|
||||||
|
commentsEnabled: true,
|
||||||
duration: 5,
|
duration: 5,
|
||||||
tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
|
tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
|
@ -254,6 +256,7 @@ describe('Test multiple servers', function () {
|
||||||
account: 'root',
|
account: 'root',
|
||||||
isLocal,
|
isLocal,
|
||||||
duration: 5,
|
duration: 5,
|
||||||
|
commentsEnabled: true,
|
||||||
tags: [ 'tag1p3' ],
|
tags: [ 'tag1p3' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
channel: {
|
channel: {
|
||||||
|
@ -280,6 +283,7 @@ describe('Test multiple servers', function () {
|
||||||
description: 'my super description for server 3-2',
|
description: 'my super description for server 3-2',
|
||||||
host: 'localhost:9003',
|
host: 'localhost:9003',
|
||||||
account: 'root',
|
account: 'root',
|
||||||
|
commentsEnabled: true,
|
||||||
isLocal,
|
isLocal,
|
||||||
duration: 5,
|
duration: 5,
|
||||||
tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
|
tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
|
||||||
|
@ -545,6 +549,7 @@ describe('Test multiple servers', function () {
|
||||||
account: 'root',
|
account: 'root',
|
||||||
isLocal,
|
isLocal,
|
||||||
duration: 5,
|
duration: 5,
|
||||||
|
commentsEnabled: true,
|
||||||
tags: [ 'tag_up_1', 'tag_up_2' ],
|
tags: [ 'tag_up_1', 'tag_up_2' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
channel: {
|
channel: {
|
||||||
|
@ -732,6 +737,26 @@ describe('Test multiple servers', function () {
|
||||||
expect(secondChild.children).to.have.lengthOf(0)
|
expect(secondChild.children).to.have.lengthOf(0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should disable comments', async function () {
|
||||||
|
this.timeout(20000)
|
||||||
|
|
||||||
|
const attributes = {
|
||||||
|
commentsEnabled: false
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, attributes)
|
||||||
|
|
||||||
|
await wait(5000)
|
||||||
|
|
||||||
|
for (const server of servers) {
|
||||||
|
const res = await getVideo(server.url, videoUUID)
|
||||||
|
expect(res.body.commentsEnabled).to.be.false
|
||||||
|
|
||||||
|
const text = 'my super forbidden comment'
|
||||||
|
await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, 409)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('With minimum parameters', function () {
|
describe('With minimum parameters', function () {
|
||||||
|
@ -748,6 +773,7 @@ describe('Test multiple servers', function () {
|
||||||
.field('privacy', '1')
|
.field('privacy', '1')
|
||||||
.field('nsfw', 'false')
|
.field('nsfw', 'false')
|
||||||
.field('channelId', '1')
|
.field('channelId', '1')
|
||||||
|
.field('commentsEnabled', 'true')
|
||||||
|
|
||||||
const filePath = join(__dirname, '..', '..', 'api', 'fixtures', 'video_short.webm')
|
const filePath = join(__dirname, '..', '..', 'api', 'fixtures', 'video_short.webm')
|
||||||
|
|
||||||
|
@ -772,6 +798,7 @@ describe('Test multiple servers', function () {
|
||||||
account: 'root',
|
account: 'root',
|
||||||
isLocal,
|
isLocal,
|
||||||
duration: 5,
|
duration: 5,
|
||||||
|
commentsEnabled: true,
|
||||||
tags: [ ],
|
tags: [ ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
channel: {
|
channel: {
|
||||||
|
|
|
@ -32,6 +32,7 @@ describe('Test a single server', function () {
|
||||||
duration: 5,
|
duration: 5,
|
||||||
tags: [ 'tag1', 'tag2', 'tag3' ],
|
tags: [ 'tag1', 'tag2', 'tag3' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
|
commentsEnabled: true,
|
||||||
channel: {
|
channel: {
|
||||||
name: 'Default root channel',
|
name: 'Default root channel',
|
||||||
description: '',
|
description: '',
|
||||||
|
@ -51,7 +52,7 @@ describe('Test a single server', function () {
|
||||||
category: 4,
|
category: 4,
|
||||||
licence: 2,
|
licence: 2,
|
||||||
language: 5,
|
language: 5,
|
||||||
nsfw: true,
|
nsfw: false,
|
||||||
description: 'my super description updated',
|
description: 'my super description updated',
|
||||||
host: 'localhost:9001',
|
host: 'localhost:9001',
|
||||||
account: 'root',
|
account: 'root',
|
||||||
|
@ -59,6 +60,7 @@ describe('Test a single server', function () {
|
||||||
tags: [ 'tagup1', 'tagup2' ],
|
tags: [ 'tagup1', 'tagup2' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
duration: 5,
|
duration: 5,
|
||||||
|
commentsEnabled: false,
|
||||||
channel: {
|
channel: {
|
||||||
name: 'Default root channel',
|
name: 'Default root channel',
|
||||||
description: '',
|
description: '',
|
||||||
|
@ -475,6 +477,7 @@ describe('Test a single server', function () {
|
||||||
language: 5,
|
language: 5,
|
||||||
nsfw: false,
|
nsfw: false,
|
||||||
description: 'my super description updated',
|
description: 'my super description updated',
|
||||||
|
commentsEnabled: false,
|
||||||
tags: [ 'tagup1', 'tagup2' ]
|
tags: [ 'tagup1', 'tagup2' ]
|
||||||
}
|
}
|
||||||
await updateVideo(server.url, server.accessToken, videoId, attributes)
|
await updateVideo(server.url, server.accessToken, videoId, attributes)
|
||||||
|
|
|
@ -16,6 +16,7 @@ type VideoAttributes = {
|
||||||
licence?: number
|
licence?: number
|
||||||
language?: number
|
language?: number
|
||||||
nsfw?: boolean
|
nsfw?: boolean
|
||||||
|
commentsEnabled?: boolean
|
||||||
description?: string
|
description?: string
|
||||||
tags?: string[]
|
tags?: string[]
|
||||||
channelId?: number
|
channelId?: number
|
||||||
|
@ -238,6 +239,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
|
||||||
description: 'my super description',
|
description: 'my super description',
|
||||||
tags: [ 'tag' ],
|
tags: [ 'tag' ],
|
||||||
privacy: VideoPrivacy.PUBLIC,
|
privacy: VideoPrivacy.PUBLIC,
|
||||||
|
commentsEnabled: true,
|
||||||
fixture: 'video_short.webm'
|
fixture: 'video_short.webm'
|
||||||
}
|
}
|
||||||
attributes = Object.assign(attributes, videoAttributesArg)
|
attributes = Object.assign(attributes, videoAttributesArg)
|
||||||
|
@ -250,6 +252,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
|
||||||
.field('category', attributes.category.toString())
|
.field('category', attributes.category.toString())
|
||||||
.field('licence', attributes.licence.toString())
|
.field('licence', attributes.licence.toString())
|
||||||
.field('nsfw', JSON.stringify(attributes.nsfw))
|
.field('nsfw', JSON.stringify(attributes.nsfw))
|
||||||
|
.field('commentsEnabled', JSON.stringify(attributes.commentsEnabled))
|
||||||
.field('description', attributes.description)
|
.field('description', attributes.description)
|
||||||
.field('privacy', attributes.privacy.toString())
|
.field('privacy', attributes.privacy.toString())
|
||||||
.field('channelId', attributes.channelId)
|
.field('channelId', attributes.channelId)
|
||||||
|
@ -273,7 +276,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
|
||||||
.expect(specialStatus)
|
.expect(specialStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVideo (url: string, accessToken: string, id: number, attributes: VideoAttributes, specialStatus = 204) {
|
function updateVideo (url: string, accessToken: string, id: number | string, attributes: VideoAttributes, specialStatus = 204) {
|
||||||
const path = '/api/v1/videos/' + id
|
const path = '/api/v1/videos/' + id
|
||||||
const body = {}
|
const body = {}
|
||||||
|
|
||||||
|
@ -281,7 +284,8 @@ function updateVideo (url: string, accessToken: string, id: number, attributes:
|
||||||
if (attributes.category) body['category'] = attributes.category
|
if (attributes.category) body['category'] = attributes.category
|
||||||
if (attributes.licence) body['licence'] = attributes.licence
|
if (attributes.licence) body['licence'] = attributes.licence
|
||||||
if (attributes.language) body['language'] = attributes.language
|
if (attributes.language) body['language'] = attributes.language
|
||||||
if (attributes.nsfw) body['nsfw'] = attributes.nsfw
|
if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
|
||||||
|
if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
|
||||||
if (attributes.description) body['description'] = attributes.description
|
if (attributes.description) body['description'] = attributes.description
|
||||||
if (attributes.tags) body['tags'] = attributes.tags
|
if (attributes.tags) body['tags'] = attributes.tags
|
||||||
if (attributes.privacy) body['privacy'] = attributes.privacy
|
if (attributes.privacy) body['privacy'] = attributes.privacy
|
||||||
|
@ -326,6 +330,7 @@ async function completeVideoCheck (
|
||||||
licence: number
|
licence: number
|
||||||
language: number
|
language: number
|
||||||
nsfw: boolean
|
nsfw: boolean
|
||||||
|
commentsEnabled: boolean
|
||||||
description: string
|
description: string
|
||||||
host: string
|
host: string
|
||||||
account: string
|
account: string
|
||||||
|
@ -376,6 +381,7 @@ async function completeVideoCheck (
|
||||||
expect(videoDetails.privacy).to.deep.equal(attributes.privacy)
|
expect(videoDetails.privacy).to.deep.equal(attributes.privacy)
|
||||||
expect(videoDetails.privacyLabel).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
|
expect(videoDetails.privacyLabel).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
|
||||||
expect(videoDetails.account.name).to.equal(attributes.account)
|
expect(videoDetails.account.name).to.equal(attributes.account)
|
||||||
|
expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled)
|
||||||
|
|
||||||
expect(videoDetails.channel.name).to.equal(attributes.channel.name)
|
expect(videoDetails.channel.name).to.equal(attributes.channel.name)
|
||||||
expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal)
|
expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal)
|
||||||
|
|
|
@ -18,6 +18,7 @@ export interface VideoTorrentObject {
|
||||||
language: ActivityIdentifierObject
|
language: ActivityIdentifierObject
|
||||||
views: number
|
views: number
|
||||||
nsfw: boolean
|
nsfw: boolean
|
||||||
|
commentsEnabled: boolean
|
||||||
published: string
|
published: string
|
||||||
updated: string
|
updated: string
|
||||||
mediaType: 'text/markdown'
|
mediaType: 'text/markdown'
|
||||||
|
|
|
@ -9,5 +9,6 @@ export interface VideoCreate {
|
||||||
nsfw: boolean
|
nsfw: boolean
|
||||||
name: string
|
name: string
|
||||||
tags?: string[]
|
tags?: string[]
|
||||||
|
commentsEnabled?: boolean
|
||||||
privacy: VideoPrivacy
|
privacy: VideoPrivacy
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,6 @@ export interface VideoUpdate {
|
||||||
description?: string
|
description?: string
|
||||||
privacy?: VideoPrivacy
|
privacy?: VideoPrivacy
|
||||||
tags?: string[]
|
tags?: string[]
|
||||||
|
commentsEnabled?: boolean
|
||||||
nsfw?: boolean
|
nsfw?: boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,4 +45,5 @@ export interface VideoDetails extends Video {
|
||||||
tags: string[]
|
tags: string[]
|
||||||
files: VideoFile[]
|
files: VideoFile[]
|
||||||
account: Account
|
account: Account
|
||||||
|
commentsEnabled: boolean
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue