aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/controllers/api/v1/videos.js10
-rw-r--r--server/initializers/constants.js6
-rw-r--r--server/middlewares/index.js2
-rw-r--r--server/middlewares/reqValidators/index.js2
-rw-r--r--server/middlewares/reqValidators/pagination.js6
-rw-r--r--server/middlewares/reqValidators/sort.js23
-rw-r--r--server/middlewares/sort.js15
-rw-r--r--server/models/videos.js9
-rw-r--r--server/tests/api/checkParams.js50
-rw-r--r--server/tests/api/singlePod.js33
-rw-r--r--server/tests/api/utils.js26
11 files changed, 173 insertions, 9 deletions
diff --git a/server/controllers/api/v1/videos.js b/server/controllers/api/v1/videos.js
index c6dbfbaf2..73e496ace 100644
--- a/server/controllers/api/v1/videos.js
+++ b/server/controllers/api/v1/videos.js
@@ -15,7 +15,9 @@ const oAuth2 = middlewares.oauth2
15const pagination = middlewares.pagination 15const pagination = middlewares.pagination
16const reqValidator = middlewares.reqValidators 16const reqValidator = middlewares.reqValidators
17const reqValidatorPagination = reqValidator.pagination 17const reqValidatorPagination = reqValidator.pagination
18const reqValidatorSort = reqValidator.sort
18const reqValidatorVideos = reqValidator.videos 19const reqValidatorVideos = reqValidator.videos
20const sort = middlewares.sort
19const utils = require('../../../helpers/utils') 21const utils = require('../../../helpers/utils')
20const Videos = require('../../../models/videos') // model 22const Videos = require('../../../models/videos') // model
21const videos = require('../../../lib/videos') 23const videos = require('../../../lib/videos')
@@ -47,6 +49,8 @@ const thumbnailsDir = path.join(__dirname, '..', '..', '..', '..', config.get('s
47 49
48router.get('/', 50router.get('/',
49 reqValidatorPagination.pagination, 51 reqValidatorPagination.pagination,
52 reqValidatorSort.videosSort,
53 sort.setVideosSort,
50 pagination.setPagination, 54 pagination.setPagination,
51 listVideos 55 listVideos
52) 56)
@@ -68,6 +72,8 @@ router.delete('/:id',
68router.get('/search/:name', 72router.get('/search/:name',
69 reqValidatorVideos.videosSearch, 73 reqValidatorVideos.videosSearch,
70 reqValidatorPagination.pagination, 74 reqValidatorPagination.pagination,
75 reqValidatorSort.videosSort,
76 sort.setVideosSort,
71 pagination.setPagination, 77 pagination.setPagination,
72 searchVideos 78 searchVideos
73) 79)
@@ -173,7 +179,7 @@ function getVideos (req, res, next) {
173} 179}
174 180
175function listVideos (req, res, next) { 181function listVideos (req, res, next) {
176 Videos.list(req.query.start, req.query.count, function (err, videosList) { 182 Videos.list(req.query.start, req.query.count, req.query.sort, function (err, videosList) {
177 if (err) return next(err) 183 if (err) return next(err)
178 184
179 res.json(getFormatedVideos(videosList)) 185 res.json(getFormatedVideos(videosList))
@@ -231,7 +237,7 @@ function removeVideo (req, res, next) {
231} 237}
232 238
233function searchVideos (req, res, next) { 239function searchVideos (req, res, next) {
234 Videos.search(req.params.name, req.query.start, req.query.count, function (err, videosList) { 240 Videos.search(req.params.name, req.query.start, req.query.count, req.query.sort, function (err, videosList) {
235 if (err) return next(err) 241 if (err) return next(err)
236 242
237 res.json(getFormatedVideos(videosList)) 243 res.json(getFormatedVideos(videosList))
diff --git a/server/initializers/constants.js b/server/initializers/constants.js
index 78bee5efe..4350bb892 100644
--- a/server/initializers/constants.js
+++ b/server/initializers/constants.js
@@ -26,6 +26,11 @@ const PODS_SCORE = {
26// Number of retries we make for the make retry requests (to friends...) 26// Number of retries we make for the make retry requests (to friends...)
27let REQUEST_RETRIES = 10 27let REQUEST_RETRIES = 10
28 28
29// Sortable columns per schema
30const SORTABLE_COLUMNS = {
31 VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ]
32}
33
29// Videos thumbnail size 34// Videos thumbnail size
30const THUMBNAILS_SIZE = '200x110' 35const THUMBNAILS_SIZE = '200x110'
31 36
@@ -51,6 +56,7 @@ module.exports = {
51 PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT, 56 PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT,
52 PODS_SCORE: PODS_SCORE, 57 PODS_SCORE: PODS_SCORE,
53 REQUEST_RETRIES: REQUEST_RETRIES, 58 REQUEST_RETRIES: REQUEST_RETRIES,
59 SORTABLE_COLUMNS: SORTABLE_COLUMNS,
54 THUMBNAILS_SIZE: THUMBNAILS_SIZE, 60 THUMBNAILS_SIZE: THUMBNAILS_SIZE,
55 THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH 61 THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH
56} 62}
diff --git a/server/middlewares/index.js b/server/middlewares/index.js
index f0fad3418..35858da2c 100644
--- a/server/middlewares/index.js
+++ b/server/middlewares/index.js
@@ -3,12 +3,14 @@
3const oauth2 = require('./oauth2') 3const oauth2 = require('./oauth2')
4const pagination = require('./pagination') 4const pagination = require('./pagination')
5const reqValidatorsMiddleware = require('./reqValidators') 5const reqValidatorsMiddleware = require('./reqValidators')
6const sort = require('./sort')
6const secureMiddleware = require('./secure') 7const secureMiddleware = require('./secure')
7 8
8const middlewares = { 9const middlewares = {
9 oauth2: oauth2, 10 oauth2: oauth2,
10 pagination: pagination, 11 pagination: pagination,
11 reqValidators: reqValidatorsMiddleware, 12 reqValidators: reqValidatorsMiddleware,
13 sort: sort,
12 secure: secureMiddleware 14 secure: secureMiddleware
13} 15}
14 16
diff --git a/server/middlewares/reqValidators/index.js b/server/middlewares/reqValidators/index.js
index b732a27b6..be68f6a29 100644
--- a/server/middlewares/reqValidators/index.js
+++ b/server/middlewares/reqValidators/index.js
@@ -3,12 +3,14 @@
3const paginationReqValidators = require('./pagination') 3const paginationReqValidators = require('./pagination')
4const podsReqValidators = require('./pods') 4const podsReqValidators = require('./pods')
5const remoteReqValidators = require('./remote') 5const remoteReqValidators = require('./remote')
6const sortReqValidators = require('./sort')
6const videosReqValidators = require('./videos') 7const videosReqValidators = require('./videos')
7 8
8const reqValidators = { 9const reqValidators = {
9 pagination: paginationReqValidators, 10 pagination: paginationReqValidators,
10 pods: podsReqValidators, 11 pods: podsReqValidators,
11 remote: remoteReqValidators, 12 remote: remoteReqValidators,
13 sort: sortReqValidators,
12 videos: videosReqValidators 14 videos: videosReqValidators
13} 15}
14 16
diff --git a/server/middlewares/reqValidators/pagination.js b/server/middlewares/reqValidators/pagination.js
index ca8375396..e598f269a 100644
--- a/server/middlewares/reqValidators/pagination.js
+++ b/server/middlewares/reqValidators/pagination.js
@@ -8,10 +8,10 @@ const reqValidatorsPagination = {
8} 8}
9 9
10function pagination (req, res, next) { 10function pagination (req, res, next) {
11 req.checkParams('start', 'Should have a number start').optional().isInt() 11 req.checkQuery('start', 'Should have a number start').optional().isInt()
12 req.checkParams('count', 'Should have a number count').optional().isInt() 12 req.checkQuery('count', 'Should have a number count').optional().isInt()
13 13
14 logger.debug('Checking pagination parameters', { parameters: req.params }) 14 logger.debug('Checking pagination parameters', { parameters: req.query })
15 15
16 checkErrors(req, res, next) 16 checkErrors(req, res, next)
17} 17}
diff --git a/server/middlewares/reqValidators/sort.js b/server/middlewares/reqValidators/sort.js
new file mode 100644
index 000000000..06e680ef4
--- /dev/null
+++ b/server/middlewares/reqValidators/sort.js
@@ -0,0 +1,23 @@
1'use strict'
2
3const checkErrors = require('./utils').checkErrors
4const constants = require('../../initializers/constants')
5const logger = require('../../helpers/logger')
6
7const reqValidatorsSort = {
8 videosSort: videosSort
9}
10
11function videosSort (req, res, next) {
12 const sortableColumns = constants.SORTABLE_COLUMNS.VIDEOS
13
14 req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns)
15
16 logger.debug('Checking sort parameters', { parameters: req.query })
17
18 checkErrors(req, res, next)
19}
20
21// ---------------------------------------------------------------------------
22
23module.exports = reqValidatorsSort
diff --git a/server/middlewares/sort.js b/server/middlewares/sort.js
new file mode 100644
index 000000000..9f52290a6
--- /dev/null
+++ b/server/middlewares/sort.js
@@ -0,0 +1,15 @@
1'use strict'
2
3const sortMiddleware = {
4 setVideosSort: setVideosSort
5}
6
7function setVideosSort (req, res, next) {
8 if (!req.query.sort) req.query.sort = '-createdDate'
9
10 return next()
11}
12
13// ---------------------------------------------------------------------------
14
15module.exports = sortMiddleware
diff --git a/server/models/videos.js b/server/models/videos.js
index 250ad3952..9cac8edda 100644
--- a/server/models/videos.js
+++ b/server/models/videos.js
@@ -80,8 +80,9 @@ function get (id, callback) {
80 }) 80 })
81} 81}
82 82
83function list (start, count, callback) { 83function list (start, count, sort, callback) {
84 VideosDB.find({}).skip(start).limit(start + count).exec(function (err, videosList) { 84 VideosDB.find({}).skip(start).limit(start + count).sort(sort)
85 .exec(function (err, videosList) {
85 if (err) { 86 if (err) {
86 logger.error('Cannot get the list of the videos.') 87 logger.error('Cannot get the list of the videos.')
87 return callback(err) 88 return callback(err)
@@ -129,8 +130,8 @@ function removeByIds (ids, callback) {
129 VideosDB.remove({ _id: { $in: ids } }, callback) 130 VideosDB.remove({ _id: { $in: ids } }, callback)
130} 131}
131 132
132function search (name, start, count, callback) { 133function search (name, start, count, sort, callback) {
133 VideosDB.find({ name: new RegExp(name) }).skip(start).limit(start + count) 134 VideosDB.find({ name: new RegExp(name) }).skip(start).limit(start + count).sort(sort)
134 .exec(function (err, videos) { 135 .exec(function (err, videos) {
135 if (err) { 136 if (err) {
136 logger.error('Cannot search the videos.') 137 logger.error('Cannot search the videos.')
diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js
index b63091910..a109aba47 100644
--- a/server/tests/api/checkParams.js
+++ b/server/tests/api/checkParams.js
@@ -130,6 +130,32 @@ describe('Test parameters validator', function () {
130 describe('Of the videos API', function () { 130 describe('Of the videos API', function () {
131 const path = '/api/v1/videos/' 131 const path = '/api/v1/videos/'
132 132
133 describe('When listing a video', function () {
134 it('Should fail with a bad start pagination', function (done) {
135 request(server.url)
136 .get(path)
137 .query({ start: 'hello' })
138 .set('Accept', 'application/json')
139 .expect(400, done)
140 })
141
142 it('Should fail with a bad count pagination', function (done) {
143 request(server.url)
144 .get(path)
145 .query({ count: 'hello' })
146 .set('Accept', 'application/json')
147 .expect(400, done)
148 })
149
150 it('Should fail with an incorrect sort', function (done) {
151 request(server.url)
152 .get(path)
153 .query({ sort: 'hello' })
154 .set('Accept', 'application/json')
155 .expect(400, done)
156 })
157 })
158
133 describe('When searching a video', function () { 159 describe('When searching a video', function () {
134 it('Should fail with nothing', function (done) { 160 it('Should fail with nothing', function (done) {
135 request(server.url) 161 request(server.url)
@@ -137,6 +163,30 @@ describe('Test parameters validator', function () {
137 .set('Accept', 'application/json') 163 .set('Accept', 'application/json')
138 .expect(400, done) 164 .expect(400, done)
139 }) 165 })
166
167 it('Should fail with a bad start pagination', function (done) {
168 request(server.url)
169 .get(pathUtils.join(path, 'search', 'test'))
170 .query({ start: 'hello' })
171 .set('Accept', 'application/json')
172 .expect(400, done)
173 })
174
175 it('Should fail with a bad count pagination', function (done) {
176 request(server.url)
177 .get(pathUtils.join(path, 'search', 'test'))
178 .query({ count: 'hello' })
179 .set('Accept', 'application/json')
180 .expect(400, done)
181 })
182
183 it('Should fail with an incorrect sort', function (done) {
184 request(server.url)
185 .get(pathUtils.join(path, 'search', 'test'))
186 .query({ sort: 'hello' })
187 .set('Accept', 'application/json')
188 .expect(400, done)
189 })
140 }) 190 })
141 191
142 describe('When adding a video', function () { 192 describe('When adding a video', function () {
diff --git a/server/tests/api/singlePod.js b/server/tests/api/singlePod.js
index 72002b631..1a53ada3a 100644
--- a/server/tests/api/singlePod.js
+++ b/server/tests/api/singlePod.js
@@ -314,6 +314,39 @@ describe('Test a single pod', function () {
314 }) 314 })
315 }) 315 })
316 316
317 it('Should list and sort by name in descending order', function (done) {
318 utils.getVideosListSort(server.url, '-name', function (err, res) {
319 if (err) throw err
320
321 const videos = res.body
322 expect(videos.length).to.equal(6)
323 expect(videos[5].name === 'video_short.mp4 name')
324 expect(videos[4].name === 'video_short.ogv name')
325 expect(videos[3].name === 'video_short.webm name')
326 expect(videos[2].name === 'video_short1.webm name')
327 expect(videos[1].name === 'video_short2.webm name')
328 expect(videos[0].name === 'video_short3.webm name')
329
330 done()
331 })
332 })
333
334 it('Should search and sort by name in ascending order', function (done) {
335 utils.searchVideoWithSort(server.url, 'webm', 'name', function (err, res) {
336 if (err) throw err
337
338 const videos = res.body
339 expect(videos.length).to.equal(4)
340
341 expect(videos[0].name === 'video_short.webm name')
342 expect(videos[1].name === 'video_short1.webm name')
343 expect(videos[2].name === 'video_short2.webm name')
344 expect(videos[3].name === 'video_short3.webm name')
345
346 done()
347 })
348 })
349
317 after(function (done) { 350 after(function (done) {
318 process.kill(-server.app.pid) 351 process.kill(-server.app.pid)
319 process.kill(-webtorrent.app.pid) 352 process.kill(-webtorrent.app.pid)
diff --git a/server/tests/api/utils.js b/server/tests/api/utils.js
index d505cb5d9..ac43946cd 100644
--- a/server/tests/api/utils.js
+++ b/server/tests/api/utils.js
@@ -14,6 +14,7 @@ const testUtils = {
14 getVideo: getVideo, 14 getVideo: getVideo,
15 getVideosList: getVideosList, 15 getVideosList: getVideosList,
16 getVideosListPagination: getVideosListPagination, 16 getVideosListPagination: getVideosListPagination,
17 getVideosListSort: getVideosListSort,
17 login: login, 18 login: login,
18 loginAndGetAccessToken: loginAndGetAccessToken, 19 loginAndGetAccessToken: loginAndGetAccessToken,
19 makeFriends: makeFriends, 20 makeFriends: makeFriends,
@@ -23,6 +24,7 @@ const testUtils = {
23 runServer: runServer, 24 runServer: runServer,
24 searchVideo: searchVideo, 25 searchVideo: searchVideo,
25 searchVideoWithPagination: searchVideoWithPagination, 26 searchVideoWithPagination: searchVideoWithPagination,
27 searchVideoWithSort: searchVideoWithSort,
26 testImage: testImage, 28 testImage: testImage,
27 uploadVideo: uploadVideo 29 uploadVideo: uploadVideo
28} 30}
@@ -89,6 +91,18 @@ function getVideosListPagination (url, start, count, end) {
89 .end(end) 91 .end(end)
90} 92}
91 93
94function getVideosListSort (url, sort, end) {
95 const path = '/api/v1/videos'
96
97 request(url)
98 .get(path)
99 .query({ sort: sort })
100 .set('Accept', 'application/json')
101 .expect(200)
102 .expect('Content-Type', /json/)
103 .end(end)
104}
105
92function login (url, client, user, expectedStatus, end) { 106function login (url, client, user, expectedStatus, end) {
93 if (!end) { 107 if (!end) {
94 end = expectedStatus 108 end = expectedStatus
@@ -300,6 +314,18 @@ function searchVideoWithPagination (url, search, start, count, end) {
300 .end(end) 314 .end(end)
301} 315}
302 316
317function searchVideoWithSort (url, search, sort, end) {
318 const path = '/api/v1/videos'
319
320 request(url)
321 .get(path + '/search/' + search)
322 .query({ sort: sort })
323 .set('Accept', 'application/json')
324 .expect(200)
325 .expect('Content-Type', /json/)
326 .end(end)
327}
328
303function testImage (url, videoName, imagePath, callback) { 329function testImage (url, videoName, imagePath, callback) {
304 request(url) 330 request(url)
305 .get(imagePath) 331 .get(imagePath)