1
0
Fork 0

Add federation to ownership change

This commit is contained in:
Chocobozzz 2018-09-04 10:22:10 +02:00
parent 0b74c74abe
commit 5cf84858d4
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
13 changed files with 139 additions and 79 deletions

View File

@ -53,7 +53,7 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
const query = event.query const query = event.query
this.userService.autocomplete(query) this.userService.autocomplete(query)
.subscribe( .subscribe(
(usernames) => { usernames => {
this.usernamePropositions = usernames this.usernamePropositions = usernames
}, },
@ -67,7 +67,7 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
this.videoOwnershipService this.videoOwnershipService
.changeOwnership(this.video.id, username) .changeOwnership(this.video.id, username)
.subscribe( .subscribe(
() => this.notificationsService.success(this.i18n('Success'), this.i18n('Ownership changed.')), () => this.notificationsService.success(this.i18n('Success'), this.i18n('Ownership change request sent.')),
err => this.notificationsService.error(this.i18n('Error'), err.message) err => this.notificationsService.error(this.i18n('Error'), err.message)
) )

View File

@ -229,7 +229,7 @@ function getUser (req: express.Request, res: express.Response, next: express.Nex
} }
async function autocompleteUsers (req: express.Request, res: express.Response, next: express.NextFunction) { async function autocompleteUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await UserModel.autocomplete(req.query.search as string) const resultList = await UserModel.autoComplete(req.query.search as string)
return res.json(resultList) return res.json(resultList)
} }

View File

@ -14,9 +14,11 @@ import {
import { AccountModel } from '../../../models/account/account' import { AccountModel } from '../../../models/account/account'
import { VideoModel } from '../../../models/video/video' import { VideoModel } from '../../../models/video/video'
import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ownership' import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ownership'
import { VideoChangeOwnershipStatus } from '../../../../shared/models/videos' import { VideoChangeOwnershipStatus, VideoPrivacy, VideoState } from '../../../../shared/models/videos'
import { VideoChannelModel } from '../../../models/video/video-channel' import { VideoChannelModel } from '../../../models/video/video-channel'
import { getFormattedObjects } from '../../../helpers/utils' import { getFormattedObjects } from '../../../helpers/utils'
import { changeVideoChannelShare } from '../../../lib/activitypub'
import { sendUpdateVideo } from '../../../lib/activitypub/send'
const ownershipVideoRouter = express.Router() const ownershipVideoRouter = express.Router()
@ -59,8 +61,8 @@ async function giveVideoOwnership (req: express.Request, res: express.Response)
const initiatorAccount = res.locals.oauth.token.User.Account as AccountModel const initiatorAccount = res.locals.oauth.token.User.Account as AccountModel
const nextOwner = res.locals.nextOwner as AccountModel const nextOwner = res.locals.nextOwner as AccountModel
await sequelizeTypescript.transaction(async t => { await sequelizeTypescript.transaction(t => {
await VideoChangeOwnershipModel.findOrCreate({ return VideoChangeOwnershipModel.findOrCreate({
where: { where: {
initiatorAccountId: initiatorAccount.id, initiatorAccountId: initiatorAccount.id,
nextOwnerAccountId: nextOwner.id, nextOwnerAccountId: nextOwner.id,
@ -72,11 +74,14 @@ async function giveVideoOwnership (req: express.Request, res: express.Response)
nextOwnerAccountId: nextOwner.id, nextOwnerAccountId: nextOwner.id,
videoId: videoInstance.id, videoId: videoInstance.id,
status: VideoChangeOwnershipStatus.WAITING status: VideoChangeOwnershipStatus.WAITING
} },
transaction: t
}) })
logger.info('Ownership change for video %s created.', videoInstance.name)
return res.type('json').status(204).end()
}) })
logger.info('Ownership change for video %s created.', videoInstance.name)
return res.type('json').status(204).end()
} }
async function listVideoOwnership (req: express.Request, res: express.Response) { async function listVideoOwnership (req: express.Request, res: express.Response) {
@ -97,11 +102,19 @@ async function acceptOwnership (req: express.Request, res: express.Response) {
const targetVideo = videoChangeOwnership.Video const targetVideo = videoChangeOwnership.Video
const channel = res.locals.videoChannel as VideoChannelModel const channel = res.locals.videoChannel as VideoChannelModel
targetVideo.set('channelId', channel.id) const oldVideoChannel = await VideoChannelModel.loadByIdAndPopulateAccount(targetVideo.channelId)
targetVideo.set('channelId', channel.id)
const targetVideoUpdated = await targetVideo.save({ transaction: t })
targetVideoUpdated.VideoChannel = channel
if (targetVideoUpdated.privacy !== VideoPrivacy.PRIVATE && targetVideoUpdated.state === VideoState.PUBLISHED) {
await changeVideoChannelShare(targetVideoUpdated, oldVideoChannel, t)
await sendUpdateVideo(targetVideoUpdated, t, oldVideoChannel.Account.Actor)
}
await targetVideo.save()
videoChangeOwnership.set('status', VideoChangeOwnershipStatus.ACCEPTED) videoChangeOwnership.set('status', VideoChangeOwnershipStatus.ACCEPTED)
await videoChangeOwnership.save() await videoChangeOwnership.save({ transaction: t })
return res.sendStatus(204) return res.sendStatus(204)
}) })
@ -110,8 +123,10 @@ async function acceptOwnership (req: express.Request, res: express.Response) {
async function refuseOwnership (req: express.Request, res: express.Response) { async function refuseOwnership (req: express.Request, res: express.Response) {
return sequelizeTypescript.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const videoChangeOwnership = res.locals.videoChangeOwnership as VideoChangeOwnershipModel const videoChangeOwnership = res.locals.videoChangeOwnership as VideoChangeOwnershipModel
videoChangeOwnership.set('status', VideoChangeOwnershipStatus.REFUSED) videoChangeOwnership.set('status', VideoChangeOwnershipStatus.REFUSED)
await videoChangeOwnership.save() await videoChangeOwnership.save({ transaction: t })
return res.sendStatus(204) return res.sendStatus(204)
}) })
} }

View File

@ -1,13 +1,15 @@
import { isActorFollowActivityValid } from './actor' import { isActorFollowActivityValid } from './actor'
import { isBaseActivityValid } from './misc' import { isBaseActivityValid } from './misc'
import { isDislikeActivityValid, isLikeActivityValid } from './rate' import { isDislikeActivityValid, isLikeActivityValid } from './rate'
import { isAnnounceActivityValid } from './announce'
function isUndoActivityValid (activity: any) { function isUndoActivityValid (activity: any) {
return isBaseActivityValid(activity, 'Undo') && return isBaseActivityValid(activity, 'Undo') &&
( (
isActorFollowActivityValid(activity.object) || isActorFollowActivityValid(activity.object) ||
isLikeActivityValid(activity.object) || isLikeActivityValid(activity.object) ||
isDislikeActivityValid(activity.object) isDislikeActivityValid(activity.object) ||
isAnnounceActivityValid(activity.object)
) )
} }

View File

@ -104,17 +104,19 @@ function processUndoFollow (actorUrl: string, followActivity: ActivityFollow) {
function processUndoAnnounce (actorUrl: string, announceActivity: ActivityAnnounce) { function processUndoAnnounce (actorUrl: string, announceActivity: ActivityAnnounce) {
return sequelizeTypescript.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const byAccount = await AccountModel.loadByUrl(actorUrl, t) const byActor = await ActorModel.loadByUrl(actorUrl, t)
if (!byAccount) throw new Error('Unknown account ' + actorUrl) if (!byActor) throw new Error('Unknown actor ' + actorUrl)
const share = await VideoShareModel.loadByUrl(announceActivity.id, t) const share = await VideoShareModel.loadByUrl(announceActivity.id, t)
if (!share) throw new Error(`'Unknown video share ${announceActivity.id}.`) if (!share) throw new Error(`Unknown video share ${announceActivity.id}.`)
if (share.actorId !== byActor.id) throw new Error(`${share.url} is not shared by ${byActor.url}.`)
await share.destroy({ transaction: t }) await share.destroy({ transaction: t })
if (share.Video.isOwned()) { if (share.Video.isOwned()) {
// Don't resend the activity to the sender // Don't resend the activity to the sender
const exceptions = [ byAccount.Actor ] const exceptions = [ byActor ]
await forwardVideoRelatedActivity(announceActivity, t, exceptions, share.Video) await forwardVideoRelatedActivity(announceActivity, t, exceptions, share.Video)
} }

View File

@ -20,7 +20,10 @@ async function sendVideoAnnounce (byActor: ActorModel, videoShare: VideoShareMod
logger.info('Creating job to send announce %s.', videoShare.url) logger.info('Creating job to send announce %s.', videoShare.url)
return broadcastToFollowers(data, byActor, [ byActor ], t) const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
const followersException = [ byActor ]
return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, followersException)
} }
function announceActivityData (url: string, byActor: ActorModel, object: string, audience?: ActivityAudience): ActivityAnnounce { function announceActivityData (url: string, byActor: ActorModel, object: string, audience?: ActivityAudience): ActivityAnnounce {

View File

@ -10,13 +10,19 @@ import { getUpdateActivityPubUrl } from '../url'
import { broadcastToFollowers } from './utils' import { broadcastToFollowers } from './utils'
import { audiencify, getAudience } from '../audience' import { audiencify, getAudience } from '../audience'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
import { videoFeedsValidator } from '../../../middlewares/validators'
import { VideoCaptionModel } from '../../../models/video/video-caption'
async function sendUpdateVideo (video: VideoModel, t: Transaction) { async function sendUpdateVideo (video: VideoModel, t: Transaction, overrodeByActor?: ActorModel) {
logger.info('Creating job to update video %s.', video.url) logger.info('Creating job to update video %s.', video.url)
const byActor = video.VideoChannel.Account.Actor const byActor = overrodeByActor ? overrodeByActor : video.VideoChannel.Account.Actor
const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString()) const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString())
// Needed to build the AP object
if (!video.VideoCaptions) video.VideoCaptions = await video.$get('VideoCaptions') as VideoCaptionModel[]
const videoObject = video.toActivityPubObject() const videoObject = video.toActivityPubObject()
const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC) const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC)

View File

@ -22,6 +22,8 @@ async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction)
} }
async function changeVideoChannelShare (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) { async function changeVideoChannelShare (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) {
logger.info('Updating video channel of video %s: %s -> %s.', video.uuid, oldVideoChannel.name, video.VideoChannel.name)
await undoShareByVideoChannel(video, oldVideoChannel, t) await undoShareByVideoChannel(video, oldVideoChannel, t)
await shareByVideoChannel(video, t) await shareByVideoChannel(video, t)

View File

@ -23,13 +23,13 @@ import {
isUserAutoPlayVideoValid, isUserAutoPlayVideoValid,
isUserBlockedReasonValid, isUserBlockedReasonValid,
isUserBlockedValid, isUserBlockedValid,
isUserNSFWPolicyValid,
isUserEmailVerifiedValid, isUserEmailVerifiedValid,
isUserNSFWPolicyValid,
isUserPasswordValid, isUserPasswordValid,
isUserRoleValid, isUserRoleValid,
isUserUsernameValid, isUserUsernameValid,
isUserVideoQuotaValid, isUserVideoQuotaDailyValid,
isUserVideoQuotaDailyValid isUserVideoQuotaValid
} from '../../helpers/custom-validators/users' } from '../../helpers/custom-validators/users'
import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
import { OAuthTokenModel } from '../oauth/oauth-token' import { OAuthTokenModel } from '../oauth/oauth-token'
@ -39,7 +39,6 @@ import { AccountModel } from './account'
import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type' import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
import { values } from 'lodash' import { values } from 'lodash'
import { NSFW_POLICY_TYPES } from '../../initializers' import { NSFW_POLICY_TYPES } from '../../initializers'
import { VideoFileModel } from '../video/video-file'
enum ScopeNames { enum ScopeNames {
WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL' WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
@ -296,6 +295,20 @@ export class UserModel extends Model<UserModel> {
} }
} }
static autoComplete (search: string) {
const query = {
where: {
username: {
[ Sequelize.Op.like ]: `%${search}%`
}
},
limit: 10
}
return UserModel.findAll(query)
.then(u => u.map(u => u.username))
}
hasRight (right: UserRight) { hasRight (right: UserRight) {
return hasUserRight(this.role, right) return hasUserRight(this.role, right)
} }
@ -394,15 +407,4 @@ export class UserModel extends Model<UserModel> {
return parseInt(total, 10) return parseInt(total, 10)
}) })
} }
static autocomplete (search: string) {
return UserModel.findAll({
where: {
username: {
[Sequelize.Op.like]: `%${search}%`
}
}
})
.then(u => u.map(u => u.username))
}
} }

View File

@ -39,7 +39,9 @@ enum ScopeNames {
{ {
model: () => VideoModel, model: () => VideoModel,
required: true, required: true,
include: [{ model: () => VideoFileModel }] include: [
{ model: () => VideoFileModel }
]
} }
] ]
} }
@ -94,15 +96,17 @@ export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel>
Video: VideoModel Video: VideoModel
static listForApi (nextOwnerId: number, start: number, count: number, sort: string) { static listForApi (nextOwnerId: number, start: number, count: number, sort: string) {
return VideoChangeOwnershipModel.scope(ScopeNames.FULL).findAndCountAll({ const query = {
offset: start, offset: start,
limit: count, limit: count,
order: getSort(sort), order: getSort(sort),
where: { where: {
nextOwnerAccountId: nextOwnerId nextOwnerAccountId: nextOwnerId
} }
}) }
.then(({ rows, count }) => ({ total: count, data: rows }))
return VideoChangeOwnershipModel.scope(ScopeNames.FULL).findAndCountAll(query)
.then(({ rows, count }) => ({ total: count, data: rows }))
} }
static load (id: number) { static load (id: number) {

View File

@ -296,6 +296,12 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
}) })
} }
static loadByIdAndPopulateAccount (id: number) {
return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findById(id)
}
static loadByIdAndAccount (id: number, accountId: number) { static loadByIdAndAccount (id: number, accountId: number) {
const query = { const query = {
where: { where: {
@ -304,13 +310,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
} }
} }
return VideoChannelModel return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findOne(query) .findOne(query)
} }
static loadAndPopulateAccount (id: number) { static loadAndPopulateAccount (id: number) {
return VideoChannelModel return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findById(id) .findById(id)
} }
@ -365,7 +371,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
] ]
} }
return VideoChannelModel return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findOne(query) .findOne(query)
} }
@ -390,7 +396,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
] ]
} }
return VideoChannelModel return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findOne(query) .findOne(query)
} }
@ -402,7 +408,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
] ]
} }
return VideoChannelModel return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ]) .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
.findById(id, options) .findById(id, options)
} }

View File

@ -5,6 +5,7 @@ import './video-abuse'
import './video-blacklist' import './video-blacklist'
import './video-blacklist-management' import './video-blacklist-management'
import './video-captions' import './video-captions'
import './vidoe-change-ownership'
import './video-channels' import './video-channels'
import './video-comments' import './video-comments'
import './video-description' import './video-description'

View File

@ -5,7 +5,7 @@ import 'mocha'
import { import {
acceptChangeOwnership, acceptChangeOwnership,
changeVideoOwnership, changeVideoOwnership,
createUser, createUser, doubleFollow, flushAndRunMultipleServers,
flushTests, flushTests,
getMyUserInformation, getMyUserInformation,
getVideoChangeOwnershipList, getVideoChangeOwnershipList,
@ -16,15 +16,17 @@ import {
ServerInfo, ServerInfo,
setAccessTokensToServers, setAccessTokensToServers,
uploadVideo, uploadVideo,
userLogin userLogin,
getVideo
} from '../../utils' } from '../../utils'
import { waitJobs } from '../../utils/server/jobs' import { waitJobs } from '../../utils/server/jobs'
import { User } from '../../../../shared/models/users' import { User } from '../../../../shared/models/users'
import { VideoDetails } from '../../../../shared/models/videos'
const expect = chai.expect const expect = chai.expect
describe('Test video change ownership - nominal', function () { describe('Test video change ownership - nominal', function () {
let server: ServerInfo = undefined let servers: ServerInfo[] = []
const firstUser = { const firstUser = {
username: 'first', username: 'first',
password: 'My great password' password: 'My great password'
@ -40,43 +42,44 @@ describe('Test video change ownership - nominal', function () {
before(async function () { before(async function () {
this.timeout(50000) this.timeout(50000)
// Run one server servers = await flushAndRunMultipleServers(2)
await flushTests() await setAccessTokensToServers(servers)
server = await runServer(1)
await setAccessTokensToServers([server])
const videoQuota = 42000000 const videoQuota = 42000000
await createUser(server.url, server.accessToken, firstUser.username, firstUser.password, videoQuota) await createUser(servers[0].url, servers[0].accessToken, firstUser.username, firstUser.password, videoQuota)
await createUser(server.url, server.accessToken, secondUser.username, secondUser.password, videoQuota) await createUser(servers[0].url, servers[0].accessToken, secondUser.username, secondUser.password, videoQuota)
firstUserAccessToken = await userLogin(server, firstUser) firstUserAccessToken = await userLogin(servers[0], firstUser)
secondUserAccessToken = await userLogin(server, secondUser) secondUserAccessToken = await userLogin(servers[0], secondUser)
// Upload some videos on the server const videoAttributes = {
const video1Attributes = {
name: 'my super name', name: 'my super name',
description: 'my super description' description: 'my super description'
} }
await uploadVideo(server.url, firstUserAccessToken, video1Attributes) await uploadVideo(servers[0].url, firstUserAccessToken, videoAttributes)
await waitJobs(server) await waitJobs(servers)
const res = await getVideosList(server.url) const res = await getVideosList(servers[0].url)
const videos = res.body.data const videos = res.body.data
expect(videos.length).to.equal(1) expect(videos.length).to.equal(1)
server.video = videos.find(video => video.name === 'my super name') const video = videos.find(video => video.name === 'my super name')
expect(video.channel.name).to.equal('first_channel')
servers[0].video = video
await doubleFollow(servers[0], servers[1])
}) })
it('Should not have video change ownership', async function () { it('Should not have video change ownership', async function () {
const resFirstUser = await getVideoChangeOwnershipList(server.url, firstUserAccessToken) const resFirstUser = await getVideoChangeOwnershipList(servers[0].url, firstUserAccessToken)
expect(resFirstUser.body.total).to.equal(0) expect(resFirstUser.body.total).to.equal(0)
expect(resFirstUser.body.data).to.be.an('array') expect(resFirstUser.body.data).to.be.an('array')
expect(resFirstUser.body.data.length).to.equal(0) expect(resFirstUser.body.data.length).to.equal(0)
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken) const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
expect(resSecondUser.body.total).to.equal(0) expect(resSecondUser.body.total).to.equal(0)
expect(resSecondUser.body.data).to.be.an('array') expect(resSecondUser.body.data).to.be.an('array')
@ -86,17 +89,17 @@ describe('Test video change ownership - nominal', function () {
it('Should send a request to change ownership of a video', async function () { it('Should send a request to change ownership of a video', async function () {
this.timeout(15000) this.timeout(15000)
await changeVideoOwnership(server.url, firstUserAccessToken, server.video.id, secondUser.username) await changeVideoOwnership(servers[0].url, firstUserAccessToken, servers[0].video.id, secondUser.username)
}) })
it('Should only return a request to change ownership for the second user', async function () { it('Should only return a request to change ownership for the second user', async function () {
const resFirstUser = await getVideoChangeOwnershipList(server.url, firstUserAccessToken) const resFirstUser = await getVideoChangeOwnershipList(servers[0].url, firstUserAccessToken)
expect(resFirstUser.body.total).to.equal(0) expect(resFirstUser.body.total).to.equal(0)
expect(resFirstUser.body.data).to.be.an('array') expect(resFirstUser.body.data).to.be.an('array')
expect(resFirstUser.body.data.length).to.equal(0) expect(resFirstUser.body.data.length).to.equal(0)
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken) const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
expect(resSecondUser.body.total).to.equal(1) expect(resSecondUser.body.total).to.equal(1)
expect(resSecondUser.body.data).to.be.an('array') expect(resSecondUser.body.data).to.be.an('array')
@ -108,13 +111,13 @@ describe('Test video change ownership - nominal', function () {
it('Should accept the same change ownership request without crashing', async function () { it('Should accept the same change ownership request without crashing', async function () {
this.timeout(10000) this.timeout(10000)
await changeVideoOwnership(server.url, firstUserAccessToken, server.video.id, secondUser.username) await changeVideoOwnership(servers[0].url, firstUserAccessToken, servers[0].video.id, secondUser.username)
}) })
it('Should not create multiple change ownership requests while one is waiting', async function () { it('Should not create multiple change ownership requests while one is waiting', async function () {
this.timeout(10000) this.timeout(10000)
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken) const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
expect(resSecondUser.body.total).to.equal(1) expect(resSecondUser.body.total).to.equal(1)
expect(resSecondUser.body.data).to.be.an('array') expect(resSecondUser.body.data).to.be.an('array')
@ -124,29 +127,29 @@ describe('Test video change ownership - nominal', function () {
it('Should not be possible to refuse the change of ownership from first user', async function () { it('Should not be possible to refuse the change of ownership from first user', async function () {
this.timeout(10000) this.timeout(10000)
await refuseChangeOwnership(server.url, firstUserAccessToken, lastRequestChangeOwnershipId, 403) await refuseChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, 403)
}) })
it('Should be possible to refuse the change of ownership from second user', async function () { it('Should be possible to refuse the change of ownership from second user', async function () {
this.timeout(10000) this.timeout(10000)
await refuseChangeOwnership(server.url, secondUserAccessToken, lastRequestChangeOwnershipId) await refuseChangeOwnership(servers[0].url, secondUserAccessToken, lastRequestChangeOwnershipId)
}) })
it('Should send a new request to change ownership of a video', async function () { it('Should send a new request to change ownership of a video', async function () {
this.timeout(15000) this.timeout(15000)
await changeVideoOwnership(server.url, firstUserAccessToken, server.video.id, secondUser.username) await changeVideoOwnership(servers[0].url, firstUserAccessToken, servers[0].video.id, secondUser.username)
}) })
it('Should return two requests to change ownership for the second user', async function () { it('Should return two requests to change ownership for the second user', async function () {
const resFirstUser = await getVideoChangeOwnershipList(server.url, firstUserAccessToken) const resFirstUser = await getVideoChangeOwnershipList(servers[0].url, firstUserAccessToken)
expect(resFirstUser.body.total).to.equal(0) expect(resFirstUser.body.total).to.equal(0)
expect(resFirstUser.body.data).to.be.an('array') expect(resFirstUser.body.data).to.be.an('array')
expect(resFirstUser.body.data.length).to.equal(0) expect(resFirstUser.body.data.length).to.equal(0)
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken) const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
expect(resSecondUser.body.total).to.equal(2) expect(resSecondUser.body.total).to.equal(2)
expect(resSecondUser.body.data).to.be.an('array') expect(resSecondUser.body.data).to.be.an('array')
@ -158,23 +161,37 @@ describe('Test video change ownership - nominal', function () {
it('Should not be possible to accept the change of ownership from first user', async function () { it('Should not be possible to accept the change of ownership from first user', async function () {
this.timeout(10000) this.timeout(10000)
const secondUserInformationResponse = await getMyUserInformation(server.url, secondUserAccessToken) const secondUserInformationResponse = await getMyUserInformation(servers[0].url, secondUserAccessToken)
const secondUserInformation: User = secondUserInformationResponse.body const secondUserInformation: User = secondUserInformationResponse.body
const channelId = secondUserInformation.videoChannels[0].id const channelId = secondUserInformation.videoChannels[0].id
await acceptChangeOwnership(server.url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, 403) await acceptChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, 403)
}) })
it('Should be possible to accept the change of ownership from second user', async function () { it('Should be possible to accept the change of ownership from second user', async function () {
this.timeout(10000) this.timeout(10000)
const secondUserInformationResponse = await getMyUserInformation(server.url, secondUserAccessToken) const secondUserInformationResponse = await getMyUserInformation(servers[0].url, secondUserAccessToken)
const secondUserInformation: User = secondUserInformationResponse.body const secondUserInformation: User = secondUserInformationResponse.body
const channelId = secondUserInformation.videoChannels[0].id const channelId = secondUserInformation.videoChannels[0].id
await acceptChangeOwnership(server.url, secondUserAccessToken, lastRequestChangeOwnershipId, channelId) await acceptChangeOwnership(servers[0].url, secondUserAccessToken, lastRequestChangeOwnershipId, channelId)
await waitJobs(servers)
})
it('Should have video channel updated', async function () {
for (const server of servers) {
const res = await getVideo(server.url, servers[0].video.uuid)
const video: VideoDetails = res.body
expect(video.name).to.equal('my super name')
expect(video.channel.displayName).to.equal('Main second channel')
expect(video.channel.name).to.equal('second_channel')
}
}) })
after(async function () { after(async function () {
killallServers([server]) killallServers(servers)
}) })
}) })