Add tests and fix bugs for video privacy

This commit is contained in:
Chocobozzz 2017-10-31 15:20:35 +01:00
parent fd45e8f43c
commit 11474c3cd9
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
8 changed files with 438 additions and 402 deletions

View File

@ -171,7 +171,7 @@ async function getUserInformation (req: express.Request, res: express.Response,
} }
function getUser (req: express.Request, res: express.Response, next: express.NextFunction) { function getUser (req: express.Request, res: express.Response, next: express.NextFunction) {
return res.json(res.locals.oauth.token.User.toFormattedJSON()) return res.json(res.locals.user.toFormattedJSON())
} }
async function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) { async function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {

View File

@ -24,6 +24,7 @@ import {
isVideoPrivacyValid isVideoPrivacyValid
} from '../../helpers' } from '../../helpers'
import { UserRight, VideoPrivacy } from '../../../shared' import { UserRight, VideoPrivacy } from '../../../shared'
import { authenticate } from '../oauth'
const videosAddValidator = [ const videosAddValidator = [
body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage( body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage(
@ -112,7 +113,7 @@ const videosUpdateValidator = [
body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'), body('licence').optional().custom(isVideoLicenceValid).withMessage('Should have a valid licence'),
body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'), body('language').optional().custom(isVideoLanguageValid).withMessage('Should have a valid language'),
body('nsfw').optional().custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'), body('nsfw').optional().custom(isVideoNSFWValid).withMessage('Should have a valid NSFW attribute'),
body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'), body('privacy').optional().custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'),
body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'), body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'),
body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'),
@ -155,7 +156,22 @@ const videosGetValidator = [
logger.debug('Checking videosGet parameters', { parameters: req.params }) logger.debug('Checking videosGet parameters', { parameters: req.params })
checkErrors(req, res, () => { checkErrors(req, res, () => {
checkVideoExists(req.params.id, res, next) checkVideoExists(req.params.id, res, () => {
const video = res.locals.video
// Video is not private, anyone can access it
if (video.privacy !== VideoPrivacy.PRIVATE) return next()
authenticate(req, res, () => {
if (video.VideoChannel.Author.userId !== res.locals.oauth.token.User.id) {
return res.status(403)
.json({ error: 'Cannot get this private video of another user' })
.end()
}
next()
})
})
}) })
} }
] ]
@ -232,28 +248,23 @@ export {
function checkUserCanDeleteVideo (userId: number, res: express.Response, callback: () => void) { function checkUserCanDeleteVideo (userId: number, res: express.Response, callback: () => void) {
// Retrieve the user who did the request // Retrieve the user who did the request
db.User.loadById(userId) if (res.locals.video.isOwned() === false) {
.then(user => { return res.status(403)
if (res.locals.video.isOwned() === false) { .json({ error: 'Cannot remove video of another pod, blacklist it' })
return res.status(403) .end()
.json({ error: 'Cannot remove video of another pod, blacklist it' }) }
.end()
}
// Check if the user can delete the video // Check if the user can delete the video
// The user can delete it if s/he is an admin // The user can delete it if s/he is an admin
// Or if s/he is the video's author // Or if s/he is the video's author
if (user.hasRight(UserRight.REMOVE_ANY_VIDEO) === false && res.locals.video.Author.userId !== res.locals.oauth.token.User.id) { const author = res.locals.video.VideoChannel.Author
return res.status(403) const user = res.locals.oauth.token.User
.json({ error: 'Cannot remove video of another user' }) if (user.hasRight(UserRight.REMOVE_ANY_VIDEO) === false && author.userId !== user.id) {
.end() return res.status(403)
} .json({ error: 'Cannot remove video of another user' })
.end()
}
// If we reach this comment, we can delete the video // If we reach this comment, we can delete the video
callback() callback()
})
.catch(err => {
logger.error('Error in video request validator.', err)
return res.sendStatus(500)
})
} }

View File

@ -19,12 +19,46 @@ import {
createUser, createUser,
getUserAccessToken getUserAccessToken
} from '../../utils' } from '../../utils'
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
describe('Test videos API validator', function () { describe('Test videos API validator', function () {
const path = '/api/v1/videos/' const path = '/api/v1/videos/'
let server: ServerInfo let server: ServerInfo
let channelId: number let channelId: number
function getCompleteVideoUploadAttributes () {
return {
name: 'my super name',
category: 5,
licence: 1,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
privacy: VideoPrivacy.PUBLIC,
channelId
}
}
function getCompleteVideoUpdateAttributes () {
return {
name: 'my super name',
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
privacy: VideoPrivacy.PUBLIC,
tags: [ 'tag1', 'tag2' ]
}
}
function getVideoUploadAttaches () {
return {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
}
// --------------------------------------------------------------- // ---------------------------------------------------------------
before(async function () { before(async function () {
@ -99,6 +133,37 @@ describe('Test videos API validator', function () {
}) })
}) })
describe('When listing my videos', function () {
const path = '/api/v1/users/me/videos'
it('Should fail with a bad start pagination', async function () {
await request(server.url)
.get(path)
.set('Authorization', 'Bearer ' + server.accessToken)
.query({ start: 'hello' })
.set('Accept', 'application/json')
.expect(400)
})
it('Should fail with a bad count pagination', async function () {
await request(server.url)
.get(path)
.set('Authorization', 'Bearer ' + server.accessToken)
.query({ count: 'hello' })
.set('Accept', 'application/json')
.expect(400)
})
it('Should fail with an incorrect sort', async function () {
await request(server.url)
.get(path)
.set('Authorization', 'Bearer ' + server.accessToken)
.query({ sort: 'hello' })
.set('Accept', 'application/json')
.expect(400)
})
})
describe('When adding a video', function () { describe('When adding a video', function () {
it('Should fail with nothing', async function () { it('Should fail with nothing', async function () {
const fields = {} const fields = {}
@ -107,219 +172,108 @@ describe('Test videos API validator', function () {
}) })
it('Should fail without name', async function () { it('Should fail without name', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
category: 5, delete fields.name
licence: 1,
language: 6, const attaches = getVideoUploadAttaches()
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a long name', async function () { it('Should fail with a long name', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'My very very very very very very very very very very very very very very very very very ' + fields.name = 'My very very very very very very very very very very very very very very very very very ' +
'very very very very very very very very very very very very very very very very long long' + 'very very very very very very very very very very very very very very very very long long' +
'very very very very very very very very very very very very very very very very long name', 'very very very very very very very very very very very very very very very very long name'
category: 5,
licence: 1, const attaches = getVideoUploadAttaches
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail without a category', async function () { it('Should fail without a category', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', delete fields.category
licence: 1,
language: 6, const attaches = getVideoUploadAttaches
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a bad category', async function () { it('Should fail with a bad category', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.category = 125
category: 125,
licence: 1, const attaches = getVideoUploadAttaches
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail without a licence', async function () { it('Should fail without a licence', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', delete fields.licence
category: 5,
language: 6, const attaches = getVideoUploadAttaches()
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a bad licence', async function () { it('Should fail with a bad licence', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.licence = 125
category: 5,
licence: 125, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a bad language', async function () { it('Should fail with a bad language', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.language = 563
category: 5,
licence: 4, const attaches = getVideoUploadAttaches()
language: 563,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail without nsfw attribute', async function () { it('Should fail without nsfw attribute', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', delete fields.nsfw
category: 5,
licence: 4, const attaches = getVideoUploadAttaches()
language: 6,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a bad nsfw attribute', async function () { it('Should fail with a bad nsfw attribute', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.nsfw = 2 as any
category: 5,
licence: 4, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: 2,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail without description', async function () { it('Should fail without description', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', delete fields.description
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a long description', async function () { it('Should fail with a long description', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.description = 'my super description which is very very very very very very very very very very very very long'.repeat(35)
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description which is very very very very very very very very very very very very very very long'.repeat(35),
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail without a channel', async function () { it('Should fail without a channel', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', delete fields.channelId
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a bad channel', async function () { it('Should fail with a bad channel', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.channelId = 545454
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId: 545454
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
@ -332,101 +286,47 @@ describe('Test videos API validator', function () {
const accessTokenUser = await getUserAccessToken(server, user) const accessTokenUser = await getUserAccessToken(server, user)
const res = await getMyUserInformation(server.url, accessTokenUser) const res = await getMyUserInformation(server.url, accessTokenUser)
const channelId = res.body.videoChannels[0].id const customChannelId = res.body.videoChannels[0].id
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.channelId = customChannelId
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with too many tags', async function () { it('Should fail with too many tags', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.tags = [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ]
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a tag length too low', async function () { it('Should fail with a tag length too low', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.tags = [ 'tag1', 't' ]
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 't' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail with a tag length too big', async function () { it('Should fail with a tag length too big', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', fields.tags = [ 'my_super_tag_too_long_long_long_long_long_long', 'tag1' ]
category: 5,
licence: 1, const attaches = getVideoUploadAttaches()
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'my_super_tag_too_long_long_long_long_long_long', 'tag1' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail without an input file', async function () { it('Should fail without an input file', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name',
category: 5,
licence: 1,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {} const attaches = {}
await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) await makePostUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
}) })
it('Should fail without an incorrect input file', async function () { it('Should fail without an incorrect input file', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name',
category: 5,
licence: 1,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = { const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short_fake.webm') 'videofile': join(__dirname, '..', 'fixtures', 'video_short_fake.webm')
} }
@ -434,16 +334,7 @@ describe('Test videos API validator', function () {
}) })
it('Should fail with a too big duration', async function () { it('Should fail with a too big duration', async function () {
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name',
category: 5,
licence: 1,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = { const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_too_long.webm') 'videofile': join(__dirname, '..', 'fixtures', 'video_too_long.webm')
} }
@ -453,19 +344,8 @@ describe('Test videos API validator', function () {
it('Should succeed with the correct parameters', async function () { it('Should succeed with the correct parameters', async function () {
this.timeout(10000) this.timeout(10000)
const fields = { const fields = getCompleteVideoUploadAttributes()
name: 'my super name', const attaches = getVideoUploadAttaches()
category: 5,
licence: 1,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ],
channelId
}
const attaches = {
'videofile': join(__dirname, '..', 'fixtures', 'video_short.webm')
}
await makePostUploadRequest({ await makePostUploadRequest({
url: server.url, url: server.url,
@ -512,26 +392,13 @@ describe('Test videos API validator', function () {
}) })
it('Should fail without a valid uuid', async function () { it('Should fail without a valid uuid', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ url: server.url, path: path + 'blabla', token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + 'blabla', token: server.accessToken, fields })
}) })
it('Should fail with an unknown id', async function () { it('Should fail with an unknown id', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ await makePutBodyRequest({
url: server.url, url: server.url,
path: path + '4da6fde3-88f7-4d16-b119-108df5630b06', path: path + '4da6fde3-88f7-4d16-b119-108df5630b06',
@ -542,127 +409,77 @@ describe('Test videos API validator', function () {
}) })
it('Should fail with a long name', async function () { it('Should fail with a long name', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'My very very very very very very very very very very very very very very very very very ' + fields.name = 'My very very very very very very very very very very very very very very very very long'.repeat(3)
'very very very very very very very very very very very very very very very very long long' +
'very very very very very very very very very very very very very very very very long name',
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a bad category', async function () { it('Should fail with a bad category', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.category = 128
category: 128,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a bad licence', async function () { it('Should fail with a bad licence', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.licence = 128
category: 5,
licence: 128,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a bad language', async function () { it('Should fail with a bad language', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.language = 896
category: 5,
licence: 3,
language: 896,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a bad nsfw attribute', async function () { it('Should fail with a bad nsfw attribute', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.nsfw = (-4 as any)
category: 5,
licence: 5,
language: 6,
nsfw: -4,
description: 'my super description',
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a long description', async function () { it('Should fail with a long description', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.description = 'my super description which is very very very very very very very very very very very very very long'.repeat(35)
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description which is very very very very very very very very very very very very very long'.repeat(35),
tags: [ 'tag1', 'tag2' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with too many tags', async function () { it('Should fail with too many tags', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.tags = [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ]
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a tag length too low', async function () { it('Should fail with a tag length too low', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.tags = [ 'tag1', 't' ]
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'tag1', 't' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a tag length too big', async function () { it('Should fail with a tag length too big', async function () {
const fields = { const fields = getCompleteVideoUpdateAttributes()
name: 'my super name', fields.tags = [ 'my_super_tag_too_long_long_long_long', 'tag1' ]
category: 5,
licence: 2,
language: 6,
nsfw: false,
description: 'my super description',
tags: [ 'my_super_tag_too_long_long_long_long', 'tag1' ]
}
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
}) })
it('Should fail with a video of another user') it('Should fail with a video of another user')
it('Should fail with a video of another pod') it('Should fail with a video of another pod')
it('Should succeed with the correct parameters', async function () {
const fields = getCompleteVideoUpdateAttributes()
await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields, statusCodeExpected: 204 })
})
}) })
describe('When getting a video', function () { describe('When getting a video', function () {

View File

@ -8,6 +8,7 @@ import './video-abuse'
import './video-blacklist' import './video-blacklist'
import './video-blacklist-management' import './video-blacklist-management'
import './video-description' import './video-description'
import './video-privacy'
import './multiple-pods' import './multiple-pods'
import './services' import './services'
import './request-schedulers' import './request-schedulers'

View File

@ -22,6 +22,7 @@ import {
getVideoCategories, getVideoCategories,
getVideoLicences, getVideoLicences,
getVideoLanguages, getVideoLanguages,
getVideoPrivacies,
testVideoImage, testVideoImage,
webtorrentAdd, webtorrentAdd,
getVideo, getVideo,
@ -76,6 +77,15 @@ describe('Test a single pod', function () {
expect(languages[3]).to.equal('Mandarin') expect(languages[3]).to.equal('Mandarin')
}) })
it('Should list video privacies', async function () {
const res = await getVideoPrivacies(server.url)
const privacies = res.body
expect(Object.keys(privacies)).to.have.length.at.least(3)
expect(privacies[3]).to.equal('Private')
})
it('Should not have videos', async function () { it('Should not have videos', async function () {
const res = await getVideosList(server.url) const res = await getVideosList(server.url)
@ -482,19 +492,6 @@ describe('Test a single pod', function () {
// }) // })
// }) // })
it('Should search the right magnetUri video', async function () {
const video = videosListBase[0]
const res = await getVideo(server.url, video.id)
const videoDetails = res.body
const res2 = await searchVideoWithPagination(server.url, encodeURIComponent(videoDetails.files[0].magnetUri), 'magnetUri', 0, 15)
const videos = res2.body.data
expect(res2.body.total).to.equal(1)
expect(videos.length).to.equal(1)
expect(videos[0].name).to.equal(video.name)
})
it('Should list and sort by name in descending order', async function () { it('Should list and sort by name in descending order', async function () {
const res = await getVideosListSort(server.url, '-name') const res = await getVideosListSort(server.url, '-name')

View File

@ -31,6 +31,7 @@ import {
getBlacklistedVideosList getBlacklistedVideosList
} from '../utils' } from '../utils'
import { UserRole } from '../../../shared' import { UserRole } from '../../../shared'
import { getMyVideos } from '../utils/videos'
describe('Test users', function () { describe('Test users', function () {
let server: ServerInfo let server: ServerInfo
@ -197,10 +198,22 @@ describe('Test users', function () {
it('Should be able to upload a video with this user', async function () { it('Should be able to upload a video with this user', async function () {
this.timeout(5000) this.timeout(5000)
const videoAttributes = {} const videoAttributes = {
name: 'super user video'
}
await uploadVideo(server.url, accessTokenUser, videoAttributes) await uploadVideo(server.url, accessTokenUser, videoAttributes)
}) })
it('Should be able to list my videos', async function () {
const res = await getMyVideos(server.url, accessTokenUser, 0, 5)
expect(res.body.total).to.equal(1)
const videos = res.body.data
expect(videos).to.have.lengthOf(1)
expect(videos[0].name).to.equal('super user video')
})
it('Should list all the users', async function () { it('Should list all the users', async function () {
const res = await getUsersList(server.url) const res = await getUsersList(server.url)
const result = res.body const result = res.body

View File

@ -0,0 +1,158 @@
/* tslint:disable:no-unused-expression */
import 'mocha'
import * as chai from 'chai'
const expect = chai.expect
import {
ServerInfo,
flushTests,
uploadVideo,
makeFriends,
getVideosList,
wait,
setAccessTokensToServers,
flushAndRunMultipleServers,
killallServers
} from '../utils'
import { VideoPrivacy } from '../../../shared/models/videos/video-privacy.enum'
import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../utils/videos'
import { createUser } from '../utils/users'
import { getUserAccessToken } from '../utils/login'
describe('Test video privacy', function () {
let servers: ServerInfo[] = []
let privateVideoId
let privateVideoUUID
let unlistedVideoUUID
before(async function () {
this.timeout(120000)
// Run servers
servers = await flushAndRunMultipleServers(2)
// Get the access tokens
await setAccessTokensToServers(servers)
// Pod 1 makes friend with pod 2
await makeFriends(servers[0].url, servers[0].accessToken)
})
it('Should upload a private video on pod 1', async function () {
this.timeout(15000)
const attributes = {
privacy: VideoPrivacy.PRIVATE
}
await uploadVideo(servers[0].url, servers[0].accessToken, attributes)
await wait(11000)
})
it('Should not have this private video on pod 2', async function () {
const res = await getVideosList(servers[1].url)
expect(res.body.total).to.equal(0)
expect(res.body.data).to.have.lengthOf(0)
})
it('Should list my (private) videos', async function () {
const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 1)
expect(res.body.total).to.equal(1)
expect(res.body.data).to.have.lengthOf(1)
privateVideoId = res.body.data[0].id
privateVideoUUID = res.body.data[0].uuid
})
it('Should not be able to watch this video with non authenticated user', async function () {
await getVideo(servers[0].url, privateVideoUUID, 401)
})
it('Should not be able to watch this private video with another user', async function () {
const user = {
username: 'hello',
password: 'super password'
}
await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
const token = await getUserAccessToken(servers[0], user)
await getVideoWithToken(servers[0].url, token, privateVideoUUID, 403)
})
it('Should be able to watch this video with the correct user', async function () {
await getVideoWithToken(servers[0].url, servers[0].accessToken, privateVideoUUID)
})
it('Should upload a unlisted video on pod 2', async function () {
this.timeout(30000)
const attributes = {
name: 'unlisted video',
privacy: VideoPrivacy.UNLISTED
}
await uploadVideo(servers[1].url, servers[1].accessToken, attributes)
await wait(22000)
})
it('Should not have this unlisted video listed on pod 1 and 2', async function () {
for (const server of servers) {
const res = await getVideosList(server.url)
expect(res.body.total).to.equal(0)
expect(res.body.data).to.have.lengthOf(0)
}
})
it('Should list my (unlisted) videos', async function () {
const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 1)
expect(res.body.total).to.equal(1)
expect(res.body.data).to.have.lengthOf(1)
unlistedVideoUUID = res.body.data[0].uuid
})
it('Should be able to get this unlisted video', async function () {
for (const server of servers) {
const res = await getVideo(server.url, unlistedVideoUUID)
expect(res.body.name).to.equal('unlisted video')
}
})
it('Should update the private video to public on pod 1', async function () {
this.timeout(15000)
const attribute = {
name: 'super video public',
privacy: VideoPrivacy.PUBLIC
}
await updateVideo(servers[0].url, servers[0].accessToken, privateVideoId, attribute)
await wait(11000)
})
it('Should not have this new unlisted video listed on pod 1 and 2', async function () {
for (const server of servers) {
const res = await getVideosList(server.url)
expect(res.body.total).to.equal(1)
expect(res.body.data).to.have.lengthOf(1)
expect(res.body.data[0].name).to.equal('super video public')
}
})
after(async function () {
killallServers(servers)
// Keep the logs if the test failed
if (this['ok']) {
await flushTests()
}
})
})

View File

@ -7,6 +7,7 @@ import { makeGetRequest } from './requests'
import { readFilePromise } from './miscs' import { readFilePromise } from './miscs'
import { ServerInfo } from './servers' import { ServerInfo } from './servers'
import { getMyUserInformation } from './users' import { getMyUserInformation } from './users'
import { VideoPrivacy } from '../../../shared'
type VideoAttributes = { type VideoAttributes = {
name?: string name?: string
@ -17,6 +18,7 @@ type VideoAttributes = {
description?: string description?: string
tags?: string[] tags?: string[]
channelId?: number channelId?: number
privacy?: VideoPrivacy
fixture?: string fixture?: string
} }
@ -38,6 +40,12 @@ function getVideoLanguages (url: string) {
return makeGetRequest(url, path) return makeGetRequest(url, path)
} }
function getVideoPrivacies (url: string) {
const path = '/api/v1/videos/privacies'
return makeGetRequest(url, path)
}
function getAllVideosListBy (url: string) { function getAllVideosListBy (url: string) {
const path = '/api/v1/videos' const path = '/api/v1/videos'
@ -51,14 +59,23 @@ function getAllVideosListBy (url: string) {
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
} }
function getVideo (url: string, id: number | string) { function getVideo (url: string, id: number | string, expectedStatus = 200) {
const path = '/api/v1/videos/' + id const path = '/api/v1/videos/' + id
return request(url) return request(url)
.get(path) .get(path)
.set('Accept', 'application/json') .set('Accept', 'application/json')
.expect(200) .expect(expectedStatus)
.expect('Content-Type', /json/) }
function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) {
const path = '/api/v1/videos/' + id
return request(url)
.get(path)
.set('Authorization', 'Bearer ' + token)
.set('Accept', 'application/json')
.expect(expectedStatus)
} }
function getVideoDescription (url: string, descriptionPath: string) { function getVideoDescription (url: string, descriptionPath: string) {
@ -80,6 +97,22 @@ function getVideosList (url: string) {
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
} }
function getMyVideos (url: string, accessToken: string, start: number, count: number, sort?: string) {
const path = '/api/v1/users/me/videos'
const req = request(url)
.get(path)
.query({ start: start })
.query({ count: count })
if (sort) req.query({ sort })
return req.set('Accept', 'application/json')
.set('Authorization', 'Bearer ' + accessToken)
.expect(200)
.expect('Content-Type', /json/)
}
function getVideosListPagination (url: string, start: number, count: number, sort?: string) { function getVideosListPagination (url: string, start: number, count: number, sort?: string) {
const path = '/api/v1/videos' const path = '/api/v1/videos'
@ -191,6 +224,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
nsfw: true, nsfw: true,
description: 'my super description', description: 'my super description',
tags: [ 'tag' ], tags: [ 'tag' ],
privacy: VideoPrivacy.PUBLIC,
fixture: 'video_short.webm' fixture: 'video_short.webm'
} }
attributes = Object.assign(attributes, videoAttributesArg) attributes = Object.assign(attributes, videoAttributesArg)
@ -204,6 +238,7 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
.field('licence', attributes.licence.toString()) .field('licence', attributes.licence.toString())
.field('nsfw', JSON.stringify(attributes.nsfw)) .field('nsfw', JSON.stringify(attributes.nsfw))
.field('description', attributes.description) .field('description', attributes.description)
.field('privacy', attributes.privacy.toString())
.field('channelId', attributes.channelId) .field('channelId', attributes.channelId)
if (attributes.language !== undefined) { if (attributes.language !== undefined) {
@ -236,6 +271,7 @@ function updateVideo (url: string, accessToken: string, id: number, attributes:
if (attributes.nsfw) body['nsfw'] = attributes.nsfw if (attributes.nsfw) body['nsfw'] = attributes.nsfw
if (attributes.description) body['description'] = attributes.description if (attributes.description) body['description'] = attributes.description
if (attributes.tags) body['tags'] = attributes.tags if (attributes.tags) body['tags'] = attributes.tags
if (attributes.privacy) body['privacy'] = attributes.privacy
return request(url) return request(url)
.put(path) .put(path)
@ -274,9 +310,12 @@ export {
getVideoDescription, getVideoDescription,
getVideoCategories, getVideoCategories,
getVideoLicences, getVideoLicences,
getVideoPrivacies,
getVideoLanguages, getVideoLanguages,
getAllVideosListBy, getAllVideosListBy,
getMyVideos,
getVideo, getVideo,
getVideoWithToken,
getVideosList, getVideosList,
getVideosListPagination, getVideosListPagination,
getVideosListSort, getVideosListSort,