aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/accounts.ts4
-rw-r--r--server/controllers/api/users.ts5
-rw-r--r--server/lib/user.ts3
-rw-r--r--server/middlewares/validators/video-channels.ts18
-rw-r--r--server/models/video/video-channel.ts17
-rw-r--r--server/models/video/video.ts11
-rw-r--r--server/tests/api/check-params/video-channels.ts73
-rw-r--r--server/tests/api/check-params/videos.ts73
-rw-r--r--server/tests/api/users/users-multiple-servers.ts86
-rw-r--r--server/tests/api/videos/video-channels.ts33
-rw-r--r--server/tests/api/videos/video-nsfw.ts55
-rw-r--r--server/tests/utils/videos/video-channels.ts10
-rw-r--r--server/tests/utils/videos/videos.ts42
13 files changed, 317 insertions, 113 deletions
diff --git a/server/controllers/api/accounts.ts b/server/controllers/api/accounts.ts
index 04c5897c5..85987c912 100644
--- a/server/controllers/api/accounts.ts
+++ b/server/controllers/api/accounts.ts
@@ -126,7 +126,8 @@ async function addVideoChannelRetryWrapper (req: express.Request, res: express.R
126 const videoChannel = await retryTransactionWrapper(addVideoChannel, options) 126 const videoChannel = await retryTransactionWrapper(addVideoChannel, options)
127 return res.json({ 127 return res.json({
128 videoChannel: { 128 videoChannel: {
129 id: videoChannel.id 129 id: videoChannel.id,
130 uuid: videoChannel.Actor.uuid
130 } 131 }
131 }).end() 132 }).end()
132} 133}
@@ -233,7 +234,6 @@ async function listVideoChannelVideos (req: express.Request, res: express.Respon
233 return res.json(getFormattedObjects(resultList.data, resultList.total)) 234 return res.json(getFormattedObjects(resultList.data, resultList.total))
234} 235}
235 236
236
237async function listAccountVideos (req: express.Request, res: express.Response, next: express.NextFunction) { 237async function listAccountVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
238 const account: AccountModel = res.locals.account 238 const account: AccountModel = res.locals.account
239 239
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts
index 474329b58..dcc4ef196 100644
--- a/server/controllers/api/users.ts
+++ b/server/controllers/api/users.ts
@@ -185,7 +185,10 @@ async function createUserRetryWrapper (req: express.Request, res: express.Respon
185 return res.json({ 185 return res.json({
186 user: { 186 user: {
187 id: user.id, 187 id: user.id,
188 uuid: account.uuid 188 account: {
189 id: account.id,
190 uuid: account.Actor.uuid
191 }
189 } 192 }
190 }).end() 193 }).end()
191} 194}
diff --git a/server/lib/user.ts b/server/lib/user.ts
index 2ea7481e8..d019c4e71 100644
--- a/server/lib/user.ts
+++ b/server/lib/user.ts
@@ -5,6 +5,7 @@ import { AccountModel } from '../models/account/account'
5import { UserModel } from '../models/account/user' 5import { UserModel } from '../models/account/user'
6import { buildActorInstance, getAccountActivityPubUrl, setAsyncActorKeys } from './activitypub' 6import { buildActorInstance, getAccountActivityPubUrl, setAsyncActorKeys } from './activitypub'
7import { createVideoChannel } from './video-channel' 7import { createVideoChannel } from './video-channel'
8import { VideoChannelModel } from '../models/video/video-channel'
8 9
9async function createUserAccountAndChannel (userToCreate: UserModel, validateUser = true) { 10async function createUserAccountAndChannel (userToCreate: UserModel, validateUser = true) {
10 const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => { 11 const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => {
@@ -28,7 +29,7 @@ async function createUserAccountAndChannel (userToCreate: UserModel, validateUse
28 account.Actor = await setAsyncActorKeys(account.Actor) 29 account.Actor = await setAsyncActorKeys(account.Actor)
29 videoChannel.Actor = await setAsyncActorKeys(videoChannel.Actor) 30 videoChannel.Actor = await setAsyncActorKeys(videoChannel.Actor)
30 31
31 return { user, account, videoChannel } 32 return { user, account, videoChannel } as { user: UserModel, account: AccountModel, videoChannel: VideoChannelModel }
32} 33}
33 34
34async function createLocalAccountWithoutKeys ( 35async function createLocalAccountWithoutKeys (
diff --git a/server/middlewares/validators/video-channels.ts b/server/middlewares/validators/video-channels.ts
index e3a11a41b..9e6f459cf 100644
--- a/server/middlewares/validators/video-channels.ts
+++ b/server/middlewares/validators/video-channels.ts
@@ -11,6 +11,7 @@ import { logger } from '../../helpers/logger'
11import { UserModel } from '../../models/account/user' 11import { UserModel } from '../../models/account/user'
12import { VideoChannelModel } from '../../models/video/video-channel' 12import { VideoChannelModel } from '../../models/video/video-channel'
13import { areValidationErrors } from './utils' 13import { areValidationErrors } from './utils'
14import { AccountModel } from '../../models/account/account'
14 15
15const listVideoAccountChannelsValidator = [ 16const listVideoAccountChannelsValidator = [
16 param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'), 17 param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'),
@@ -53,6 +54,7 @@ const videoChannelsUpdateValidator = [
53 if (areValidationErrors(req, res)) return 54 if (areValidationErrors(req, res)) return
54 if (!await isAccountIdExist(req.params.accountId, res)) return 55 if (!await isAccountIdExist(req.params.accountId, res)) return
55 if (!await isVideoChannelExist(req.params.id, res)) return 56 if (!await isVideoChannelExist(req.params.id, res)) return
57 if (!checkAccountOwnsVideoChannel(res.locals.account, res.locals.videoChannel, res)) return
56 58
57 // We need to make additional checks 59 // We need to make additional checks
58 if (res.locals.videoChannel.Actor.isOwned() === false) { 60 if (res.locals.videoChannel.Actor.isOwned() === false) {
@@ -82,6 +84,7 @@ const videoChannelsRemoveValidator = [
82 if (!await isAccountIdExist(req.params.accountId, res)) return 84 if (!await isAccountIdExist(req.params.accountId, res)) return
83 if (!await isVideoChannelExist(req.params.id, res)) return 85 if (!await isVideoChannelExist(req.params.id, res)) return
84 86
87 if (!checkAccountOwnsVideoChannel(res.locals.account, res.locals.videoChannel, res)) return
85 // Check if the user who did the request is able to delete the video 88 // Check if the user who did the request is able to delete the video
86 if (!checkUserCanDeleteVideoChannel(res.locals.oauth.token.User, res.locals.videoChannel, res)) return 89 if (!checkUserCanDeleteVideoChannel(res.locals.oauth.token.User, res.locals.videoChannel, res)) return
87 if (!await checkVideoChannelIsNotTheLastOne(res)) return 90 if (!await checkVideoChannelIsNotTheLastOne(res)) return
@@ -98,10 +101,13 @@ const videoChannelsGetValidator = [
98 logger.debug('Checking videoChannelsGet parameters', { parameters: req.params }) 101 logger.debug('Checking videoChannelsGet parameters', { parameters: req.params })
99 102
100 if (areValidationErrors(req, res)) return 103 if (areValidationErrors(req, res)) return
104
101 // On some routes, accountId is optional (for example in the ActivityPub route) 105 // On some routes, accountId is optional (for example in the ActivityPub route)
102 if (req.params.accountId && !await isAccountIdExist(req.params.accountId, res)) return 106 if (req.params.accountId && !await isAccountIdExist(req.params.accountId, res)) return
103 if (!await isVideoChannelExist(req.params.id, res)) return 107 if (!await isVideoChannelExist(req.params.id, res)) return
104 108
109 if (res.locals.account && !checkAccountOwnsVideoChannel(res.locals.account, res.locals.videoChannel, res)) return
110
105 return next() 111 return next()
106 } 112 }
107] 113]
@@ -154,3 +160,15 @@ async function checkVideoChannelIsNotTheLastOne (res: express.Response) {
154 160
155 return true 161 return true
156} 162}
163
164function checkAccountOwnsVideoChannel (account: AccountModel, videoChannel: VideoChannelModel, res: express.Response) {
165 if (videoChannel.Account.id !== account.id) {
166 res.status(400)
167 .json({ error: 'This account does not own this video channel' })
168 .end()
169
170 return false
171 }
172
173 return true
174}
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index 40f3be7fe..4a50af265 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -108,7 +108,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
108 foreignKey: { 108 foreignKey: {
109 allowNull: false 109 allowNull: false
110 }, 110 },
111 onDelete: 'CASCADE' 111 hooks: true
112 }) 112 })
113 Account: AccountModel 113 Account: AccountModel
114 114
@@ -234,17 +234,26 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
234 234
235 toFormattedJSON (): VideoChannel { 235 toFormattedJSON (): VideoChannel {
236 const actor = this.Actor.toFormattedJSON() 236 const actor = this.Actor.toFormattedJSON()
237 const account = { 237 const videoChannel = {
238 id: this.id, 238 id: this.id,
239 displayName: this.name, 239 displayName: this.name,
240 description: this.description, 240 description: this.description,
241 support: this.support, 241 support: this.support,
242 isLocal: this.Actor.isOwned(), 242 isLocal: this.Actor.isOwned(),
243 createdAt: this.createdAt, 243 createdAt: this.createdAt,
244 updatedAt: this.updatedAt 244 updatedAt: this.updatedAt,
245 ownerAccount: undefined,
246 videos: undefined
247 }
248
249 if (this.Account) {
250 videoChannel.ownerAccount = {
251 id: this.Account.id,
252 uuid: this.Account.Actor.uuid
253 }
245 } 254 }
246 255
247 return Object.assign(actor, account) 256 return Object.assign(actor, videoChannel)
248 } 257 }
249 258
250 toActivityPubObject (): ActivityPubActor { 259 toActivityPubObject (): ActivityPubActor {
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 7ababbf23..f23fac2ab 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -430,7 +430,7 @@ export class VideoModel extends Model<VideoModel> {
430 foreignKey: { 430 foreignKey: {
431 allowNull: true 431 allowNull: true
432 }, 432 },
433 onDelete: 'cascade' 433 hooks: true
434 }) 434 })
435 VideoChannel: VideoChannelModel 435 VideoChannel: VideoChannelModel
436 436
@@ -510,10 +510,12 @@ export class VideoModel extends Model<VideoModel> {
510 return undefined 510 return undefined
511 } 511 }
512 512
513 @AfterDestroy 513 @BeforeDestroy
514 static async removeFilesAndSendDelete (instance: VideoModel) { 514 static async removeFilesAndSendDelete (instance: VideoModel) {
515 const tasks: Promise<any>[] = [] 515 const tasks: Promise<any>[] = []
516 516
517 logger.debug('Removing files of video %s.', instance.url)
518
517 tasks.push(instance.removeThumbnail()) 519 tasks.push(instance.removeThumbnail())
518 520
519 if (instance.isOwned()) { 521 if (instance.isOwned()) {
@@ -530,10 +532,13 @@ export class VideoModel extends Model<VideoModel> {
530 }) 532 })
531 } 533 }
532 534
533 return Promise.all(tasks) 535 // Do not wait video deletion because we could be in a transaction
536 Promise.all(tasks)
534 .catch(err => { 537 .catch(err => {
535 logger.error('Some errors when removing files of video %s in after destroy hook.', instance.uuid, { err }) 538 logger.error('Some errors when removing files of video %s in after destroy hook.', instance.uuid, { err })
536 }) 539 })
540
541 return undefined
537 } 542 }
538 543
539 static list () { 544 static list () {
diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts
index acb6bdd57..25b2dc9b9 100644
--- a/server/tests/api/check-params/video-channels.ts
+++ b/server/tests/api/check-params/video-channels.ts
@@ -7,7 +7,7 @@ import {
7 createUser, 7 createUser,
8 deleteVideoChannel, 8 deleteVideoChannel,
9 flushTests, 9 flushTests,
10 getAccountVideoChannelsList, 10 getAccountVideoChannelsList, getMyUserInformation,
11 getVideoChannelsList, 11 getVideoChannelsList,
12 immutableAssign, 12 immutableAssign,
13 killallServers, 13 killallServers,
@@ -21,6 +21,7 @@ import {
21} from '../../utils' 21} from '../../utils'
22import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 22import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
23import { getAccountsList } from '../../utils/users/accounts' 23import { getAccountsList } from '../../utils/users/accounts'
24import { User } from '../../../../shared/models/users'
24 25
25const expect = chai.expect 26const expect = chai.expect
26 27
@@ -29,6 +30,8 @@ describe('Test videos API validator', function () {
29 const accountPath = '/api/v1/accounts/' 30 const accountPath = '/api/v1/accounts/'
30 let server: ServerInfo 31 let server: ServerInfo
31 let accessTokenUser: string 32 let accessTokenUser: string
33 let accountUUID: string
34 let videoChannelUUID: string
32 35
33 // --------------------------------------------------------------- 36 // ---------------------------------------------------------------
34 37
@@ -45,8 +48,18 @@ describe('Test videos API validator', function () {
45 username: 'fake', 48 username: 'fake',
46 password: 'fake_password' 49 password: 'fake_password'
47 } 50 }
48 await createUser(server.url, server.accessToken, user.username, user.password) 51
49 accessTokenUser = await userLogin(server, user) 52 {
53 await createUser(server.url, server.accessToken, user.username, user.password)
54 accessTokenUser = await userLogin(server, user)
55 }
56
57 {
58 const res = await getMyUserInformation(server.url, server.accessToken)
59 const user: User = res.body
60 accountUUID = user.account.uuid
61 videoChannelUUID = user.videoChannels[0].uuid
62 }
50 }) 63 })
51 64
52 describe('When listing a video channels', function () { 65 describe('When listing a video channels', function () {
@@ -74,18 +87,15 @@ describe('Test videos API validator', function () {
74 }) 87 })
75 88
76 describe('When adding a video channel', function () { 89 describe('When adding a video channel', function () {
77 let path: string
78
79 const baseCorrectParams = { 90 const baseCorrectParams = {
80 name: 'hello', 91 name: 'hello',
81 description: 'super description', 92 description: 'super description',
82 support: 'super support text' 93 support: 'super support text'
83 } 94 }
95 let path: string
84 96
85 before(async function () { 97 before(async function () {
86 const res = await getAccountsList(server.url) 98 path = accountPath + accountUUID + '/video-channels'
87 const accountId = res.body.data[0].id
88 path = accountPath + accountId + '/video-channels'
89 }) 99 })
90 100
91 it('Should fail with a non authenticated user', async function () { 101 it('Should fail with a non authenticated user', async function () {
@@ -129,21 +139,14 @@ describe('Test videos API validator', function () {
129 }) 139 })
130 140
131 describe('When updating a video channel', function () { 141 describe('When updating a video channel', function () {
132 let path: string
133
134 const baseCorrectParams = { 142 const baseCorrectParams = {
135 name: 'hello', 143 name: 'hello',
136 description: 'super description' 144 description: 'super description'
137 } 145 }
146 let path: string
138 147
139 before(async function () { 148 before(async function () {
140 const res1 = await getVideoChannelsList(server.url, 0, 1) 149 path = accountPath + accountUUID + '/video-channels/' + videoChannelUUID
141 const videoChannelId = res1.body.data[0].id
142
143 const res2 = await getAccountsList(server.url)
144 const accountId = res2.body.data[0].id
145
146 path = accountPath + accountId + '/video-channels/' + videoChannelId
147 }) 150 })
148 151
149 it('Should fail with a non authenticated user', async function () { 152 it('Should fail with a non authenticated user', async function () {
@@ -194,16 +197,9 @@ describe('Test videos API validator', function () {
194 197
195 describe('When getting a video channel', function () { 198 describe('When getting a video channel', function () {
196 let basePath: string 199 let basePath: string
197 let videoChannelId: number
198 200
199 before(async function () { 201 before(async function () {
200 const res1 = await getVideoChannelsList(server.url, 0, 1) 202 basePath = accountPath + accountUUID + '/video-channels'
201 videoChannelId = res1.body.data[0].id
202
203 const res2 = await getAccountsList(server.url)
204 const accountId = res2.body.data[0].id
205
206 basePath = accountPath + accountId + '/video-channels'
207 }) 203 })
208 204
209 it('Should return the list of the video channels with nothing', async function () { 205 it('Should return the list of the video channels with nothing', async function () {
@@ -235,49 +231,38 @@ describe('Test videos API validator', function () {
235 it('Should succeed with the correct parameters', async function () { 231 it('Should succeed with the correct parameters', async function () {
236 await makeGetRequest({ 232 await makeGetRequest({
237 url: server.url, 233 url: server.url,
238 path: basePath + '/' + videoChannelId, 234 path: basePath + '/' + videoChannelUUID,
239 statusCodeExpected: 200 235 statusCodeExpected: 200
240 }) 236 })
241 }) 237 })
242 }) 238 })
243 239
244 describe('When deleting a video channel', function () { 240 describe('When deleting a video channel', function () {
245 let videoChannelId: number
246 let accountId: number
247
248 before(async function () {
249 const res1 = await getVideoChannelsList(server.url, 0, 1)
250 videoChannelId = res1.body.data[0].id
251
252 const res2 = await getAccountsList(server.url)
253 accountId = res2.body.data[0].id
254 })
255
256 it('Should fail with a non authenticated user', async function () { 241 it('Should fail with a non authenticated user', async function () {
257 await deleteVideoChannel(server.url, 'coucou', accountId, videoChannelId, 401) 242 await deleteVideoChannel(server.url, 'coucou', accountUUID, videoChannelUUID, 401)
258 }) 243 })
259 244
260 it('Should fail with another authenticated user', async function () { 245 it('Should fail with another authenticated user', async function () {
261 await deleteVideoChannel(server.url, accessTokenUser, accountId, videoChannelId, 403) 246 await deleteVideoChannel(server.url, accessTokenUser, accountUUID, videoChannelUUID, 403)
262 }) 247 })
263 248
264 it('Should fail with an unknown account id', async function () { 249 it('Should fail with an unknown account id', async function () {
265 await deleteVideoChannel(server.url, server.accessToken, 454554,videoChannelId, 404) 250 await deleteVideoChannel(server.url, server.accessToken, 454554,videoChannelUUID, 404)
266 }) 251 })
267 252
268 it('Should fail with an unknown video channel id', async function () { 253 it('Should fail with an unknown video channel id', async function () {
269 await deleteVideoChannel(server.url, server.accessToken, accountId,454554, 404) 254 await deleteVideoChannel(server.url, server.accessToken, accountUUID,454554, 404)
270 }) 255 })
271 256
272 it('Should succeed with the correct parameters', async function () { 257 it('Should succeed with the correct parameters', async function () {
273 await deleteVideoChannel(server.url, server.accessToken, accountId, videoChannelId) 258 await deleteVideoChannel(server.url, server.accessToken, accountUUID, videoChannelUUID)
274 }) 259 })
275 260
276 it('Should fail to delete the last user video channel', async function () { 261 it('Should fail to delete the last user video channel', async function () {
277 const res = await getVideoChannelsList(server.url, 0, 1) 262 const res = await getVideoChannelsList(server.url, 0, 1)
278 videoChannelId = res.body.data[0].id 263 const lastVideoChannelUUID = res.body.data[0].uuid
279 264
280 await deleteVideoChannel(server.url, server.accessToken, accountId, videoChannelId, 409) 265 await deleteVideoChannel(server.url, server.accessToken, accountUUID, lastVideoChannelUUID, 409)
281 }) 266 })
282 }) 267 })
283 268
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index da41f515b..850ad12e0 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -10,6 +10,7 @@ import {
10 makeGetRequest, makeUploadRequest, makePutBodyRequest, removeVideo, runServer, ServerInfo, setAccessTokensToServers, userLogin 10 makeGetRequest, makeUploadRequest, makePutBodyRequest, removeVideo, runServer, ServerInfo, setAccessTokensToServers, userLogin
11} from '../../utils' 11} from '../../utils'
12import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 12import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
13import { getAccountsList } from '../../utils/users/accounts'
13 14
14const expect = chai.expect 15const expect = chai.expect
15 16
@@ -17,7 +18,9 @@ describe('Test videos API validator', function () {
17 const path = '/api/v1/videos/' 18 const path = '/api/v1/videos/'
18 let server: ServerInfo 19 let server: ServerInfo
19 let userAccessToken = '' 20 let userAccessToken = ''
21 let accountUUID: string
20 let channelId: number 22 let channelId: number
23 let channelUUID: string
21 let videoId 24 let videoId
22 25
23 // --------------------------------------------------------------- 26 // ---------------------------------------------------------------
@@ -36,8 +39,12 @@ describe('Test videos API validator', function () {
36 await createUser(server.url, server.accessToken, username, password) 39 await createUser(server.url, server.accessToken, username, password)
37 userAccessToken = await userLogin(server, { username, password }) 40 userAccessToken = await userLogin(server, { username, password })
38 41
39 const res = await getMyUserInformation(server.url, server.accessToken) 42 {
40 channelId = res.body.videoChannels[0].id 43 const res = await getMyUserInformation(server.url, server.accessToken)
44 channelId = res.body.videoChannels[ 0 ].id
45 channelUUID = res.body.videoChannels[ 0 ].uuid
46 accountUUID = res.body.account.uuid
47 }
41 }) 48 })
42 49
43 describe('When listing a video', function () { 50 describe('When listing a video', function () {
@@ -52,6 +59,10 @@ describe('Test videos API validator', function () {
52 it('Should fail with an incorrect sort', async function () { 59 it('Should fail with an incorrect sort', async function () {
53 await checkBadSortPagination(server.url, path) 60 await checkBadSortPagination(server.url, path)
54 }) 61 })
62
63 it('Should success with the correct parameters', async function () {
64 await makeGetRequest({ url: server.url, path, statusCodeExpected: 200 })
65 })
55 }) 66 })
56 67
57 describe('When searching a video', function () { 68 describe('When searching a video', function () {
@@ -75,6 +86,10 @@ describe('Test videos API validator', function () {
75 it('Should fail with an incorrect sort', async function () { 86 it('Should fail with an incorrect sort', async function () {
76 await checkBadSortPagination(server.url, join(path, 'search', 'test')) 87 await checkBadSortPagination(server.url, join(path, 'search', 'test'))
77 }) 88 })
89
90 it('Should success with the correct parameters', async function () {
91 await makeGetRequest({ url: server.url, path, statusCodeExpected: 200 })
92 })
78 }) 93 })
79 94
80 describe('When listing my videos', function () { 95 describe('When listing my videos', function () {
@@ -91,6 +106,58 @@ describe('Test videos API validator', function () {
91 it('Should fail with an incorrect sort', async function () { 106 it('Should fail with an incorrect sort', async function () {
92 await checkBadSortPagination(server.url, path, server.accessToken) 107 await checkBadSortPagination(server.url, path, server.accessToken)
93 }) 108 })
109
110 it('Should success with the correct parameters', async function () {
111 await makeGetRequest({ url: server.url, token: server.accessToken, path, statusCodeExpected: 200 })
112 })
113 })
114
115 describe('When listing account videos', function () {
116 let path: string
117
118 before(async function () {
119 path = '/api/v1/accounts/' + accountUUID + '/videos'
120 })
121
122 it('Should fail with a bad start pagination', async function () {
123 await checkBadStartPagination(server.url, path, server.accessToken)
124 })
125
126 it('Should fail with a bad count pagination', async function () {
127 await checkBadCountPagination(server.url, path, server.accessToken)
128 })
129
130 it('Should fail with an incorrect sort', async function () {
131 await checkBadSortPagination(server.url, path, server.accessToken)
132 })
133
134 it('Should success with the correct parameters', async function () {
135 await makeGetRequest({ url: server.url, path, statusCodeExpected: 200 })
136 })
137 })
138
139 describe('When listing video channel videos', function () {
140 let path: string
141
142 before(async function () {
143 path = '/api/v1/accounts/' + accountUUID + '/video-channels/' + channelUUID + '/videos'
144 })
145
146 it('Should fail with a bad start pagination', async function () {
147 await checkBadStartPagination(server.url, path, server.accessToken)
148 })
149
150 it('Should fail with a bad count pagination', async function () {
151 await checkBadCountPagination(server.url, path, server.accessToken)
152 })
153
154 it('Should fail with an incorrect sort', async function () {
155 await checkBadSortPagination(server.url, path, server.accessToken)
156 })
157
158 it('Should success with the correct parameters', async function () {
159 await makeGetRequest({ url: server.url, path, statusCodeExpected: 200 })
160 })
94 }) 161 })
95 162
96 describe('When adding a video', function () { 163 describe('When adding a video', function () {
@@ -112,7 +179,7 @@ describe('Test videos API validator', function () {
112 support: 'my super support text', 179 support: 'my super support text',
113 tags: [ 'tag1', 'tag2' ], 180 tags: [ 'tag1', 'tag2' ],
114 privacy: VideoPrivacy.PUBLIC, 181 privacy: VideoPrivacy.PUBLIC,
115 channelId 182 channelId: channelId
116 } 183 }
117 }) 184 })
118 185
diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts
index bb458f7a5..a7f3aa8d3 100644
--- a/server/tests/api/users/users-multiple-servers.ts
+++ b/server/tests/api/users/users-multiple-servers.ts
@@ -4,22 +4,33 @@ import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { Account } from '../../../../shared/models/actors' 5import { Account } from '../../../../shared/models/actors'
6import { 6import {
7 checkVideoFilesWereRemoved, createUser, doubleFollow, flushAndRunMultipleServers, removeUser, updateMyUser, userLogin, 7 checkVideoFilesWereRemoved,
8 createUser,
9 doubleFollow,
10 flushAndRunMultipleServers,
11 getAccountVideos,
12 getVideoChannelsList,
13 removeUser,
14 updateMyUser,
15 userLogin,
8 wait 16 wait
9} from '../../utils' 17} from '../../utils'
10import { flushTests, getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../utils/index' 18import { flushTests, getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../utils/index'
11import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../utils/users/accounts' 19import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../utils/users/accounts'
12import { setAccessTokensToServers } from '../../utils/users/login' 20import { setAccessTokensToServers } from '../../utils/users/login'
21import { User } from '../../../../shared/models/users'
22import { VideoChannel } from '../../../../shared/models/videos'
13 23
14const expect = chai.expect 24const expect = chai.expect
15 25
16describe('Test users with multiple servers', function () { 26describe('Test users with multiple servers', function () {
17 let servers: ServerInfo[] = [] 27 let servers: ServerInfo[] = []
18 let user 28 let user: User
19 let userUUID 29 let userAccountUUID: string
20 let userId 30 let userVideoChannelUUID: string
21 let videoUUID 31 let userId: number
22 let userAccessToken 32 let videoUUID: string
33 let userAccessToken: string
23 34
24 before(async function () { 35 before(async function () {
25 this.timeout(120000) 36 this.timeout(120000)
@@ -39,17 +50,28 @@ describe('Test users with multiple servers', function () {
39 // The root user of server 1 is propagated to servers 2 and 3 50 // The root user of server 1 is propagated to servers 2 and 3
40 await uploadVideo(servers[0].url, servers[0].accessToken, {}) 51 await uploadVideo(servers[0].url, servers[0].accessToken, {})
41 52
42 const user = { 53 {
43 username: 'user1', 54 const user = {
44 password: 'password' 55 username: 'user1',
56 password: 'password'
57 }
58 const res = await createUser(servers[ 0 ].url, servers[ 0 ].accessToken, user.username, user.password)
59 userAccountUUID = res.body.user.account.uuid
60 userId = res.body.user.id
61
62 userAccessToken = await userLogin(servers[ 0 ], user)
63 }
64
65 {
66 const res = await getMyUserInformation(servers[ 0 ].url, servers[ 0 ].accessToken)
67 const user: User = res.body
68 userVideoChannelUUID = user.videoChannels[0].uuid
45 } 69 }
46 const resUser = await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
47 userUUID = resUser.body.user.uuid
48 userId = resUser.body.user.id
49 userAccessToken = await userLogin(servers[0], user)
50 70
51 const resVideo = await uploadVideo(servers[0].url, userAccessToken, {}) 71 {
52 videoUUID = resVideo.body.uuid 72 const resVideo = await uploadVideo(servers[ 0 ].url, userAccessToken, {})
73 videoUUID = resVideo.body.video.uuid
74 }
53 75
54 await wait(5000) 76 await wait(5000)
55 }) 77 })
@@ -106,14 +128,31 @@ describe('Test users with multiple servers', function () {
106 } 128 }
107 }) 129 })
108 130
131 it('Should list account videos', async function () {
132 for (const server of servers) {
133 const res = await getAccountVideos(server.url, server.accessToken, userAccountUUID, 0, 5)
134
135 expect(res.body.total).to.equal(1)
136 expect(res.body.data).to.be.an('array')
137 expect(res.body.data).to.have.lengthOf(1)
138 expect(res.body.data[0].uuid).to.equal(videoUUID)
139 }
140 })
141
109 it('Should remove the user', async function () { 142 it('Should remove the user', async function () {
110 this.timeout(10000) 143 this.timeout(10000)
111 144
112 for (const server of servers) { 145 for (const server of servers) {
113 const resAccounts = await getAccountsList(server.url, '-createdAt') 146 const resAccounts = await getAccountsList(server.url, '-createdAt')
114 147
115 const userServer1List = resAccounts.body.data.find(a => a.name === 'user1' && a.host === 'localhost:9001') as Account 148 const accountDeleted = resAccounts.body.data.find(a => a.name === 'user1' && a.host === 'localhost:9001') as Account
116 expect(userServer1List).not.to.be.undefined 149 expect(accountDeleted).not.to.be.undefined
150
151 const resVideoChannels = await getVideoChannelsList(server.url, 0, 10)
152 const videoChannelDeleted = resVideoChannels.body.data.find(a => {
153 return a.displayName === 'Default user1 channel' && a.host === 'localhost:9001'
154 }) as VideoChannel
155 expect(videoChannelDeleted).not.to.be.undefined
117 } 156 }
118 157
119 await removeUser(servers[0].url, userId, servers[0].accessToken) 158 await removeUser(servers[0].url, userId, servers[0].accessToken)
@@ -123,14 +162,21 @@ describe('Test users with multiple servers', function () {
123 for (const server of servers) { 162 for (const server of servers) {
124 const resAccounts = await getAccountsList(server.url, '-createdAt') 163 const resAccounts = await getAccountsList(server.url, '-createdAt')
125 164
126 const userServer1List = resAccounts.body.data.find(a => a.name === 'user1' && a.host === 'localhost:9001') as Account 165 const accountDeleted = resAccounts.body.data.find(a => a.name === 'user1' && a.host === 'localhost:9001') as Account
127 expect(userServer1List).to.be.undefined 166 expect(accountDeleted).to.be.undefined
167
168 const resVideoChannels = await getVideoChannelsList(server.url, 0, 10)
169 const videoChannelDeleted = resVideoChannels.body.data.find(a => {
170 return a.name === 'Default user1 channel' && a.host === 'localhost:9001'
171 }) as VideoChannel
172 expect(videoChannelDeleted).to.be.undefined
128 } 173 }
129 }) 174 })
130 175
131 it('Should not have actor files', async () => { 176 it('Should not have actor files', async () => {
132 for (const server of servers) { 177 for (const server of servers) {
133 await checkActorFilesWereRemoved(userUUID, server.serverNumber) 178 await checkActorFilesWereRemoved(userAccountUUID, server.serverNumber)
179 await checkActorFilesWereRemoved(userVideoChannelUUID, server.serverNumber)
134 } 180 }
135 }) 181 })
136 182
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts
index a7552a83a..04e7b8c6a 100644
--- a/server/tests/api/videos/video-channels.ts
+++ b/server/tests/api/videos/video-channels.ts
@@ -3,7 +3,7 @@
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { User } from '../../../../shared/index' 5import { User } from '../../../../shared/index'
6import { doubleFollow, flushAndRunMultipleServers, uploadVideo, wait } from '../../utils' 6import { doubleFollow, flushAndRunMultipleServers, getVideoChannelVideos, uploadVideo, wait } from '../../utils'
7import { 7import {
8 addVideoChannel, 8 addVideoChannel,
9 deleteVideoChannel, 9 deleteVideoChannel,
@@ -24,8 +24,9 @@ const expect = chai.expect
24describe('Test video channels', function () { 24describe('Test video channels', function () {
25 let servers: ServerInfo[] 25 let servers: ServerInfo[]
26 let userInfo: User 26 let userInfo: User
27 let accountId: number 27 let accountUUID: string
28 let videoChannelId: number 28 let videoChannelId: number
29 let videoChannelUUID: string
29 30
30 before(async function () { 31 before(async function () {
31 this.timeout(30000) 32 this.timeout(30000)
@@ -38,8 +39,9 @@ describe('Test video channels', function () {
38 await doubleFollow(servers[0], servers[1]) 39 await doubleFollow(servers[0], servers[1])
39 40
40 { 41 {
41 const res = await getAccountsList(servers[0].url) 42 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
42 accountId = res.body.data[0].id 43 const user: User = res.body
44 accountUUID = user.account.uuid
43 } 45 }
44 46
45 await wait(5000) 47 await wait(5000)
@@ -61,11 +63,12 @@ describe('Test video channels', function () {
61 description: 'super video channel description', 63 description: 'super video channel description',
62 support: 'super video channel support text' 64 support: 'super video channel support text'
63 } 65 }
64 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, accountId, videoChannel) 66 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, accountUUID, videoChannel)
65 videoChannelId = res.body.videoChannel.id 67 videoChannelId = res.body.videoChannel.id
68 videoChannelUUID = res.body.videoChannel.uuid
66 69
67 // The channel is 1 is propagated to servers 2 70 // The channel is 1 is propagated to servers 2
68 await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: videoChannelId }) 71 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'my video name', channelId: videoChannelId })
69 72
70 await wait(3000) 73 await wait(3000)
71 }) 74 })
@@ -127,7 +130,7 @@ describe('Test video channels', function () {
127 support: 'video channel support text updated' 130 support: 'video channel support text updated'
128 } 131 }
129 132
130 await updateVideoChannel(servers[0].url, servers[0].accessToken, accountId, videoChannelId, videoChannelAttributes) 133 await updateVideoChannel(servers[0].url, servers[0].accessToken, accountUUID, videoChannelId, videoChannelAttributes)
131 134
132 await wait(3000) 135 await wait(3000)
133 }) 136 })
@@ -146,7 +149,7 @@ describe('Test video channels', function () {
146 }) 149 })
147 150
148 it('Should get video channel', async function () { 151 it('Should get video channel', async function () {
149 const res = await getVideoChannel(servers[0].url, accountId, videoChannelId) 152 const res = await getVideoChannel(servers[0].url, accountUUID, videoChannelId)
150 153
151 const videoChannel = res.body 154 const videoChannel = res.body
152 expect(videoChannel.displayName).to.equal('video channel updated') 155 expect(videoChannel.displayName).to.equal('video channel updated')
@@ -154,8 +157,20 @@ describe('Test video channels', function () {
154 expect(videoChannel.support).to.equal('video channel support text updated') 157 expect(videoChannel.support).to.equal('video channel support text updated')
155 }) 158 })
156 159
160 it('Should list the video channel videos', async function () {
161 this.timeout(10000)
162
163 for (const server of servers) {
164 const res = await getVideoChannelVideos(server.url, server.accessToken, accountUUID, videoChannelUUID, 0, 5)
165 expect(res.body.total).to.equal(1)
166 expect(res.body.data).to.be.an('array')
167 expect(res.body.data).to.have.lengthOf(1)
168 expect(res.body.data[0].name).to.equal('my video name')
169 }
170 })
171
157 it('Should delete video channel', async function () { 172 it('Should delete video channel', async function () {
158 await deleteVideoChannel(servers[0].url, servers[0].accessToken, accountId, videoChannelId) 173 await deleteVideoChannel(servers[0].url, servers[0].accessToken, accountUUID, videoChannelId)
159 }) 174 })
160 175
161 it('Should have video channel deleted', async function () { 176 it('Should have video channel deleted', async function () {
diff --git a/server/tests/api/videos/video-nsfw.ts b/server/tests/api/videos/video-nsfw.ts
index 4e5ab11ce..8901f38f9 100644
--- a/server/tests/api/videos/video-nsfw.ts
+++ b/server/tests/api/videos/video-nsfw.ts
@@ -7,8 +7,9 @@ import { userLogin } from '../../utils/users/login'
7import { createUser } from '../../utils/users/users' 7import { createUser } from '../../utils/users/users'
8import { getMyVideos } from '../../utils/videos/videos' 8import { getMyVideos } from '../../utils/videos/videos'
9import { 9import {
10 getAccountVideos,
10 getConfig, getCustomConfig, 11 getConfig, getCustomConfig,
11 getMyUserInformation, 12 getMyUserInformation, getVideoChannelVideos,
12 getVideosListWithToken, 13 getVideosListWithToken,
13 runServer, 14 runServer,
14 searchVideo, 15 searchVideo,
@@ -17,6 +18,7 @@ import {
17} from '../../utils' 18} from '../../utils'
18import { ServerConfig } from '../../../../shared/models' 19import { ServerConfig } from '../../../../shared/models'
19import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 20import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
21import { User } from '../../../../shared/models/users'
20 22
21const expect = chai.expect 23const expect = chai.expect
22 24
@@ -25,6 +27,31 @@ describe('Test video NSFW policy', function () {
25 let userAccessToken: string 27 let userAccessToken: string
26 let customConfig: CustomConfig 28 let customConfig: CustomConfig
27 29
30 function getVideosFunctions (token?: string) {
31 return getMyUserInformation(server.url, server.accessToken)
32 .then(res => {
33 const user: User = res.body
34 const videoChannelUUID = user.videoChannels[0].uuid
35 const accountUUID = user.account.uuid
36
37 if (token) {
38 return Promise.all([
39 getVideosListWithToken(server.url, token),
40 searchVideoWithToken(server.url, 'n', token),
41 getAccountVideos(server.url, token, accountUUID, 0, 5),
42 getVideoChannelVideos(server.url, token, accountUUID, videoChannelUUID, 0, 5)
43 ])
44 }
45
46 return Promise.all([
47 getVideosList(server.url),
48 searchVideo(server.url, 'n'),
49 getAccountVideos(server.url, undefined, accountUUID, 0, 5),
50 getVideoChannelVideos(server.url, undefined, accountUUID, videoChannelUUID, 0, 5)
51 ])
52 })
53 }
54
28 before(async function () { 55 before(async function () {
29 this.timeout(50000) 56 this.timeout(50000)
30 57
@@ -56,7 +83,7 @@ describe('Test video NSFW policy', function () {
56 const serverConfig: ServerConfig = resConfig.body 83 const serverConfig: ServerConfig = resConfig.body
57 expect(serverConfig.instance.defaultNSFWPolicy).to.equal('display') 84 expect(serverConfig.instance.defaultNSFWPolicy).to.equal('display')
58 85
59 for (const res of [ await getVideosList(server.url), await searchVideo(server.url, 'n') ]) { 86 for (const res of await getVideosFunctions()) {
60 expect(res.body.total).to.equal(2) 87 expect(res.body.total).to.equal(2)
61 88
62 const videos = res.body.data 89 const videos = res.body.data
@@ -74,7 +101,7 @@ describe('Test video NSFW policy', function () {
74 const serverConfig: ServerConfig = resConfig.body 101 const serverConfig: ServerConfig = resConfig.body
75 expect(serverConfig.instance.defaultNSFWPolicy).to.equal('do_not_list') 102 expect(serverConfig.instance.defaultNSFWPolicy).to.equal('do_not_list')
76 103
77 for (const res of [ await getVideosList(server.url), await searchVideo(server.url, 'n') ]) { 104 for (const res of await getVideosFunctions()) {
78 expect(res.body.total).to.equal(1) 105 expect(res.body.total).to.equal(1)
79 106
80 const videos = res.body.data 107 const videos = res.body.data
@@ -91,7 +118,7 @@ describe('Test video NSFW policy', function () {
91 const serverConfig: ServerConfig = resConfig.body 118 const serverConfig: ServerConfig = resConfig.body
92 expect(serverConfig.instance.defaultNSFWPolicy).to.equal('blur') 119 expect(serverConfig.instance.defaultNSFWPolicy).to.equal('blur')
93 120
94 for (const res of [ await getVideosList(server.url), await searchVideo(server.url, 'n') ]) { 121 for (const res of await getVideosFunctions()) {
95 expect(res.body.total).to.equal(2) 122 expect(res.body.total).to.equal(2)
96 123
97 const videos = res.body.data 124 const videos = res.body.data
@@ -118,12 +145,7 @@ describe('Test video NSFW policy', function () {
118 }) 145 })
119 146
120 it('Should display NSFW videos with blur user NSFW policy', async function () { 147 it('Should display NSFW videos with blur user NSFW policy', async function () {
121 const results = [ 148 for (const res of await getVideosFunctions(userAccessToken)) {
122 await getVideosListWithToken(server.url, userAccessToken),
123 await searchVideoWithToken(server.url, 'n', userAccessToken)
124 ]
125
126 for (const res of results) {
127 expect(res.body.total).to.equal(2) 149 expect(res.body.total).to.equal(2)
128 150
129 const videos = res.body.data 151 const videos = res.body.data
@@ -140,12 +162,7 @@ describe('Test video NSFW policy', function () {
140 nsfwPolicy: 'display' 162 nsfwPolicy: 'display'
141 }) 163 })
142 164
143 const results = [ 165 for (const res of await getVideosFunctions(server.accessToken)) {
144 await getVideosListWithToken(server.url, server.accessToken),
145 await searchVideoWithToken(server.url, 'n', server.accessToken)
146 ]
147
148 for (const res of results) {
149 expect(res.body.total).to.equal(2) 166 expect(res.body.total).to.equal(2)
150 167
151 const videos = res.body.data 168 const videos = res.body.data
@@ -162,11 +179,7 @@ describe('Test video NSFW policy', function () {
162 nsfwPolicy: 'do_not_list' 179 nsfwPolicy: 'do_not_list'
163 }) 180 })
164 181
165 const results = [ 182 for (const res of await getVideosFunctions(server.accessToken)) {
166 await getVideosListWithToken(server.url, server.accessToken),
167 await searchVideoWithToken(server.url, 'n', server.accessToken)
168 ]
169 for (const res of results) {
170 expect(res.body.total).to.equal(1) 183 expect(res.body.total).to.equal(1)
171 184
172 const videos = res.body.data 185 const videos = res.body.data
diff --git a/server/tests/utils/videos/video-channels.ts b/server/tests/utils/videos/video-channels.ts
index cfc541431..0b4fa89b7 100644
--- a/server/tests/utils/videos/video-channels.ts
+++ b/server/tests/utils/videos/video-channels.ts
@@ -34,7 +34,7 @@ function getAccountVideoChannelsList (url: string, accountId: number | string, s
34function addVideoChannel ( 34function addVideoChannel (
35 url: string, 35 url: string,
36 token: string, 36 token: string,
37 accountId: number, 37 accountId: number | string,
38 videoChannelAttributesArg: VideoChannelAttributes, 38 videoChannelAttributesArg: VideoChannelAttributes,
39 expectedStatus = 200 39 expectedStatus = 200
40) { 40) {
@@ -59,8 +59,8 @@ function addVideoChannel (
59function updateVideoChannel ( 59function updateVideoChannel (
60 url: string, 60 url: string,
61 token: string, 61 token: string,
62 accountId: number, 62 accountId: number | string,
63 channelId: number, 63 channelId: number | string,
64 attributes: VideoChannelAttributes, 64 attributes: VideoChannelAttributes,
65 expectedStatus = 204 65 expectedStatus = 204
66) { 66) {
@@ -79,7 +79,7 @@ function updateVideoChannel (
79 .expect(expectedStatus) 79 .expect(expectedStatus)
80} 80}
81 81
82function deleteVideoChannel (url: string, token: string, accountId: number, channelId: number, expectedStatus = 204) { 82function deleteVideoChannel (url: string, token: string, accountId: number | string, channelId: number | string, expectedStatus = 204) {
83 const path = '/api/v1/accounts/' + accountId + '/video-channels/' + channelId 83 const path = '/api/v1/accounts/' + accountId + '/video-channels/' + channelId
84 84
85 return request(url) 85 return request(url)
@@ -89,7 +89,7 @@ function deleteVideoChannel (url: string, token: string, accountId: number, chan
89 .expect(expectedStatus) 89 .expect(expectedStatus)
90} 90}
91 91
92function getVideoChannel (url: string, accountId: number, channelId: number) { 92function getVideoChannel (url: string, accountId: number | string, channelId: number | string) {
93 const path = '/api/v1/accounts/' + accountId + '/video-channels/' + channelId 93 const path = '/api/v1/accounts/' + accountId + '/video-channels/' + channelId
94 94
95 return request(url) 95 return request(url)
diff --git a/server/tests/utils/videos/videos.ts b/server/tests/utils/videos/videos.ts
index 943c85cc7..2ba3a860b 100644
--- a/server/tests/utils/videos/videos.ts
+++ b/server/tests/utils/videos/videos.ts
@@ -167,6 +167,46 @@ function getMyVideos (url: string, accessToken: string, start: number, count: nu
167 .expect('Content-Type', /json/) 167 .expect('Content-Type', /json/)
168} 168}
169 169
170function getAccountVideos (url: string, accessToken: string, accountId: number | string, start: number, count: number, sort?: string) {
171 const path = '/api/v1/accounts/' + accountId + '/videos'
172
173 return makeGetRequest({
174 url,
175 path,
176 query: {
177 start,
178 count,
179 sort
180 },
181 token: accessToken,
182 statusCodeExpected: 200
183 })
184}
185
186function getVideoChannelVideos (
187 url: string,
188 accessToken: string,
189 accountId: number | string,
190 videoChannelId: number | string,
191 start: number,
192 count: number,
193 sort?: string
194) {
195 const path = '/api/v1/accounts/' + accountId + '/video-channels/' + videoChannelId + '/videos'
196
197 return makeGetRequest({
198 url,
199 path,
200 query: {
201 start,
202 count,
203 sort
204 },
205 token: accessToken,
206 statusCodeExpected: 200
207 })
208}
209
170function getVideosListPagination (url: string, start: number, count: number, sort?: string) { 210function getVideosListPagination (url: string, start: number, count: number, sort?: string) {
171 const path = '/api/v1/videos' 211 const path = '/api/v1/videos'
172 212
@@ -514,6 +554,8 @@ export {
514 getVideoPrivacies, 554 getVideoPrivacies,
515 getVideoLanguages, 555 getVideoLanguages,
516 getMyVideos, 556 getMyVideos,
557 getAccountVideos,
558 getVideoChannelVideos,
517 searchVideoWithToken, 559 searchVideoWithToken,
518 getVideo, 560 getVideo,
519 getVideoWithToken, 561 getVideoWithToken,