Add new abuses tests
This commit is contained in:
parent
811cef146c
commit
310b5219b3
|
@ -138,8 +138,8 @@
|
|||
<tr>
|
||||
<td colspan="6">
|
||||
<div class="no-results">
|
||||
<ng-container *ngIf="search" i18n>No video abuses found matching current filters.</ng-container>
|
||||
<ng-container *ngIf="!search" i18n>No video abuses found.</ng-container>
|
||||
<ng-container *ngIf="search" i18n>No abuses found matching current filters.</ng-container>
|
||||
<ng-container *ngIf="!search" i18n>No abuses found.</ng-container>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -118,7 +118,7 @@ export class UserNotification implements UserNotificationServer {
|
|||
this.commentUrl = [ this.buildVideoUrl(this.comment.video), { threadId: this.comment.threadId } ]
|
||||
break
|
||||
|
||||
case UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS:
|
||||
case UserNotificationType.NEW_ABUSE_FOR_MODERATORS:
|
||||
this.abuseUrl = '/admin/moderation/abuses/list'
|
||||
|
||||
if (this.abuse.video) this.videoUrl = this.buildVideoUrl(this.abuse.video)
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS">
|
||||
<ng-container *ngSwitchCase="UserNotificationType.NEW_ABUSE_FOR_MODERATORS">
|
||||
<my-global-icon iconName="flag" aria-hidden="true"></my-global-icon>
|
||||
|
||||
<div class="message" i18n>
|
||||
|
|
|
@ -140,7 +140,6 @@ export class VideoReportComponent extends FormReactive implements OnInit {
|
|||
const { hasStart, startAt, hasEnd, endAt } = this.form.get('timestamp').value
|
||||
|
||||
this.abuseService.reportVideo({
|
||||
accountId: this.video.account.id,
|
||||
reason,
|
||||
predefinedReasons,
|
||||
video: {
|
||||
|
|
|
@ -100,7 +100,7 @@ async function updateAbuse (req: express.Request, res: express.Response) {
|
|||
return abuse.save({ transaction: t })
|
||||
})
|
||||
|
||||
// Do not send the delete to other instances, we updated OUR copy of this video abuse
|
||||
// Do not send the delete to other instances, we updated OUR copy of this abuse
|
||||
|
||||
return res.type('json').status(204).end()
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ async function deleteAbuse (req: express.Request, res: express.Response) {
|
|||
return abuse.destroy({ transaction: t })
|
||||
})
|
||||
|
||||
// Do not send the delete to other instances, we delete OUR copy of this video abuse
|
||||
// Do not send the delete to other instances, we delete OUR copy of this abuse
|
||||
|
||||
return res.type('json').status(204).end()
|
||||
}
|
||||
|
|
|
@ -50,7 +50,5 @@ async function removeUserHistory (req: express.Request, res: express.Response) {
|
|||
return UserVideoHistoryModel.removeUserHistoryBefore(user, beforeDate, t)
|
||||
})
|
||||
|
||||
// Do not send the delete to other instances, we delete OUR copy of this video abuse
|
||||
|
||||
return res.type('json').status(204).end()
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ import { AbuseFilter, abusePredefinedReasonsMap, AbusePredefinedReasonsString, A
|
|||
import { ABUSE_STATES, CONSTRAINTS_FIELDS } from '../../initializers/constants'
|
||||
import { exists, isArray } from './misc'
|
||||
|
||||
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.ABUSES
|
||||
const ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.ABUSES
|
||||
|
||||
function isAbuseReasonValid (value: string) {
|
||||
return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
|
||||
return exists(value) && validator.isLength(value, ABUSES_CONSTRAINTS_FIELDS.REASON)
|
||||
}
|
||||
|
||||
function isAbusePredefinedReasonValid (value: AbusePredefinedReasonsString) {
|
||||
|
@ -32,7 +32,7 @@ function isAbuseTimestampCoherent (endAt: number, { req }) {
|
|||
}
|
||||
|
||||
function isAbuseModerationCommentValid (value: string) {
|
||||
return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.MODERATION_COMMENT)
|
||||
return exists(value) && validator.isLength(value, ABUSES_CONSTRAINTS_FIELDS.MODERATION_COMMENT)
|
||||
}
|
||||
|
||||
function isAbuseStateValid (value: string) {
|
||||
|
|
|
@ -68,7 +68,7 @@ async function doesVideoCommentExist (idArg: number | string, video: MVideoId, r
|
|||
|
||||
async function doesCommentIdExist (idArg: number | string, res: express.Response) {
|
||||
const id = parseInt(idArg + '', 10)
|
||||
const videoComment = await VideoCommentModel.loadById(id)
|
||||
const videoComment = await VideoCommentModel.loadByIdAndPopulateVideoAndAccountAndReply(id)
|
||||
|
||||
if (!videoComment) {
|
||||
res.status(404)
|
||||
|
@ -77,7 +77,7 @@ async function doesCommentIdExist (idArg: number | string, res: express.Response
|
|||
return false
|
||||
}
|
||||
|
||||
res.locals.videoComment = videoComment
|
||||
res.locals.videoCommentFull = videoComment
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ async function doesAbuseExist (abuseId: number | string, res: Response) {
|
|||
|
||||
if (!abuse) {
|
||||
res.status(404)
|
||||
.json({ error: 'Video abuse not found' })
|
||||
.json({ error: 'Abuse not found' })
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -43,12 +43,10 @@ async function up (utils: {
|
|||
await utils.sequelize.query(`
|
||||
CREATE TABLE IF NOT EXISTS "commentAbuse" (
|
||||
"id" serial,
|
||||
"deletedComment" jsonb DEFAULT NULL,
|
||||
"abuseId" integer NOT NULL REFERENCES "abuse" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
"videoCommentId" integer REFERENCES "videoComment" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
"createdAt" timestamp WITH time zone NOT NULL,
|
||||
"updatedAt" timestamp WITH time zone NOT NULL,
|
||||
"commentId" integer REFERENCES "videoComment" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
`)
|
||||
|
|
|
@ -325,6 +325,7 @@ class Emailer {
|
|||
subject: `New comment abuse report from ${reporter}`,
|
||||
locals: {
|
||||
commentUrl,
|
||||
videoName: comment.Video.name,
|
||||
isLocal: comment.isOwned(),
|
||||
commentCreatedAt: new Date(comment.createdAt).toLocaleString(),
|
||||
reason: abuse.reason,
|
||||
|
|
|
@ -7,7 +7,8 @@ block title
|
|||
block content
|
||||
p
|
||||
| #[a(href=WEBSERVER.URL) #{WEBSERVER.HOST}] received an abuse report for the #{isLocal ? '' : 'remote '}comment "
|
||||
a(href=commentUrl) of #{flaggedAccount}
|
||||
a(href=commentUrl) on video #{videoName}
|
||||
| of #{flaggedAccount}
|
||||
| created on #{commentCreatedAt}
|
||||
|
||||
p The reporter, #{reporter}, cited the following reason(s):
|
||||
|
|
|
@ -371,7 +371,7 @@ class Notifier {
|
|||
|
||||
async function notificationCreator (user: MUserWithNotificationSetting) {
|
||||
const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
|
||||
type: UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS,
|
||||
type: UserNotificationType.NEW_ABUSE_FOR_MODERATORS,
|
||||
userId: user.id,
|
||||
abuseId: abuse.id
|
||||
})
|
||||
|
|
|
@ -128,7 +128,7 @@ const abuseListValidator = [
|
|||
.custom(exists).withMessage('Should have a valid search'),
|
||||
query('state')
|
||||
.optional()
|
||||
.custom(isAbuseStateValid).withMessage('Should have a valid video abuse state'),
|
||||
.custom(isAbuseStateValid).withMessage('Should have a valid abuse state'),
|
||||
query('videoIs')
|
||||
.optional()
|
||||
.custom(isAbuseVideoIsValid).withMessage('Should have a valid "video is" attribute'),
|
||||
|
|
|
@ -362,8 +362,8 @@ export class AbuseModel extends Model<AbuseModel> {
|
|||
const countReportsForReporter = this.get('countReportsForReporter') as number
|
||||
const countReportsForReportee = this.get('countReportsForReportee') as number
|
||||
|
||||
let video: VideoAbuse
|
||||
let comment: VideoCommentAbuse
|
||||
let video: VideoAbuse = null
|
||||
let comment: VideoCommentAbuse = null
|
||||
|
||||
if (this.VideoAbuse) {
|
||||
const abuseModel = this.VideoAbuse
|
||||
|
@ -391,13 +391,13 @@ export class AbuseModel extends Model<AbuseModel> {
|
|||
|
||||
if (this.VideoCommentAbuse) {
|
||||
const abuseModel = this.VideoCommentAbuse
|
||||
const entity = abuseModel.VideoComment || abuseModel.deletedComment
|
||||
const entity = abuseModel.VideoComment
|
||||
|
||||
comment = {
|
||||
id: entity.id,
|
||||
text: entity.text,
|
||||
text: entity.text ?? '',
|
||||
|
||||
deleted: !abuseModel.VideoComment,
|
||||
deleted: entity.isDeleted(),
|
||||
|
||||
video: {
|
||||
id: entity.Video.id,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||
import { VideoComment } from '@shared/models'
|
||||
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||
import { VideoCommentModel } from '../video/video-comment'
|
||||
import { AbuseModel } from './abuse'
|
||||
|
||||
|
@ -22,11 +21,6 @@ export class VideoCommentAbuseModel extends Model<VideoCommentAbuseModel> {
|
|||
@UpdatedAt
|
||||
updatedAt: Date
|
||||
|
||||
@AllowNull(true)
|
||||
@Default(null)
|
||||
@Column(DataType.JSONB)
|
||||
deletedComment: VideoComment & { Video: { name: string, id: number, uuid: string }}
|
||||
|
||||
@ForeignKey(() => AbuseModel)
|
||||
@Column
|
||||
abuseId: number
|
||||
|
|
|
@ -109,7 +109,7 @@ function buildAccountInclude (required: boolean, withActor = false) {
|
|||
required: true,
|
||||
include: [
|
||||
{
|
||||
attributes: [ 'uuid' ],
|
||||
attributes: [ 'id', 'name', 'uuid' ],
|
||||
model: VideoModel.unscoped(),
|
||||
required: true
|
||||
}
|
||||
|
@ -492,6 +492,8 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
|
|||
threadId: abuse.VideoCommentAbuse.VideoComment.getThreadId(),
|
||||
|
||||
video: {
|
||||
id: abuse.VideoCommentAbuse.VideoComment.Video.id,
|
||||
name: abuse.VideoCommentAbuse.VideoComment.Video.name,
|
||||
uuid: abuse.VideoCommentAbuse.VideoComment.Video.uuid
|
||||
}
|
||||
} : undefined
|
||||
|
|
|
@ -3,7 +3,6 @@ import { uniq } from 'lodash'
|
|||
import { FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction } from 'sequelize'
|
||||
import {
|
||||
AllowNull,
|
||||
BeforeDestroy,
|
||||
BelongsTo,
|
||||
Column,
|
||||
CreatedAt,
|
||||
|
@ -16,7 +15,6 @@ import {
|
|||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { logger } from '@server/helpers/logger'
|
||||
import { getServerActor } from '@server/models/application/application'
|
||||
import { MAccount, MAccountId, MUserAccountId } from '@server/types/models'
|
||||
import { VideoPrivacy } from '@shared/models'
|
||||
|
@ -242,51 +240,13 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
|||
|
||||
@HasMany(() => VideoCommentAbuseModel, {
|
||||
foreignKey: {
|
||||
name: 'commentId',
|
||||
name: 'videoCommentId',
|
||||
allowNull: true
|
||||
},
|
||||
onDelete: 'set null'
|
||||
})
|
||||
CommentAbuses: VideoCommentAbuseModel[]
|
||||
|
||||
@BeforeDestroy
|
||||
static async saveEssentialDataToAbuses (instance: VideoCommentModel, options) {
|
||||
const tasks: Promise<any>[] = []
|
||||
|
||||
if (!Array.isArray(instance.CommentAbuses)) {
|
||||
instance.CommentAbuses = await instance.$get('CommentAbuses')
|
||||
|
||||
if (instance.CommentAbuses.length === 0) return undefined
|
||||
}
|
||||
|
||||
if (!instance.Video) {
|
||||
instance.Video = await instance.$get('Video')
|
||||
}
|
||||
|
||||
logger.info('Saving video comment %s for abuse.', instance.url)
|
||||
|
||||
const details = Object.assign(instance.toFormattedJSON(), {
|
||||
Video: {
|
||||
id: instance.Video.id,
|
||||
name: instance.Video.name,
|
||||
uuid: instance.Video.uuid
|
||||
}
|
||||
})
|
||||
|
||||
for (const abuse of instance.CommentAbuses) {
|
||||
abuse.deletedComment = details
|
||||
|
||||
tasks.push(abuse.save({ transaction: options.transaction }))
|
||||
}
|
||||
|
||||
Promise.all(tasks)
|
||||
.catch(err => {
|
||||
logger.error('Some errors when saving details of comment %s in its abuses before destroy hook.', instance.url, { err })
|
||||
})
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
static loadById (id: number, t?: Transaction): Bluebird<MComment> {
|
||||
const query: FindOptions = {
|
||||
where: {
|
||||
|
|
|
@ -21,9 +21,7 @@ import {
|
|||
checkBadStartPagination
|
||||
} from '../../../../shared/extra-utils/requests/check-api-params'
|
||||
|
||||
// FIXME: deprecated in 2.3. Remove this controller
|
||||
|
||||
describe('Test video abuses API validators', function () {
|
||||
describe('Test abuses API validators', function () {
|
||||
const basePath = '/api/v1/abuses/'
|
||||
|
||||
let server: ServerInfo
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,10 +3,16 @@
|
|||
import 'mocha'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import {
|
||||
addVideoCommentThread,
|
||||
addVideoToBlacklist,
|
||||
cleanupTests,
|
||||
createUser,
|
||||
follow,
|
||||
generateUserAccessToken,
|
||||
getAccount,
|
||||
getCustomConfig,
|
||||
getVideoCommentThreads,
|
||||
getVideoIdFromUUID,
|
||||
immutableAssign,
|
||||
MockInstancesIndex,
|
||||
registerUser,
|
||||
|
@ -23,7 +29,9 @@ import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
|
|||
import {
|
||||
checkAutoInstanceFollowing,
|
||||
CheckerBaseParams,
|
||||
checkNewAccountAbuseForModerators,
|
||||
checkNewBlacklistOnMyVideo,
|
||||
checkNewCommentAbuseForModerators,
|
||||
checkNewInstanceFollower,
|
||||
checkNewVideoAbuseForModerators,
|
||||
checkNewVideoFromSubscription,
|
||||
|
@ -91,11 +99,74 @@ describe('Test moderation notifications', function () {
|
|||
|
||||
await waitJobs(servers)
|
||||
|
||||
await reportAbuse({ url: servers[1].url, token: servers[1].accessToken, videoId: video.id, reason: 'super reason' })
|
||||
const videoId = await getVideoIdFromUUID(servers[1].url, video.uuid)
|
||||
await reportAbuse({ url: servers[1].url, token: servers[1].accessToken, videoId, reason: 'super reason' })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkNewVideoAbuseForModerators(baseParams, video.uuid, name, 'presence')
|
||||
})
|
||||
|
||||
it('Should send a notification to moderators on local comment abuse', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + uuidv4())
|
||||
const comment = resComment.body.comment
|
||||
|
||||
await reportAbuse({ url: servers[0].url, token: servers[0].accessToken, commentId: comment.id, reason: 'super reason' })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkNewCommentAbuseForModerators(baseParams, video.uuid, name, 'presence')
|
||||
})
|
||||
|
||||
it('Should send a notification to moderators on remote comment abuse', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const name = 'video for abuse ' + uuidv4()
|
||||
const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
|
||||
const video = resVideo.body.video
|
||||
await addVideoCommentThread(servers[0].url, userAccessToken, video.id, 'comment abuse ' + uuidv4())
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
const resComments = await getVideoCommentThreads(servers[1].url, video.uuid, 0, 5)
|
||||
const commentId = resComments.body.data[0].id
|
||||
await reportAbuse({ url: servers[1].url, token: servers[1].accessToken, commentId, reason: 'super reason' })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkNewCommentAbuseForModerators(baseParams, video.uuid, name, 'presence')
|
||||
})
|
||||
|
||||
it('Should send a notification to moderators on local account abuse', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const username = 'user' + new Date().getTime()
|
||||
const resUser = await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username, password: 'donald' })
|
||||
const accountId = resUser.body.user.account.id
|
||||
|
||||
await reportAbuse({ url: servers[0].url, token: servers[0].accessToken, accountId, reason: 'super reason' })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkNewAccountAbuseForModerators(baseParams, username, 'presence')
|
||||
})
|
||||
|
||||
it('Should send a notification to moderators on remote account abuse', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
const username = 'user' + new Date().getTime()
|
||||
const tmpToken = await generateUserAccessToken(servers[0], username)
|
||||
await uploadVideo(servers[0].url, tmpToken, { name: 'super video' })
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
const resAccount = await getAccount(servers[1].url, username + '@' + servers[0].host)
|
||||
await reportAbuse({ url: servers[1].url, token: servers[1].accessToken, accountId: resAccount.body.id, reason: 'super reason' })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkNewAccountAbuseForModerators(baseParams, username, 'presence')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Video blacklist on my video', function () {
|
||||
|
|
|
@ -180,7 +180,7 @@ describe('Test emails', function () {
|
|||
})
|
||||
})
|
||||
|
||||
describe('When creating a video abuse', function () {
|
||||
describe('When creating an abuse', function () {
|
||||
it('Should send the notification email', async function () {
|
||||
this.timeout(10000)
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ export module UserNotificationIncludes {
|
|||
Pick<VideoCommentAbuseModel, 'id'> &
|
||||
PickWith<VideoCommentAbuseModel, 'VideoComment',
|
||||
Pick<VideoCommentModel, 'id' | 'originCommentId' | 'getThreadId'> &
|
||||
PickWith<VideoCommentModel, 'Video', Pick<VideoModel, 'uuid'>>>
|
||||
PickWith<VideoCommentModel, 'Video', Pick<VideoModel, 'id' | 'name' | 'uuid'>>>
|
||||
|
||||
export type AbuseInclude =
|
||||
Pick<AbuseModel, 'id'> &
|
||||
|
|
|
@ -91,7 +91,6 @@ declare module 'express' {
|
|||
|
||||
accountVideoRate?: MAccountVideoRateAccountVideo
|
||||
|
||||
videoComment?: MComment
|
||||
videoCommentFull?: MCommentOwnerVideoReply
|
||||
videoCommentThread?: MComment
|
||||
|
||||
|
|
|
@ -57,10 +57,15 @@ function reportAbuse (options: {
|
|||
function getAbusesList (options: {
|
||||
url: string
|
||||
token: string
|
||||
|
||||
start?: number
|
||||
count?: number
|
||||
sort?: string
|
||||
|
||||
id?: number
|
||||
predefinedReason?: AbusePredefinedReasonsString
|
||||
search?: string
|
||||
filter?: AbuseFilter,
|
||||
filter?: AbuseFilter
|
||||
state?: AbuseState
|
||||
videoIs?: AbuseVideoIs
|
||||
searchReporter?: string
|
||||
|
@ -71,6 +76,9 @@ function getAbusesList (options: {
|
|||
const {
|
||||
url,
|
||||
token,
|
||||
start,
|
||||
count,
|
||||
sort,
|
||||
id,
|
||||
predefinedReason,
|
||||
search,
|
||||
|
@ -85,13 +93,15 @@ function getAbusesList (options: {
|
|||
const path = '/api/v1/abuses'
|
||||
|
||||
const query = {
|
||||
sort: 'createdAt',
|
||||
id,
|
||||
predefinedReason,
|
||||
search,
|
||||
state,
|
||||
filter,
|
||||
videoIs,
|
||||
start,
|
||||
count,
|
||||
sort: sort || 'createdAt',
|
||||
searchReporter,
|
||||
searchReportee,
|
||||
searchVideo,
|
||||
|
|
|
@ -37,8 +37,8 @@ interface ServerInfo {
|
|||
video?: {
|
||||
id: number
|
||||
uuid: string
|
||||
name: string
|
||||
account: {
|
||||
name?: string
|
||||
account?: {
|
||||
name: string
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,13 +139,17 @@ async function checkNotification (
|
|||
}
|
||||
|
||||
function checkVideo (video: any, videoName?: string, videoUUID?: string) {
|
||||
expect(video.name).to.be.a('string')
|
||||
expect(video.name).to.not.be.empty
|
||||
if (videoName) expect(video.name).to.equal(videoName)
|
||||
if (videoName) {
|
||||
expect(video.name).to.be.a('string')
|
||||
expect(video.name).to.not.be.empty
|
||||
expect(video.name).to.equal(videoName)
|
||||
}
|
||||
|
||||
expect(video.uuid).to.be.a('string')
|
||||
expect(video.uuid).to.not.be.empty
|
||||
if (videoUUID) expect(video.uuid).to.equal(videoUUID)
|
||||
if (videoUUID) {
|
||||
expect(video.uuid).to.be.a('string')
|
||||
expect(video.uuid).to.not.be.empty
|
||||
expect(video.uuid).to.equal(videoUUID)
|
||||
}
|
||||
|
||||
expect(video.id).to.be.a('number')
|
||||
}
|
||||
|
@ -436,7 +440,7 @@ async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string,
|
|||
}
|
||||
|
||||
async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
|
||||
const notificationType = UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS
|
||||
const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
|
||||
|
||||
function notificationChecker (notification: UserNotification, type: CheckerType) {
|
||||
if (type === 'presence') {
|
||||
|
@ -460,6 +464,56 @@ async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUU
|
|||
await checkNotification(base, notificationChecker, emailNotificationFinder, type)
|
||||
}
|
||||
|
||||
async function checkNewCommentAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
|
||||
const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
|
||||
|
||||
function notificationChecker (notification: UserNotification, type: CheckerType) {
|
||||
if (type === 'presence') {
|
||||
expect(notification).to.not.be.undefined
|
||||
expect(notification.type).to.equal(notificationType)
|
||||
|
||||
expect(notification.abuse.id).to.be.a('number')
|
||||
checkVideo(notification.abuse.comment.video, videoName, videoUUID)
|
||||
} else {
|
||||
expect(notification).to.satisfy((n: UserNotification) => {
|
||||
return n === undefined || n.abuse === undefined || n.abuse.comment.video.uuid !== videoUUID
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function emailNotificationFinder (email: object) {
|
||||
const text = email['text']
|
||||
return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
|
||||
}
|
||||
|
||||
await checkNotification(base, notificationChecker, emailNotificationFinder, type)
|
||||
}
|
||||
|
||||
async function checkNewAccountAbuseForModerators (base: CheckerBaseParams, displayName: string, type: CheckerType) {
|
||||
const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
|
||||
|
||||
function notificationChecker (notification: UserNotification, type: CheckerType) {
|
||||
if (type === 'presence') {
|
||||
expect(notification).to.not.be.undefined
|
||||
expect(notification.type).to.equal(notificationType)
|
||||
|
||||
expect(notification.abuse.id).to.be.a('number')
|
||||
expect(notification.abuse.account.displayName).to.equal(displayName)
|
||||
} else {
|
||||
expect(notification).to.satisfy((n: UserNotification) => {
|
||||
return n === undefined || n.abuse === undefined || n.abuse.account.displayName !== displayName
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function emailNotificationFinder (email: object) {
|
||||
const text = email['text']
|
||||
return text.indexOf(displayName) !== -1 && text.indexOf('abuse') !== -1
|
||||
}
|
||||
|
||||
await checkNotification(base, notificationChecker, emailNotificationFinder, type)
|
||||
}
|
||||
|
||||
async function checkVideoAutoBlacklistForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
|
||||
const notificationType = UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS
|
||||
|
||||
|
@ -541,6 +595,9 @@ async function prepareNotificationsTest (serversCount = 3) {
|
|||
smtp: {
|
||||
hostname: 'localhost',
|
||||
port
|
||||
},
|
||||
signup: {
|
||||
limit: 20
|
||||
}
|
||||
}
|
||||
const servers = await flushAndRunMultipleServers(serversCount, overrideConfig)
|
||||
|
@ -623,5 +680,7 @@ export {
|
|||
markAsReadNotifications,
|
||||
getLastNotification,
|
||||
checkNewInstanceFollower,
|
||||
prepareNotificationsTest
|
||||
prepareNotificationsTest,
|
||||
checkNewCommentAbuseForModerators,
|
||||
checkNewAccountAbuseForModerators
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { FollowState } from '../actors'
|
|||
export enum UserNotificationType {
|
||||
NEW_VIDEO_FROM_SUBSCRIPTION = 1,
|
||||
NEW_COMMENT_ON_MY_VIDEO = 2,
|
||||
NEW_VIDEO_ABUSE_FOR_MODERATORS = 3,
|
||||
NEW_ABUSE_FOR_MODERATORS = 3,
|
||||
|
||||
BLACKLIST_ON_MY_VIDEO = 4,
|
||||
UNBLACKLIST_ON_MY_VIDEO = 5,
|
||||
|
|
|
@ -106,9 +106,9 @@ tags:
|
|||
Managing plugins installed from a local path or from NPM, or search for new ones.
|
||||
externalDocs:
|
||||
url: https://docs.joinpeertube.org/#/api-plugins
|
||||
- name: Video Abuses
|
||||
- name: Abuses
|
||||
description: |
|
||||
Video abuses deal with reports of local or remote videos alike.
|
||||
Abuses deal with reports of local or remote videos/comments/accounts alike.
|
||||
- name: Video
|
||||
description: |
|
||||
Operations dealing with listing, uploading, fetching or modifying videos.
|
||||
|
@ -166,7 +166,7 @@ x-tagGroups:
|
|||
- Search
|
||||
- name: Moderation
|
||||
tags:
|
||||
- Video Abuses
|
||||
- Abuses
|
||||
- Video Blocks
|
||||
- Account Blocks
|
||||
- Server Blocks
|
||||
|
@ -1474,13 +1474,13 @@ paths:
|
|||
/videos/abuse:
|
||||
get:
|
||||
deprecated: true
|
||||
summary: List video abuses
|
||||
summary: List abuses
|
||||
security:
|
||||
- OAuth2:
|
||||
- admin
|
||||
- moderator
|
||||
tags:
|
||||
- Video Abuses
|
||||
- Abuses
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
|
@ -1508,7 +1508,7 @@ paths:
|
|||
type: string
|
||||
- name: state
|
||||
in: query
|
||||
description: 'The video playlist privacy (Pending = `1`, Rejected = `2`, Accepted = `3`)'
|
||||
description: 'The abuse state (Pending = `1`, Rejected = `2`, Accepted = `3`)'
|
||||
schema:
|
||||
type: integer
|
||||
enum:
|
||||
|
@ -1554,7 +1554,7 @@ paths:
|
|||
security:
|
||||
- OAuth2: []
|
||||
tags:
|
||||
- Video Abuses
|
||||
- Abuses
|
||||
- Videos
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/idOrUUID'
|
||||
|
@ -1607,7 +1607,7 @@ paths:
|
|||
- admin
|
||||
- moderator
|
||||
tags:
|
||||
- Video Abuses
|
||||
- Abuses
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/idOrUUID'
|
||||
- $ref: '#/components/parameters/abuseId'
|
||||
|
@ -1626,11 +1626,11 @@ paths:
|
|||
'204':
|
||||
description: successful operation
|
||||
'404':
|
||||
description: video abuse not found
|
||||
description: abuse not found
|
||||
delete:
|
||||
deprecated: true
|
||||
tags:
|
||||
- Video Abuses
|
||||
- Abuses
|
||||
summary: Delete an abuse
|
||||
security:
|
||||
- OAuth2:
|
||||
|
@ -3320,7 +3320,7 @@ components:
|
|||
name: abuseId
|
||||
in: path
|
||||
required: true
|
||||
description: Video abuse id
|
||||
description: Abuse id
|
||||
schema:
|
||||
type: integer
|
||||
captionLanguage:
|
||||
|
@ -5098,7 +5098,7 @@ components:
|
|||
|
||||
- `2` NEW_COMMENT_ON_MY_VIDEO
|
||||
|
||||
- `3` NEW_VIDEO_ABUSE_FOR_MODERATORS
|
||||
- `3` NEW_ABUSE_FOR_MODERATORS
|
||||
|
||||
- `4` BLACKLIST_ON_MY_VIDEO
|
||||
|
||||
|
|
Loading…
Reference in New Issue