diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2016-05-13 18:10:46 +0200 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2016-05-13 18:10:46 +0200 |
commit | fbf1134e3e6b386c9ec5a3946c61f3faf84397fb (patch) | |
tree | 9071ea72c86e83bb07d8ec681a54daff2e0eb7b9 | |
parent | f67e976fdccbfe6432c1176148d194c980a5585a (diff) | |
download | PeerTube-fbf1134e3e6b386c9ec5a3946c61f3faf84397fb.tar.gz PeerTube-fbf1134e3e6b386c9ec5a3946c61f3faf84397fb.tar.zst PeerTube-fbf1134e3e6b386c9ec5a3946c61f3faf84397fb.zip |
Introduce paginations in videos listing
-rw-r--r-- | server/controllers/api/v1/videos.js | 40 | ||||
-rw-r--r-- | server/middlewares/index.js | 2 | ||||
-rw-r--r-- | server/middlewares/pagination.js | 18 | ||||
-rw-r--r-- | server/middlewares/reqValidators/index.js | 2 | ||||
-rw-r--r-- | server/middlewares/reqValidators/pagination.js | 21 | ||||
-rw-r--r-- | server/models/videos.js | 9 | ||||
-rw-r--r-- | server/tests/api/singlePod.js | 80 | ||||
-rw-r--r-- | server/tests/api/utils.js | 28 |
8 files changed, 188 insertions, 12 deletions
diff --git a/server/controllers/api/v1/videos.js b/server/controllers/api/v1/videos.js index b6e3de08f..0e058836e 100644 --- a/server/controllers/api/v1/videos.js +++ b/server/controllers/api/v1/videos.js | |||
@@ -11,7 +11,10 @@ const logger = require('../../../helpers/logger') | |||
11 | const friends = require('../../../lib/friends') | 11 | const friends = require('../../../lib/friends') |
12 | const middlewares = require('../../../middlewares') | 12 | const middlewares = require('../../../middlewares') |
13 | const oAuth2 = middlewares.oauth2 | 13 | const oAuth2 = middlewares.oauth2 |
14 | const reqValidator = middlewares.reqValidators.videos | 14 | const pagination = middlewares.pagination |
15 | const reqValidator = middlewares.reqValidators | ||
16 | const reqValidatorPagination = reqValidator.pagination | ||
17 | const reqValidatorVideos = reqValidator.videos | ||
15 | const utils = require('../../../helpers/utils') | 18 | const utils = require('../../../helpers/utils') |
16 | const Videos = require('../../../models/videos') // model | 19 | const Videos = require('../../../models/videos') // model |
17 | const videos = require('../../../lib/videos') | 20 | const videos = require('../../../lib/videos') |
@@ -41,11 +44,32 @@ const storage = multer.diskStorage({ | |||
41 | const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }]) | 44 | const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }]) |
42 | const thumbnailsDir = path.join(__dirname, '..', '..', '..', '..', config.get('storage.thumbnails')) | 45 | const thumbnailsDir = path.join(__dirname, '..', '..', '..', '..', config.get('storage.thumbnails')) |
43 | 46 | ||
44 | router.get('/', listVideos) | 47 | router.get('/', |
45 | router.post('/', oAuth2.authenticate, reqFiles, reqValidator.videosAdd, addVideo) | 48 | reqValidatorPagination.pagination, |
46 | router.get('/:id', reqValidator.videosGet, getVideos) | 49 | pagination.setPagination, |
47 | router.delete('/:id', oAuth2.authenticate, reqValidator.videosRemove, removeVideo) | 50 | listVideos |
48 | router.get('/search/:name', reqValidator.videosSearch, searchVideos) | 51 | ) |
52 | router.post('/', | ||
53 | oAuth2.authenticate, | ||
54 | reqFiles, | ||
55 | reqValidatorVideos.videosAdd, | ||
56 | addVideo | ||
57 | ) | ||
58 | router.get('/:id', | ||
59 | reqValidatorVideos.videosGet, | ||
60 | getVideos | ||
61 | ) | ||
62 | router.delete('/:id', | ||
63 | oAuth2.authenticate, | ||
64 | reqValidatorVideos.videosRemove, | ||
65 | removeVideo | ||
66 | ) | ||
67 | router.get('/search/:name', | ||
68 | reqValidatorVideos.videosSearch, | ||
69 | reqValidatorPagination.pagination, | ||
70 | pagination.setPagination, | ||
71 | searchVideos | ||
72 | ) | ||
49 | 73 | ||
50 | // --------------------------------------------------------------------------- | 74 | // --------------------------------------------------------------------------- |
51 | 75 | ||
@@ -129,7 +153,7 @@ function getVideos (req, res, next) { | |||
129 | } | 153 | } |
130 | 154 | ||
131 | function listVideos (req, res, next) { | 155 | function listVideos (req, res, next) { |
132 | Videos.list(function (err, videosList) { | 156 | Videos.list(req.query.start, req.query.count, function (err, videosList) { |
133 | if (err) return next(err) | 157 | if (err) return next(err) |
134 | 158 | ||
135 | res.json(getFormatedVideos(videosList)) | 159 | res.json(getFormatedVideos(videosList)) |
@@ -162,7 +186,7 @@ function removeVideo (req, res, next) { | |||
162 | } | 186 | } |
163 | 187 | ||
164 | function searchVideos (req, res, next) { | 188 | function searchVideos (req, res, next) { |
165 | Videos.search(req.params.name, function (err, videosList) { | 189 | Videos.search(req.params.name, req.query.start, req.query.count, function (err, videosList) { |
166 | if (err) return next(err) | 190 | if (err) return next(err) |
167 | 191 | ||
168 | res.json(getFormatedVideos(videosList)) | 192 | res.json(getFormatedVideos(videosList)) |
diff --git a/server/middlewares/index.js b/server/middlewares/index.js index ffd19337c..f0fad3418 100644 --- a/server/middlewares/index.js +++ b/server/middlewares/index.js | |||
@@ -1,11 +1,13 @@ | |||
1 | 'use strict' | 1 | 'use strict' |
2 | 2 | ||
3 | const oauth2 = require('./oauth2') | 3 | const oauth2 = require('./oauth2') |
4 | const pagination = require('./pagination') | ||
4 | const reqValidatorsMiddleware = require('./reqValidators') | 5 | const reqValidatorsMiddleware = require('./reqValidators') |
5 | const secureMiddleware = require('./secure') | 6 | const secureMiddleware = require('./secure') |
6 | 7 | ||
7 | const middlewares = { | 8 | const middlewares = { |
8 | oauth2: oauth2, | 9 | oauth2: oauth2, |
10 | pagination: pagination, | ||
9 | reqValidators: reqValidatorsMiddleware, | 11 | reqValidators: reqValidatorsMiddleware, |
10 | secure: secureMiddleware | 12 | secure: secureMiddleware |
11 | } | 13 | } |
diff --git a/server/middlewares/pagination.js b/server/middlewares/pagination.js new file mode 100644 index 000000000..2a426ec28 --- /dev/null +++ b/server/middlewares/pagination.js | |||
@@ -0,0 +1,18 @@ | |||
1 | 'use strict' | ||
2 | |||
3 | const paginationMiddleware = { | ||
4 | setPagination: setPagination | ||
5 | } | ||
6 | |||
7 | function setPagination (req, res, next) { | ||
8 | if (!req.query.start) req.query.start = 0 | ||
9 | else req.query.start = parseInt(req.query.start) | ||
10 | if (!req.query.count) req.query.count = 15 | ||
11 | else req.query.count = parseInt(req.query.count) | ||
12 | |||
13 | return next() | ||
14 | } | ||
15 | |||
16 | // --------------------------------------------------------------------------- | ||
17 | |||
18 | module.exports = paginationMiddleware | ||
diff --git a/server/middlewares/reqValidators/index.js b/server/middlewares/reqValidators/index.js index c6c5e1309..b732a27b6 100644 --- a/server/middlewares/reqValidators/index.js +++ b/server/middlewares/reqValidators/index.js | |||
@@ -1,10 +1,12 @@ | |||
1 | 'use strict' | 1 | 'use strict' |
2 | 2 | ||
3 | const paginationReqValidators = require('./pagination') | ||
3 | const podsReqValidators = require('./pods') | 4 | const podsReqValidators = require('./pods') |
4 | const remoteReqValidators = require('./remote') | 5 | const remoteReqValidators = require('./remote') |
5 | const videosReqValidators = require('./videos') | 6 | const videosReqValidators = require('./videos') |
6 | 7 | ||
7 | const reqValidators = { | 8 | const reqValidators = { |
9 | pagination: paginationReqValidators, | ||
8 | pods: podsReqValidators, | 10 | pods: podsReqValidators, |
9 | remote: remoteReqValidators, | 11 | remote: remoteReqValidators, |
10 | videos: videosReqValidators | 12 | videos: videosReqValidators |
diff --git a/server/middlewares/reqValidators/pagination.js b/server/middlewares/reqValidators/pagination.js new file mode 100644 index 000000000..ca8375396 --- /dev/null +++ b/server/middlewares/reqValidators/pagination.js | |||
@@ -0,0 +1,21 @@ | |||
1 | 'use strict' | ||
2 | |||
3 | const checkErrors = require('./utils').checkErrors | ||
4 | const logger = require('../../helpers/logger') | ||
5 | |||
6 | const reqValidatorsPagination = { | ||
7 | pagination: pagination | ||
8 | } | ||
9 | |||
10 | function pagination (req, res, next) { | ||
11 | req.checkParams('start', 'Should have a number start').optional().isInt() | ||
12 | req.checkParams('count', 'Should have a number count').optional().isInt() | ||
13 | |||
14 | logger.debug('Checking pagination parameters', { parameters: req.params }) | ||
15 | |||
16 | checkErrors(req, res, next) | ||
17 | } | ||
18 | |||
19 | // --------------------------------------------------------------------------- | ||
20 | |||
21 | module.exports = reqValidatorsPagination | ||
diff --git a/server/models/videos.js b/server/models/videos.js index eaea35b7f..aa9ed687d 100644 --- a/server/models/videos.js +++ b/server/models/videos.js | |||
@@ -76,8 +76,8 @@ function get (id, callback) { | |||
76 | }) | 76 | }) |
77 | } | 77 | } |
78 | 78 | ||
79 | function list (callback) { | 79 | function list (start, count, callback) { |
80 | VideosDB.find(function (err, videosList) { | 80 | VideosDB.find({}).skip(start).limit(start + count).exec(function (err, videosList) { |
81 | if (err) { | 81 | if (err) { |
82 | logger.error('Cannot get the list of the videos.') | 82 | logger.error('Cannot get the list of the videos.') |
83 | return callback(err) | 83 | return callback(err) |
@@ -125,8 +125,9 @@ function removeByIds (ids, callback) { | |||
125 | VideosDB.remove({ _id: { $in: ids } }, callback) | 125 | VideosDB.remove({ _id: { $in: ids } }, callback) |
126 | } | 126 | } |
127 | 127 | ||
128 | function search (name, callback) { | 128 | function search (name, start, count, callback) { |
129 | VideosDB.find({ name: new RegExp(name) }, function (err, videos) { | 129 | VideosDB.find({ name: new RegExp(name) }).skip(start).limit(start + count) |
130 | .exec(function (err, videos) { | ||
130 | if (err) { | 131 | if (err) { |
131 | logger.error('Cannot search the videos.') | 132 | logger.error('Cannot search the videos.') |
132 | return callback(err) | 133 | return callback(err) |
diff --git a/server/tests/api/singlePod.js b/server/tests/api/singlePod.js index 0d0e6a82e..d377bdf45 100644 --- a/server/tests/api/singlePod.js +++ b/server/tests/api/singlePod.js | |||
@@ -15,6 +15,7 @@ const utils = require('./utils') | |||
15 | describe('Test a single pod', function () { | 15 | describe('Test a single pod', function () { |
16 | let server = null | 16 | let server = null |
17 | let videoId = -1 | 17 | let videoId = -1 |
18 | let videosListBase = null | ||
18 | 19 | ||
19 | before(function (done) { | 20 | before(function (done) { |
20 | this.timeout(20000) | 21 | this.timeout(20000) |
@@ -215,7 +216,11 @@ describe('Test a single pod', function () { | |||
215 | 216 | ||
216 | it('Should have the correct thumbnails', function (done) { | 217 | it('Should have the correct thumbnails', function (done) { |
217 | utils.getVideosList(server.url, function (err, res) { | 218 | utils.getVideosList(server.url, function (err, res) { |
219 | if (err) throw err | ||
220 | |||
218 | const videos = res.body | 221 | const videos = res.body |
222 | // For the next test | ||
223 | videosListBase = videos | ||
219 | 224 | ||
220 | async.each(videos, function (video, callbackEach) { | 225 | async.each(videos, function (video, callbackEach) { |
221 | if (err) throw err | 226 | if (err) throw err |
@@ -231,6 +236,81 @@ describe('Test a single pod', function () { | |||
231 | }) | 236 | }) |
232 | }) | 237 | }) |
233 | 238 | ||
239 | it('Should list only the two first videos', function (done) { | ||
240 | utils.getVideosListPagination(server.url, 0, 2, function (err, res) { | ||
241 | if (err) throw err | ||
242 | |||
243 | const videos = res.body | ||
244 | expect(videos.length).to.equal(2) | ||
245 | expect(videos[0].name === videosListBase[0].name) | ||
246 | expect(videos[1].name === videosListBase[1].name) | ||
247 | |||
248 | done() | ||
249 | }) | ||
250 | }) | ||
251 | |||
252 | it('Should list only the next three videos', function (done) { | ||
253 | utils.getVideosListPagination(server.url, 2, 3, function (err, res) { | ||
254 | if (err) throw err | ||
255 | |||
256 | const videos = res.body | ||
257 | expect(videos.length).to.equal(4) | ||
258 | expect(videos[0].name === videosListBase[2].name) | ||
259 | expect(videos[1].name === videosListBase[3].name) | ||
260 | expect(videos[2].name === videosListBase[4].name) | ||
261 | |||
262 | done() | ||
263 | }) | ||
264 | }) | ||
265 | |||
266 | it('Should list the last video', function (done) { | ||
267 | utils.getVideosListPagination(server.url, 5, 6, function (err, res) { | ||
268 | if (err) throw err | ||
269 | |||
270 | const videos = res.body | ||
271 | expect(videos.length).to.equal(1) | ||
272 | expect(videos[0].name === videosListBase[5].name) | ||
273 | |||
274 | done() | ||
275 | }) | ||
276 | }) | ||
277 | |||
278 | it('Should search the first video', function (done) { | ||
279 | utils.searchVideoWithPagination(server.url, 'webm', 0, 1, function (err, res) { | ||
280 | if (err) throw err | ||
281 | |||
282 | const videos = res.body | ||
283 | expect(videos.length).to.equal(1) | ||
284 | expect(videos[0].name === 'video_short.webm name') | ||
285 | |||
286 | done() | ||
287 | }) | ||
288 | }) | ||
289 | |||
290 | it('Should search the last two videos', function (done) { | ||
291 | utils.searchVideoWithPagination(server.url, 'webm', 2, 2, function (err, res) { | ||
292 | if (err) throw err | ||
293 | |||
294 | const videos = res.body | ||
295 | expect(videos.length).to.equal(2) | ||
296 | expect(videos[0].name === 'video_short2.webm name') | ||
297 | expect(videos[1].name === 'video_short3.webm name') | ||
298 | |||
299 | done() | ||
300 | }) | ||
301 | }) | ||
302 | |||
303 | it('Should search all the videos', function (done) { | ||
304 | utils.searchVideoWithPagination(server.url, 'webm', 0, 15, function (err, res) { | ||
305 | if (err) throw err | ||
306 | |||
307 | const videos = res.body | ||
308 | expect(videos.length).to.equal(4) | ||
309 | |||
310 | done() | ||
311 | }) | ||
312 | }) | ||
313 | |||
234 | after(function (done) { | 314 | after(function (done) { |
235 | process.kill(-server.app.pid) | 315 | process.kill(-server.app.pid) |
236 | process.kill(-webtorrent.app.pid) | 316 | process.kill(-webtorrent.app.pid) |
diff --git a/server/tests/api/utils.js b/server/tests/api/utils.js index 9c5e4ee61..f0b1c3653 100644 --- a/server/tests/api/utils.js +++ b/server/tests/api/utils.js | |||
@@ -12,6 +12,7 @@ const testUtils = { | |||
12 | getFriendsList: getFriendsList, | 12 | getFriendsList: getFriendsList, |
13 | getVideo: getVideo, | 13 | getVideo: getVideo, |
14 | getVideosList: getVideosList, | 14 | getVideosList: getVideosList, |
15 | getVideosListPagination: getVideosListPagination, | ||
15 | login: login, | 16 | login: login, |
16 | loginAndGetAccessToken: loginAndGetAccessToken, | 17 | loginAndGetAccessToken: loginAndGetAccessToken, |
17 | makeFriends: makeFriends, | 18 | makeFriends: makeFriends, |
@@ -20,6 +21,7 @@ const testUtils = { | |||
20 | flushAndRunMultipleServers: flushAndRunMultipleServers, | 21 | flushAndRunMultipleServers: flushAndRunMultipleServers, |
21 | runServer: runServer, | 22 | runServer: runServer, |
22 | searchVideo: searchVideo, | 23 | searchVideo: searchVideo, |
24 | searchVideoWithPagination: searchVideoWithPagination, | ||
23 | testImage: testImage, | 25 | testImage: testImage, |
24 | uploadVideo: uploadVideo | 26 | uploadVideo: uploadVideo |
25 | } | 27 | } |
@@ -63,6 +65,19 @@ function getVideosList (url, end) { | |||
63 | .end(end) | 65 | .end(end) |
64 | } | 66 | } |
65 | 67 | ||
68 | function getVideosListPagination (url, start, count, end) { | ||
69 | const path = '/api/v1/videos' | ||
70 | |||
71 | request(url) | ||
72 | .get(path) | ||
73 | .query({ start: start }) | ||
74 | .query({ count: count }) | ||
75 | .set('Accept', 'application/json') | ||
76 | .expect(200) | ||
77 | .expect('Content-Type', /json/) | ||
78 | .end(end) | ||
79 | } | ||
80 | |||
66 | function login (url, client, user, expectedStatus, end) { | 81 | function login (url, client, user, expectedStatus, end) { |
67 | if (!end) { | 82 | if (!end) { |
68 | end = expectedStatus | 83 | end = expectedStatus |
@@ -261,6 +276,19 @@ function searchVideo (url, search, end) { | |||
261 | .end(end) | 276 | .end(end) |
262 | } | 277 | } |
263 | 278 | ||
279 | function searchVideoWithPagination (url, search, start, count, end) { | ||
280 | const path = '/api/v1/videos' | ||
281 | |||
282 | request(url) | ||
283 | .get(path + '/search/' + search) | ||
284 | .query({ start: start }) | ||
285 | .query({ count: count }) | ||
286 | .set('Accept', 'application/json') | ||
287 | .expect(200) | ||
288 | .expect('Content-Type', /json/) | ||
289 | .end(end) | ||
290 | } | ||
291 | |||
264 | function testImage (url, videoName, imagePath, callback) { | 292 | function testImage (url, videoName, imagePath, callback) { |
265 | request(url) | 293 | request(url) |
266 | .get(imagePath) | 294 | .get(imagePath) |