aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2016-06-06 14:15:03 +0200
committerChocobozzz <florian.bigard@gmail.com>2016-06-06 14:15:03 +0200
commitbe587647f98a4b83ca06a61fe55c7ac5d60927c6 (patch)
tree8a28a1cb9c9a06d80803ecd3fa00aa6767bb3f8b
parent8483b2216454afdb88f6aa53cad5eecd8c394bc0 (diff)
downloadPeerTube-be587647f98a4b83ca06a61fe55c7ac5d60927c6.tar.gz
PeerTube-be587647f98a4b83ca06a61fe55c7ac5d60927c6.tar.zst
PeerTube-be587647f98a4b83ca06a61fe55c7ac5d60927c6.zip
Add tags support to server
-rw-r--r--package.json1
-rw-r--r--server/controllers/api/v1/videos.js8
-rw-r--r--server/helpers/customValidators.js101
-rw-r--r--server/initializers/constants.js23
-rw-r--r--server/lib/videos.js3
-rw-r--r--server/middlewares/reqValidators/remote.js4
-rw-r--r--server/middlewares/reqValidators/videos.js14
-rw-r--r--server/models/videos.js1
-rw-r--r--server/tests/api/checkParams.js104
-rw-r--r--server/tests/api/friendsAdvanced.js3
-rw-r--r--server/tests/api/multiplePods.js28
-rw-r--r--server/tests/api/singlePod.js16
-rw-r--r--server/tests/api/users.js19
-rw-r--r--server/tests/api/utils.js25
14 files changed, 277 insertions, 73 deletions
diff --git a/package.json b/package.json
index 5e437b982..579ef3d2e 100644
--- a/package.json
+++ b/package.json
@@ -61,7 +61,6 @@
61 "scripty": "^1.5.0", 61 "scripty": "^1.5.0",
62 "segfault-handler": "^1.0.0", 62 "segfault-handler": "^1.0.0",
63 "ursa": "^0.9.1", 63 "ursa": "^0.9.1",
64 "validator": "^5.0.0",
65 "webtorrent": "^0.93.2", 64 "webtorrent": "^0.93.2",
66 "winston": "^2.1.1", 65 "winston": "^2.1.1",
67 "ws": "^1.0.1" 66 "ws": "^1.0.1"
diff --git a/server/controllers/api/v1/videos.js b/server/controllers/api/v1/videos.js
index 7f59dd232..5449cbcfa 100644
--- a/server/controllers/api/v1/videos.js
+++ b/server/controllers/api/v1/videos.js
@@ -115,7 +115,8 @@ function addVideo (req, res, next) {
115 magnetUri: torrent.magnetURI, 115 magnetUri: torrent.magnetURI,
116 author: res.locals.oauth.token.user.username, 116 author: res.locals.oauth.token.user.username,
117 duration: videoFile.duration, 117 duration: videoFile.duration,
118 thumbnail: thumbnailName 118 thumbnail: thumbnailName,
119 tags: videoInfos.tags
119 } 120 }
120 121
121 Videos.add(videoData, function (err, insertedVideo) { 122 Videos.add(videoData, function (err, insertedVideo) {
@@ -156,7 +157,7 @@ function addVideo (req, res, next) {
156 return callback(null) 157 return callback(null)
157 } 158 }
158 159
159 ], function (err) { 160 ], function andFinally (err) {
160 if (err) { 161 if (err) {
161 logger.error('Cannot insert the video.') 162 logger.error('Cannot insert the video.')
162 return next(err) 163 return next(err)
@@ -228,7 +229,7 @@ function removeVideo (req, res, next) {
228 229
229 return callback(null) 230 return callback(null)
230 } 231 }
231 ], function (err) { 232 ], function andFinally (err) {
232 if (err) { 233 if (err) {
233 logger.error('Errors when removed the video.', { error: err }) 234 logger.error('Errors when removed the video.', { error: err })
234 return next(err) 235 return next(err)
@@ -259,6 +260,7 @@ function getFormatedVideo (videoObj) {
259 magnetUri: videoObj.magnetUri, 260 magnetUri: videoObj.magnetUri,
260 author: videoObj.author, 261 author: videoObj.author,
261 duration: videoObj.duration, 262 duration: videoObj.duration,
263 tags: videoObj.tags,
262 thumbnailPath: constants.THUMBNAILS_STATIC_PATH + '/' + videoObj.thumbnail, 264 thumbnailPath: constants.THUMBNAILS_STATIC_PATH + '/' + videoObj.thumbnail,
263 createdDate: videoObj.createdDate 265 createdDate: videoObj.createdDate
264 } 266 }
diff --git a/server/helpers/customValidators.js b/server/helpers/customValidators.js
index 5a0e70ffc..9c3ff38ef 100644
--- a/server/helpers/customValidators.js
+++ b/server/helpers/customValidators.js
@@ -1,34 +1,47 @@
1'use strict' 1'use strict'
2 2
3const validator = require('validator') 3const validator = require('express-validator').validator
4 4
5const constants = require('../initializers/constants') 5const constants = require('../initializers/constants')
6const VIDEOS_CONSTRAINTS_FIELDS = constants.VIDEOS_CONSTRAINTS_FIELDS
6 7
7const customValidators = { 8const customValidators = {
8 eachIsRemoteVideosAddValid: eachIsRemoteVideosAddValid, 9 exists: exists,
9 eachIsRemoteVideosRemoveValid: eachIsRemoteVideosRemoveValid, 10 isEachAddRemoteVideosValid: isEachAddRemoteVideosValid,
10 isArray: isArray 11 isEachRemoveRemoteVideosValid: isEachRemoveRemoteVideosValid,
11} 12 isArray: isArray,
12 13 isVideoAuthorValid: isVideoAuthorValid,
13function eachIsRemoteVideosAddValid (values) { 14 isVideoDateValid: isVideoDateValid,
14 return values.every(function (val) { 15 isVideoDescriptionValid: isVideoDescriptionValid,
15 return validator.isLength(val.name, 1, 50) && 16 isVideoDurationValid: isVideoDurationValid,
16 validator.isLength(val.description, 1, 50) && 17 isVideoMagnetUriValid: isVideoMagnetUriValid,
17 validator.isLength(val.magnetUri, 10) && 18 isVideoNameValid: isVideoNameValid,
18 validator.isURL(val.podUrl) && 19 isVideoPodUrlValid: isVideoPodUrlValid,
19 !isNaN(val.duration) && 20 isVideoTagsValid: isVideoTagsValid,
20 val.duration >= 0 && 21 isVideoThumbnailValid: isVideoThumbnailValid
21 val.duration < constants.MAXIMUM_VIDEO_DURATION && 22}
22 validator.isLength(val.author, 1, constants.MAXIMUM_AUTHOR_LENGTH) && 23
23 validator.isBase64(val.thumbnailBase64) && 24function exists (value) {
24 validator.isByteLength(val.thumbnailBase64, { min: 0, max: 20000 }) && 25 return value !== undefined && value !== null
25 validator.isDate(val.createdDate) 26}
27
28function isEachAddRemoteVideosValid (videos) {
29 return videos.every(function (video) {
30 return isVideoAuthorValid(video.author) &&
31 isVideoDateValid(video.createdDate) &&
32 isVideoDescriptionValid(video.description) &&
33 isVideoDurationValid(video.duration) &&
34 isVideoMagnetUriValid(video.magnetUri) &&
35 isVideoNameValid(video.name) &&
36 isVideoPodUrlValid(video.podUrl) &&
37 isVideoTagsValid(video.tags) &&
38 isVideoThumbnailValid(video.thumbnailBase64)
26 }) 39 })
27} 40}
28 41
29function eachIsRemoteVideosRemoveValid (values) { 42function isEachRemoveRemoteVideosValid (videos) {
30 return values.every(function (val) { 43 return videos.every(function (video) {
31 return validator.isLength(val.magnetUri, 10) 44 return isVideoMagnetUriValid(video.magnetUri)
32 }) 45 })
33} 46}
34 47
@@ -36,6 +49,50 @@ function isArray (value) {
36 return Array.isArray(value) 49 return Array.isArray(value)
37} 50}
38 51
52function isVideoAuthorValid (value) {
53 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.AUTHOR)
54}
55
56function isVideoDateValid (value) {
57 return validator.isDate(value)
58}
59
60function isVideoDescriptionValid (value) {
61 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
62}
63
64function isVideoDurationValid (value) {
65 return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
66}
67
68function isVideoMagnetUriValid (value) {
69 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.MAGNET_URI)
70}
71
72function isVideoNameValid (value) {
73 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
74}
75
76function isVideoPodUrlValid (value) {
77 return validator.isURL(value)
78}
79
80function isVideoTagsValid (tags) {
81 return isArray(tags) &&
82 validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
83 tags.every(function (tag) {
84 return validator.isAlphanumeric(tag) &&
85 validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
86 })
87}
88
89function isVideoThumbnailValid (value) {
90 return validator.isBase64(value) &&
91 validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
92}
93
39// --------------------------------------------------------------------------- 94// ---------------------------------------------------------------------------
40 95
41module.exports = customValidators 96module.exports = customValidators
97
98// ---------------------------------------------------------------------------
diff --git a/server/initializers/constants.js b/server/initializers/constants.js
index 63ac863c1..97d22abdb 100644
--- a/server/initializers/constants.js
+++ b/server/initializers/constants.js
@@ -9,11 +9,6 @@ let FRIEND_BASE_SCORE = 100
9// Time to wait between requests to the friends (10 min) 9// Time to wait between requests to the friends (10 min)
10let INTERVAL = 600000 10let INTERVAL = 600000
11 11
12// Max length of the author username
13const MAXIMUM_AUTHOR_LENGTH = 20
14// 2 hours maximum for the duration of a video (in seconds)
15let MAXIMUM_VIDEO_DURATION = 7200
16
17// Number of results by default for the pagination 12// Number of results by default for the pagination
18const PAGINATION_COUNT_DEFAULT = 15 13const PAGINATION_COUNT_DEFAULT = 15
19 14
@@ -42,11 +37,22 @@ const THUMBNAILS_SIZE = '200x110'
42// Path for access to thumbnails with express router 37// Path for access to thumbnails with express router
43const THUMBNAILS_STATIC_PATH = '/static/thumbnails' 38const THUMBNAILS_STATIC_PATH = '/static/thumbnails'
44 39
40const VIDEOS_CONSTRAINTS_FIELDS = {
41 NAME: { min: 1, max: 50 }, // Length
42 DESCRIPTION: { min: 1, max: 250 }, // Length
43 MAGNET_URI: { min: 10 }, // Length
44 DURATION: { min: 1, max: 7200 }, // Number
45 AUTHOR: { min: 3, max: 20 }, // Length
46 TAGS: { min: 1, max: 3 }, // Number of total tags
47 TAG: { min: 2, max: 10 }, // Length
48 THUMBNAIL: { min: 0, max: 20000 } // Bytes
49}
50
45// Special constants for a test instance 51// Special constants for a test instance
46if (isTestInstance() === true) { 52if (isTestInstance() === true) {
47 FRIEND_BASE_SCORE = 20 53 FRIEND_BASE_SCORE = 20
48 INTERVAL = 10000 54 INTERVAL = 10000
49 MAXIMUM_VIDEO_DURATION = 14 55 VIDEOS_CONSTRAINTS_FIELDS.DURATION.max = 14
50 REQUEST_RETRIES = 2 56 REQUEST_RETRIES = 2
51} 57}
52 58
@@ -56,15 +62,14 @@ module.exports = {
56 API_VERSION: API_VERSION, 62 API_VERSION: API_VERSION,
57 FRIEND_BASE_SCORE: FRIEND_BASE_SCORE, 63 FRIEND_BASE_SCORE: FRIEND_BASE_SCORE,
58 INTERVAL: INTERVAL, 64 INTERVAL: INTERVAL,
59 MAXIMUM_AUTHOR_LENGTH: MAXIMUM_AUTHOR_LENGTH,
60 MAXIMUM_VIDEO_DURATION: MAXIMUM_VIDEO_DURATION,
61 PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT, 65 PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT,
62 PODS_SCORE: PODS_SCORE, 66 PODS_SCORE: PODS_SCORE,
63 REQUEST_RETRIES: REQUEST_RETRIES, 67 REQUEST_RETRIES: REQUEST_RETRIES,
64 SEARCHABLE_COLUMNS: SEARCHABLE_COLUMNS, 68 SEARCHABLE_COLUMNS: SEARCHABLE_COLUMNS,
65 SORTABLE_COLUMNS: SORTABLE_COLUMNS, 69 SORTABLE_COLUMNS: SORTABLE_COLUMNS,
66 THUMBNAILS_SIZE: THUMBNAILS_SIZE, 70 THUMBNAILS_SIZE: THUMBNAILS_SIZE,
67 THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH 71 THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH,
72 VIDEOS_CONSTRAINTS_FIELDS: VIDEOS_CONSTRAINTS_FIELDS
68} 73}
69 74
70// --------------------------------------------------------------------------- 75// ---------------------------------------------------------------------------
diff --git a/server/lib/videos.js b/server/lib/videos.js
index 154c31ef9..e0db0e1d5 100644
--- a/server/lib/videos.js
+++ b/server/lib/videos.js
@@ -153,7 +153,8 @@ function createRemoteVideoObjects (videos, callback) {
153 magnetUri: video.magnetUri, 153 magnetUri: video.magnetUri,
154 podUrl: video.podUrl, 154 podUrl: video.podUrl,
155 duration: video.duration, 155 duration: video.duration,
156 thumbnail: thumbnailName 156 thumbnail: thumbnailName,
157 tags: video.tags
157 } 158 }
158 remoteVideos.push(params) 159 remoteVideos.push(params)
159 160
diff --git a/server/middlewares/reqValidators/remote.js b/server/middlewares/reqValidators/remote.js
index 3bc0e0f40..b5f3118b0 100644
--- a/server/middlewares/reqValidators/remote.js
+++ b/server/middlewares/reqValidators/remote.js
@@ -11,7 +11,7 @@ const reqValidatorsRemote = {
11 11
12function remoteVideosAdd (req, res, next) { 12function remoteVideosAdd (req, res, next) {
13 req.checkBody('data').isArray() 13 req.checkBody('data').isArray()
14 req.checkBody('data').eachIsRemoteVideosAddValid() 14 req.checkBody('data').isEachAddRemoteVideosValid()
15 15
16 logger.debug('Checking remoteVideosAdd parameters', { parameters: req.body }) 16 logger.debug('Checking remoteVideosAdd parameters', { parameters: req.body })
17 17
@@ -20,7 +20,7 @@ function remoteVideosAdd (req, res, next) {
20 20
21function remoteVideosRemove (req, res, next) { 21function remoteVideosRemove (req, res, next) {
22 req.checkBody('data').isArray() 22 req.checkBody('data').isArray()
23 req.checkBody('data').eachIsRemoteVideosRemoveValid() 23 req.checkBody('data').isEachRemoveRemoteVideosValid()
24 24
25 logger.debug('Checking remoteVideosRemove parameters', { parameters: req.body }) 25 logger.debug('Checking remoteVideosRemove parameters', { parameters: req.body })
26 26
diff --git a/server/middlewares/reqValidators/videos.js b/server/middlewares/reqValidators/videos.js
index 10b6d39c6..3618e4716 100644
--- a/server/middlewares/reqValidators/videos.js
+++ b/server/middlewares/reqValidators/videos.js
@@ -2,6 +2,7 @@
2 2
3const checkErrors = require('./utils').checkErrors 3const checkErrors = require('./utils').checkErrors
4const constants = require('../../initializers/constants') 4const constants = require('../../initializers/constants')
5const customValidators = require('../../helpers/customValidators')
5const logger = require('../../helpers/logger') 6const logger = require('../../helpers/logger')
6const videos = require('../../lib/videos') 7const videos = require('../../lib/videos')
7const Videos = require('../../models/videos') 8const Videos = require('../../models/videos')
@@ -16,8 +17,9 @@ const reqValidatorsVideos = {
16function videosAdd (req, res, next) { 17function videosAdd (req, res, next) {
17 req.checkFiles('videofile[0].originalname', 'Should have an input video').notEmpty() 18 req.checkFiles('videofile[0].originalname', 'Should have an input video').notEmpty()
18 req.checkFiles('videofile[0].mimetype', 'Should have a correct mime type').matches(/video\/(webm)|(mp4)|(ogg)/i) 19 req.checkFiles('videofile[0].mimetype', 'Should have a correct mime type').matches(/video\/(webm)|(mp4)|(ogg)/i)
19 req.checkBody('name', 'Should have a name').isLength(1, 50) 20 req.checkBody('name', 'Should have a valid name').isVideoNameValid()
20 req.checkBody('description', 'Should have a description').isLength(1, 250) 21 req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid()
22 req.checkBody('tags', 'Should have correct tags').isVideoTagsValid()
21 23
22 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) 24 logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
23 25
@@ -29,7 +31,7 @@ function videosAdd (req, res, next) {
29 return res.status(400).send('Cannot retrieve metadata of the file.') 31 return res.status(400).send('Cannot retrieve metadata of the file.')
30 } 32 }
31 33
32 if (duration > constants.MAXIMUM_VIDEO_DURATION) { 34 if (!customValidators.isVideoDurationValid(duration)) {
33 return res.status(400).send('Duration of the video file is too big (max: ' + constants.MAXIMUM_VIDEO_DURATION + 's).') 35 return res.status(400).send('Duration of the video file is too big (max: ' + constants.MAXIMUM_VIDEO_DURATION + 's).')
34 } 36 }
35 37
@@ -48,7 +50,7 @@ function videosGet (req, res, next) {
48 Videos.get(req.params.id, function (err, video) { 50 Videos.get(req.params.id, function (err, video) {
49 if (err) { 51 if (err) {
50 logger.error('Error in videosGet request validator.', { error: err }) 52 logger.error('Error in videosGet request validator.', { error: err })
51 res.sendStatus(500) 53 return res.sendStatus(500)
52 } 54 }
53 55
54 const state = videos.getVideoState(video) 56 const state = videos.getVideoState(video)
@@ -68,7 +70,7 @@ function videosRemove (req, res, next) {
68 Videos.get(req.params.id, function (err, video) { 70 Videos.get(req.params.id, function (err, video) {
69 if (err) { 71 if (err) {
70 logger.error('Error in videosRemove request validator.', { error: err }) 72 logger.error('Error in videosRemove request validator.', { error: err })
71 res.sendStatus(500) 73 return res.sendStatus(500)
72 } 74 }
73 75
74 const state = videos.getVideoState(video) 76 const state = videos.getVideoState(video)
@@ -82,7 +84,7 @@ function videosRemove (req, res, next) {
82 84
83function videosSearch (req, res, next) { 85function videosSearch (req, res, next) {
84 const searchableColumns = constants.SEARCHABLE_COLUMNS.VIDEOS 86 const searchableColumns = constants.SEARCHABLE_COLUMNS.VIDEOS
85 req.checkParams('value', 'Should have a name').notEmpty() 87 req.checkParams('value', 'Should have a valid search').notEmpty()
86 req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns) 88 req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns)
87 89
88 logger.debug('Checking videosSearch parameters', { parameters: req.params }) 90 logger.debug('Checking videosSearch parameters', { parameters: req.params })
diff --git a/server/models/videos.js b/server/models/videos.js
index 7bd41f7ee..f4658c371 100644
--- a/server/models/videos.js
+++ b/server/models/videos.js
@@ -21,6 +21,7 @@ const videosSchema = mongoose.Schema({
21 author: String, 21 author: String,
22 duration: Number, 22 duration: Number,
23 thumbnail: String, 23 thumbnail: String,
24 tags: [ String ],
24 createdDate: { 25 createdDate: {
25 type: Date, 26 type: Date,
26 default: Date.now 27 default: Date.now
diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js
index e02fd0da5..95a7738f8 100644
--- a/server/tests/api/checkParams.js
+++ b/server/tests/api/checkParams.js
@@ -23,7 +23,14 @@ describe('Test parameters validator', function () {
23 23
24 Object.keys(fields).forEach(function (field) { 24 Object.keys(fields).forEach(function (field) {
25 const value = fields[field] 25 const value = fields[field]
26 req.field(field, value) 26
27 if (Array.isArray(value)) {
28 for (let i = 0; i < value.length; i++) {
29 req.field(field + '[' + i + ']', value[i])
30 }
31 } else {
32 req.field(field, value)
33 }
27 }) 34 })
28 35
29 Object.keys(attaches).forEach(function (attach) { 36 Object.keys(attaches).forEach(function (attach) {
@@ -198,7 +205,8 @@ describe('Test parameters validator', function () {
198 205
199 it('Should fail without name', function (done) { 206 it('Should fail without name', function (done) {
200 const data = { 207 const data = {
201 description: 'my super description' 208 description: 'my super description',
209 tags: [ 'tag1', 'tag2' ]
202 } 210 }
203 const attach = { 211 const attach = {
204 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') 212 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
@@ -209,7 +217,8 @@ describe('Test parameters validator', function () {
209 it('Should fail with a long name', function (done) { 217 it('Should fail with a long name', function (done) {
210 const data = { 218 const data = {
211 name: 'My very very very very very very very very very very very very very very very very long name', 219 name: 'My very very very very very very very very very very very very very very very very long name',
212 description: 'my super description' 220 description: 'my super description',
221 tags: [ 'tag1', 'tag2' ]
213 } 222 }
214 const attach = { 223 const attach = {
215 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') 224 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
@@ -219,7 +228,8 @@ describe('Test parameters validator', function () {
219 228
220 it('Should fail without description', function (done) { 229 it('Should fail without description', function (done) {
221 const data = { 230 const data = {
222 name: 'my super name' 231 name: 'my super name',
232 tags: [ 'tag1', 'tag2' ]
223 } 233 }
224 const attach = { 234 const attach = {
225 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') 235 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
@@ -232,7 +242,8 @@ describe('Test parameters validator', function () {
232 name: 'my super name', 242 name: 'my super name',
233 description: 'my super description which is very very very very very very very very very very very very very very' + 243 description: 'my super description which is very very very very very very very very very very very very very very' +
234 'very very very very very very very very very very very very very very very very very very very very very' + 244 'very very very very very very very very very very very very very very very very very very very very very' +
235 'very very very very very very very very very very very very very very very long' 245 'very very very very very very very very very very very very very very very long',
246 tags: [ 'tag1', 'tag2' ]
236 } 247 }
237 const attach = { 248 const attach = {
238 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') 249 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
@@ -240,11 +251,83 @@ describe('Test parameters validator', function () {
240 makePostRequest(path, server.accessToken, data, attach, done) 251 makePostRequest(path, server.accessToken, data, attach, done)
241 }) 252 })
242 253
243 it('Should fail without an input file', function (done) { 254 it('Should fail without tags', function (done) {
244 const data = { 255 const data = {
245 name: 'my super name', 256 name: 'my super name',
246 description: 'my super description' 257 description: 'my super description'
247 } 258 }
259 const attach = {
260 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
261 }
262 makePostRequest(path, server.accessToken, data, attach, done)
263 })
264
265 it('Should fail with too many tags', function (done) {
266 const data = {
267 name: 'my super name',
268 description: 'my super description',
269 tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ]
270 }
271 const attach = {
272 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
273 }
274 makePostRequest(path, server.accessToken, data, attach, done)
275 })
276
277 it('Should fail with not enough tags', function (done) {
278 const data = {
279 name: 'my super name',
280 description: 'my super description',
281 tags: [ ]
282 }
283 const attach = {
284 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
285 }
286 makePostRequest(path, server.accessToken, data, attach, done)
287 })
288
289 it('Should fail with a tag length too low', function (done) {
290 const data = {
291 name: 'my super name',
292 description: 'my super description',
293 tags: [ 'tag1', 't' ]
294 }
295 const attach = {
296 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
297 }
298 makePostRequest(path, server.accessToken, data, attach, done)
299 })
300
301 it('Should fail with a tag length too big', function (done) {
302 const data = {
303 name: 'my super name',
304 description: 'my super description',
305 tags: [ 'mysupertagtoolong', 'tag1' ]
306 }
307 const attach = {
308 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
309 }
310 makePostRequest(path, server.accessToken, data, attach, done)
311 })
312
313 it('Should fail with malformed tags', function (done) {
314 const data = {
315 name: 'my super name',
316 description: 'my super description',
317 tags: [ 'my tag' ]
318 }
319 const attach = {
320 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
321 }
322 makePostRequest(path, server.accessToken, data, attach, done)
323 })
324
325 it('Should fail without an input file', function (done) {
326 const data = {
327 name: 'my super name',
328 description: 'my super description',
329 tags: [ 'tag1', 'tag2' ]
330 }
248 const attach = {} 331 const attach = {}
249 makePostRequest(path, server.accessToken, data, attach, done) 332 makePostRequest(path, server.accessToken, data, attach, done)
250 }) 333 })
@@ -252,7 +335,8 @@ describe('Test parameters validator', function () {
252 it('Should fail without an incorrect input file', function (done) { 335 it('Should fail without an incorrect input file', function (done) {
253 const data = { 336 const data = {
254 name: 'my super name', 337 name: 'my super name',
255 description: 'my super description' 338 description: 'my super description',
339 tags: [ 'tag1', 'tag2' ]
256 } 340 }
257 const attach = { 341 const attach = {
258 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short_fake.webm') 342 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short_fake.webm')
@@ -263,7 +347,8 @@ describe('Test parameters validator', function () {
263 it('Should fail with a too big duration', function (done) { 347 it('Should fail with a too big duration', function (done) {
264 const data = { 348 const data = {
265 name: 'my super name', 349 name: 'my super name',
266 description: 'my super description' 350 description: 'my super description',
351 tags: [ 'tag1', 'tag2' ]
267 } 352 }
268 const attach = { 353 const attach = {
269 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_too_long.webm') 354 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_too_long.webm')
@@ -274,7 +359,8 @@ describe('Test parameters validator', function () {
274 it('Should succeed with the correct parameters', function (done) { 359 it('Should succeed with the correct parameters', function (done) {
275 const data = { 360 const data = {
276 name: 'my super name', 361 name: 'my super name',
277 description: 'my super description' 362 description: 'my super description',
363 tags: [ 'tag1', 'tag2' ]
278 } 364 }
279 const attach = { 365 const attach = {
280 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') 366 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
diff --git a/server/tests/api/friendsAdvanced.js b/server/tests/api/friendsAdvanced.js
index 7b895b6b5..86620254e 100644
--- a/server/tests/api/friendsAdvanced.js
+++ b/server/tests/api/friendsAdvanced.js
@@ -27,10 +27,11 @@ describe('Test advanced friends', function () {
27 function uploadVideo (podNumber, callback) { 27 function uploadVideo (podNumber, callback) {
28 const name = 'my super video' 28 const name = 'my super video'
29 const description = 'my super description' 29 const description = 'my super description'
30 const tags = [ 'tag1', 'tag2' ]
30 const fixture = 'video_short.webm' 31 const fixture = 'video_short.webm'
31 const server = servers[podNumber - 1] 32 const server = servers[podNumber - 1]
32 33
33 return utils.uploadVideo(server.url, server.accessToken, name, description, fixture, callback) 34 return utils.uploadVideo(server.url, server.accessToken, name, description, tags, fixture, callback)
34 } 35 }
35 36
36 function getVideos (podNumber, callback) { 37 function getVideos (podNumber, callback) {
diff --git a/server/tests/api/multiplePods.js b/server/tests/api/multiplePods.js
index dac6dd410..40326c260 100644
--- a/server/tests/api/multiplePods.js
+++ b/server/tests/api/multiplePods.js
@@ -75,7 +75,11 @@ describe('Test multiple pods', function () {
75 75
76 async.series([ 76 async.series([
77 function (next) { 77 function (next) {
78 utils.uploadVideo(servers[0].url, servers[0].accessToken, 'my super name for pod 1', 'my super description for pod 1', 'video_short1.webm', next) 78 const name = 'my super name for pod 1'
79 const description = 'my super description for pod 1'
80 const tags = [ 'tag1p1', 'tag2p1' ]
81 const file = 'video_short1.webm'
82 utils.uploadVideo(servers[0].url, servers[0].accessToken, name, description, tags, file, next)
79 }, 83 },
80 function (next) { 84 function (next) {
81 setTimeout(next, 11000) 85 setTimeout(next, 11000)
@@ -99,6 +103,7 @@ describe('Test multiple pods', function () {
99 expect(video.podUrl).to.equal('localhost:9001') 103 expect(video.podUrl).to.equal('localhost:9001')
100 expect(video.magnetUri).to.exist 104 expect(video.magnetUri).to.exist
101 expect(video.duration).to.equal(10) 105 expect(video.duration).to.equal(10)
106 expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ])
102 expect(utils.dateIsValid(video.createdDate)).to.be.true 107 expect(utils.dateIsValid(video.createdDate)).to.be.true
103 108
104 if (server.url !== 'http://localhost:9001') { 109 if (server.url !== 'http://localhost:9001') {
@@ -131,7 +136,11 @@ describe('Test multiple pods', function () {
131 136
132 async.series([ 137 async.series([
133 function (next) { 138 function (next) {
134 utils.uploadVideo(servers[1].url, servers[1].accessToken, 'my super name for pod 2', 'my super description for pod 2', 'video_short2.webm', next) 139 const name = 'my super name for pod 2'
140 const description = 'my super description for pod 2'
141 const tags = [ 'tag1p2', 'tag2p2', 'tag3p2' ]
142 const file = 'video_short2.webm'
143 utils.uploadVideo(servers[1].url, servers[1].accessToken, name, description, tags, file, next)
135 }, 144 },
136 function (next) { 145 function (next) {
137 setTimeout(next, 11000) 146 setTimeout(next, 11000)
@@ -155,6 +164,7 @@ describe('Test multiple pods', function () {
155 expect(video.podUrl).to.equal('localhost:9002') 164 expect(video.podUrl).to.equal('localhost:9002')
156 expect(video.magnetUri).to.exist 165 expect(video.magnetUri).to.exist
157 expect(video.duration).to.equal(5) 166 expect(video.duration).to.equal(5)
167 expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ])
158 expect(utils.dateIsValid(video.createdDate)).to.be.true 168 expect(utils.dateIsValid(video.createdDate)).to.be.true
159 169
160 if (server.url !== 'http://localhost:9002') { 170 if (server.url !== 'http://localhost:9002') {
@@ -187,10 +197,18 @@ describe('Test multiple pods', function () {
187 197
188 async.series([ 198 async.series([
189 function (next) { 199 function (next) {
190 utils.uploadVideo(servers[2].url, servers[2].accessToken, 'my super name for pod 3', 'my super description for pod 3', 'video_short3.webm', next) 200 const name = 'my super name for pod 3'
201 const description = 'my super description for pod 3'
202 const tags = [ 'tag1p3' ]
203 const file = 'video_short3.webm'
204 utils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next)
191 }, 205 },
192 function (next) { 206 function (next) {
193 utils.uploadVideo(servers[2].url, servers[2].accessToken, 'my super name for pod 3-2', 'my super description for pod 3-2', 'video_short.webm', next) 207 const name = 'my super name for pod 3-2'
208 const description = 'my super description for pod 3-2'
209 const tags = [ 'tag2p3', 'tag3p3', 'tag4p3' ]
210 const file = 'video_short.webm'
211 utils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next)
194 }, 212 },
195 function (next) { 213 function (next) {
196 setTimeout(next, 22000) 214 setTimeout(next, 22000)
@@ -224,6 +242,7 @@ describe('Test multiple pods', function () {
224 expect(video1.podUrl).to.equal('localhost:9003') 242 expect(video1.podUrl).to.equal('localhost:9003')
225 expect(video1.magnetUri).to.exist 243 expect(video1.magnetUri).to.exist
226 expect(video1.duration).to.equal(5) 244 expect(video1.duration).to.equal(5)
245 expect(video1.tags).to.deep.equal([ 'tag1p3' ])
227 expect(utils.dateIsValid(video1.createdDate)).to.be.true 246 expect(utils.dateIsValid(video1.createdDate)).to.be.true
228 247
229 expect(video2.name).to.equal('my super name for pod 3-2') 248 expect(video2.name).to.equal('my super name for pod 3-2')
@@ -231,6 +250,7 @@ describe('Test multiple pods', function () {
231 expect(video2.podUrl).to.equal('localhost:9003') 250 expect(video2.podUrl).to.equal('localhost:9003')
232 expect(video2.magnetUri).to.exist 251 expect(video2.magnetUri).to.exist
233 expect(video2.duration).to.equal(5) 252 expect(video2.duration).to.equal(5)
253 expect(video2.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ])
234 expect(utils.dateIsValid(video2.createdDate)).to.be.true 254 expect(utils.dateIsValid(video2.createdDate)).to.be.true
235 255
236 if (server.url !== 'http://localhost:9003') { 256 if (server.url !== 'http://localhost:9003') {
diff --git a/server/tests/api/singlePod.js b/server/tests/api/singlePod.js
index 296dd0aa4..ef882b080 100644
--- a/server/tests/api/singlePod.js
+++ b/server/tests/api/singlePod.js
@@ -57,7 +57,11 @@ describe('Test a single pod', function () {
57 57
58 it('Should upload the video', function (done) { 58 it('Should upload the video', function (done) {
59 this.timeout(5000) 59 this.timeout(5000)
60 utils.uploadVideo(server.url, server.accessToken, 'my super name', 'my super description', 'video_short.webm', done) 60 const name = 'my super name'
61 const description = 'my super description'
62 const tags = [ 'tag1', 'tag2', 'tag3' ]
63 const file = 'video_short.webm'
64 utils.uploadVideo(server.url, server.accessToken, name, description, tags, file, done)
61 }) 65 })
62 66
63 it('Should seed the uploaded video', function (done) { 67 it('Should seed the uploaded video', function (done) {
@@ -78,6 +82,7 @@ describe('Test a single pod', function () {
78 expect(video.magnetUri).to.exist 82 expect(video.magnetUri).to.exist
79 expect(video.author).to.equal('root') 83 expect(video.author).to.equal('root')
80 expect(video.isLocal).to.be.true 84 expect(video.isLocal).to.be.true
85 expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
81 expect(utils.dateIsValid(video.createdDate)).to.be.true 86 expect(utils.dateIsValid(video.createdDate)).to.be.true
82 87
83 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { 88 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
@@ -112,6 +117,7 @@ describe('Test a single pod', function () {
112 expect(video.magnetUri).to.exist 117 expect(video.magnetUri).to.exist
113 expect(video.author).to.equal('root') 118 expect(video.author).to.equal('root')
114 expect(video.isLocal).to.be.true 119 expect(video.isLocal).to.be.true
120 expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
115 expect(utils.dateIsValid(video.createdDate)).to.be.true 121 expect(utils.dateIsValid(video.createdDate)).to.be.true
116 122
117 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { 123 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
@@ -143,6 +149,7 @@ describe('Test a single pod', function () {
143 expect(video.podUrl).to.equal('localhost:9001') 149 expect(video.podUrl).to.equal('localhost:9001')
144 expect(video.author).to.equal('root') 150 expect(video.author).to.equal('root')
145 expect(video.isLocal).to.be.true 151 expect(video.isLocal).to.be.true
152 expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
146 expect(utils.dateIsValid(video.createdDate)).to.be.true 153 expect(utils.dateIsValid(video.createdDate)).to.be.true
147 154
148 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { 155 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
@@ -168,6 +175,7 @@ describe('Test a single pod', function () {
168 expect(video.podUrl).to.equal('localhost:9001') 175 expect(video.podUrl).to.equal('localhost:9001')
169 expect(video.author).to.equal('root') 176 expect(video.author).to.equal('root')
170 expect(video.isLocal).to.be.true 177 expect(video.isLocal).to.be.true
178 expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
171 expect(utils.dateIsValid(video.createdDate)).to.be.true 179 expect(utils.dateIsValid(video.createdDate)).to.be.true
172 180
173 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { 181 utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) {
@@ -235,7 +243,11 @@ describe('Test a single pod', function () {
235 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' 243 'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
236 ] 244 ]
237 async.each(videos, function (video, callbackEach) { 245 async.each(videos, function (video, callbackEach) {
238 utils.uploadVideo(server.url, server.accessToken, video + ' name', video + ' description', video, callbackEach) 246 const name = video + ' name'
247 const description = video + ' description'
248 const tags = [ 'tag1', 'tag2', 'tag3' ]
249
250 utils.uploadVideo(server.url, server.accessToken, name, description, tags, video, callbackEach)
239 }, done) 251 }, done)
240 }) 252 })
241 253
diff --git a/server/tests/api/users.js b/server/tests/api/users.js
index 9ab5083a0..7ab426d85 100644
--- a/server/tests/api/users.js
+++ b/server/tests/api/users.js
@@ -79,7 +79,12 @@ describe('Test users', function () {
79 79
80 it('Should not be able to upload a video', function (done) { 80 it('Should not be able to upload a video', function (done) {
81 accessToken = 'mysupertoken' 81 accessToken = 'mysupertoken'
82 utils.uploadVideo(server.url, accessToken, 'my super name', 'my super description', 'video_short.webm', 401, done) 82
83 const name = 'my super name'
84 const description = 'my super description'
85 const tags = [ 'tag1', 'tag2' ]
86 const video = 'video_short.webm'
87 utils.uploadVideo(server.url, accessToken, name, description, tags, video, 401, done)
83 }) 88 })
84 89
85 it('Should not be able to make friends', function (done) { 90 it('Should not be able to make friends', function (done) {
@@ -102,7 +107,11 @@ describe('Test users', function () {
102 }) 107 })
103 108
104 it('Should upload the video with the correct token', function (done) { 109 it('Should upload the video with the correct token', function (done) {
105 utils.uploadVideo(server.url, accessToken, 'my super name', 'my super description', 'video_short.webm', 204, function (err, res) { 110 const name = 'my super name'
111 const description = 'my super description'
112 const tags = [ 'tag1', 'tag2' ]
113 const video = 'video_short.webm'
114 utils.uploadVideo(server.url, accessToken, name, description, tags, video, 204, function (err, res) {
106 if (err) throw err 115 if (err) throw err
107 116
108 utils.getVideosList(server.url, function (err, res) { 117 utils.getVideosList(server.url, function (err, res) {
@@ -118,7 +127,11 @@ describe('Test users', function () {
118 }) 127 })
119 128
120 it('Should upload the video again with the correct token', function (done) { 129 it('Should upload the video again with the correct token', function (done) {
121 utils.uploadVideo(server.url, accessToken, 'my super name 2', 'my super description 2', 'video_short.webm', 204, done) 130 const name = 'my super name 2'
131 const description = 'my super description 2'
132 const tags = [ 'tag1' ]
133 const video = 'video_short.webm'
134 utils.uploadVideo(server.url, accessToken, name, description, tags, video, 204, done)
122 }) 135 })
123 136
124 it('Should not be able to remove the video with an incorrect token', function (done) { 137 it('Should not be able to remove the video with an incorrect token', function (done) {
diff --git a/server/tests/api/utils.js b/server/tests/api/utils.js
index c6430c930..e0068eada 100644
--- a/server/tests/api/utils.js
+++ b/server/tests/api/utils.js
@@ -349,7 +349,7 @@ function testImage (url, videoName, imagePath, callback) {
349 }) 349 })
350} 350}
351 351
352function uploadVideo (url, accessToken, name, description, fixture, specialStatus, end) { 352function uploadVideo (url, accessToken, name, description, tags, fixture, specialStatus, end) {
353 if (!end) { 353 if (!end) {
354 end = specialStatus 354 end = specialStatus
355 specialStatus = 204 355 specialStatus = 204
@@ -357,15 +357,20 @@ function uploadVideo (url, accessToken, name, description, fixture, specialStatu
357 357
358 const path = '/api/v1/videos' 358 const path = '/api/v1/videos'
359 359
360 request(url) 360 const req = request(url)
361 .post(path) 361 .post(path)
362 .set('Accept', 'application/json') 362 .set('Accept', 'application/json')
363 .set('Authorization', 'Bearer ' + accessToken) 363 .set('Authorization', 'Bearer ' + accessToken)
364 .field('name', name) 364 .field('name', name)
365 .field('description', description) 365 .field('description', description)
366 .attach('videofile', pathUtils.join(__dirname, 'fixtures', fixture)) 366
367 .expect(specialStatus) 367 for (let i = 0; i < tags.length; i++) {
368 .end(end) 368 req.field('tags[' + i + ']', tags[i])
369 }
370
371 req.attach('videofile', pathUtils.join(__dirname, 'fixtures', fixture))
372 .expect(specialStatus)
373 .end(end)
369} 374}
370 375
371// --------------------------------------------------------------------------- 376// ---------------------------------------------------------------------------