444c2fc558c80ff0b2dec7f2a3496ed943c4bc4a
[oweals/peertube.git] / server / tests / api / check-params.js
1 'use strict'
2
3 const chai = require('chai')
4 const expect = chai.expect
5 const pathUtils = require('path')
6 const request = require('supertest')
7 const series = require('async/series')
8
9 const loginUtils = require('../utils/login')
10 const requestsUtils = require('../utils/requests')
11 const serversUtils = require('../utils/servers')
12 const usersUtils = require('../utils/users')
13
14 describe('Test parameters validator', function () {
15   let server = null
16   let userAccessToken = null
17
18   // ---------------------------------------------------------------
19
20   before(function (done) {
21     this.timeout(20000)
22
23     series([
24       function (next) {
25         serversUtils.flushTests(next)
26       },
27       function (next) {
28         serversUtils.runServer(1, function (server1) {
29           server = server1
30
31           next()
32         })
33       },
34       function (next) {
35         loginUtils.loginAndGetAccessToken(server, function (err, token) {
36           if (err) throw err
37           server.accessToken = token
38
39           next()
40         })
41       }
42     ], done)
43   })
44
45   describe('Of the pods API', function () {
46     const path = '/api/v1/pods/'
47
48     describe('When making friends', function () {
49       let userAccessToken = null
50
51       before(function (done) {
52         usersUtils.createUser(server.url, server.accessToken, 'user1', 'password', function () {
53           server.user = {
54             username: 'user1',
55             password: 'password'
56           }
57
58           loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
59             if (err) throw err
60
61             userAccessToken = accessToken
62
63             done()
64           })
65         })
66       })
67
68       describe('When making friends', function () {
69         const body = {
70           hosts: [ 'localhost:9002' ]
71         }
72
73         it('Should fail without hosts', function (done) {
74           request(server.url)
75             .post(path + '/makefriends')
76             .set('Authorization', 'Bearer ' + server.accessToken)
77             .set('Accept', 'application/json')
78             .expect(400, done)
79         })
80
81         it('Should fail if hosts is not an array', function (done) {
82           request(server.url)
83             .post(path + '/makefriends')
84             .send({ hosts: 'localhost:9002' })
85             .set('Authorization', 'Bearer ' + server.accessToken)
86             .set('Accept', 'application/json')
87             .expect(400, done)
88         })
89
90         it('Should fail if the array is not composed by hosts', function (done) {
91           request(server.url)
92             .post(path + '/makefriends')
93             .send({ hosts: [ 'localhost:9002', 'localhost:coucou' ] })
94             .set('Authorization', 'Bearer ' + server.accessToken)
95             .set('Accept', 'application/json')
96             .expect(400, done)
97         })
98
99         it('Should fail if the array is composed with http schemes', function (done) {
100           request(server.url)
101             .post(path + '/makefriends')
102             .send({ hosts: [ 'localhost:9002', 'http://localhost:9003' ] })
103             .set('Authorization', 'Bearer ' + server.accessToken)
104             .set('Accept', 'application/json')
105             .expect(400, done)
106         })
107
108         it('Should fail if hosts are not unique', function (done) {
109           request(server.url)
110             .post(path + '/makefriends')
111             .send({ urls: [ 'localhost:9002', 'localhost:9002' ] })
112             .set('Authorization', 'Bearer ' + server.accessToken)
113             .set('Accept', 'application/json')
114             .expect(400, done)
115         })
116
117         it('Should fail with a invalid token', function (done) {
118           request(server.url)
119             .post(path + '/makefriends')
120             .send(body)
121             .set('Authorization', 'Bearer faketoken')
122             .set('Accept', 'application/json')
123             .expect(401, done)
124         })
125
126         it('Should fail if the user is not an administrator', function (done) {
127           request(server.url)
128             .post(path + '/makefriends')
129             .send(body)
130             .set('Authorization', 'Bearer ' + userAccessToken)
131             .set('Accept', 'application/json')
132             .expect(403, done)
133         })
134       })
135
136       describe('When quitting friends', function () {
137         it('Should fail with a invalid token', function (done) {
138           request(server.url)
139             .get(path + '/quitfriends')
140             .query({ start: 'hello' })
141             .set('Authorization', 'Bearer faketoken')
142             .set('Accept', 'application/json')
143             .expect(401, done)
144         })
145
146         it('Should fail if the user is not an administrator', function (done) {
147           request(server.url)
148             .get(path + '/quitfriends')
149             .query({ start: 'hello' })
150             .set('Authorization', 'Bearer ' + userAccessToken)
151             .set('Accept', 'application/json')
152             .expect(403, done)
153         })
154       })
155     })
156
157     describe('When adding a pod', function () {
158       it('Should fail with nothing', function (done) {
159         const data = {}
160         requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
161       })
162
163       it('Should fail without public key', function (done) {
164         const data = {
165           host: 'coucou.com'
166         }
167         requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
168       })
169
170       it('Should fail without an host', function (done) {
171         const data = {
172           publicKey: 'mysuperpublickey'
173         }
174         requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
175       })
176
177       it('Should fail with an incorrect host', function (done) {
178         const data = {
179           host: 'http://coucou.com',
180           publicKey: 'mysuperpublickey'
181         }
182         requestsUtils.makePostBodyRequest(server.url, path, null, data, function () {
183           data.host = 'http://coucou'
184           requestsUtils.makePostBodyRequest(server.url, path, null, data, function () {
185             data.host = 'coucou'
186             requestsUtils.makePostBodyRequest(server.url, path, null, data, done)
187           })
188         })
189       })
190
191       it('Should succeed with the correct parameters', function (done) {
192         const data = {
193           host: 'coucou.com',
194           publicKey: 'mysuperpublickey'
195         }
196         requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 200)
197       })
198     })
199   })
200
201   describe('Of the videos API', function () {
202     const path = '/api/v1/videos/'
203
204     describe('When listing a video', function () {
205       it('Should fail with a bad start pagination', function (done) {
206         request(server.url)
207           .get(path)
208           .query({ start: 'hello' })
209           .set('Accept', 'application/json')
210           .expect(400, done)
211       })
212
213       it('Should fail with a bad count pagination', function (done) {
214         request(server.url)
215           .get(path)
216           .query({ count: 'hello' })
217           .set('Accept', 'application/json')
218           .expect(400, done)
219       })
220
221       it('Should fail with an incorrect sort', function (done) {
222         request(server.url)
223           .get(path)
224           .query({ sort: 'hello' })
225           .set('Accept', 'application/json')
226           .expect(400, done)
227       })
228     })
229
230     describe('When searching a video', function () {
231       it('Should fail with nothing', function (done) {
232         request(server.url)
233           .get(pathUtils.join(path, 'search'))
234           .set('Accept', 'application/json')
235           .expect(400, done)
236       })
237
238       it('Should fail with a bad start pagination', function (done) {
239         request(server.url)
240           .get(pathUtils.join(path, 'search', 'test'))
241           .query({ start: 'hello' })
242           .set('Accept', 'application/json')
243           .expect(400, done)
244       })
245
246       it('Should fail with a bad count pagination', function (done) {
247         request(server.url)
248           .get(pathUtils.join(path, 'search', 'test'))
249           .query({ count: 'hello' })
250           .set('Accept', 'application/json')
251           .expect(400, done)
252       })
253
254       it('Should fail with an incorrect sort', function (done) {
255         request(server.url)
256           .get(pathUtils.join(path, 'search', 'test'))
257           .query({ sort: 'hello' })
258           .set('Accept', 'application/json')
259           .expect(400, done)
260       })
261     })
262
263     describe('When adding a video', function () {
264       it('Should fail with nothing', function (done) {
265         const data = {}
266         const attach = {}
267         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
268       })
269
270       it('Should fail without name', function (done) {
271         const data = {
272           description: 'my super description',
273           tags: [ 'tag1', 'tag2' ]
274         }
275         const attach = {
276           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
277         }
278         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
279       })
280
281       it('Should fail with a long name', function (done) {
282         const data = {
283           name: 'My very very very very very very very very very very very very very very very very long name',
284           description: 'my super description',
285           tags: [ 'tag1', 'tag2' ]
286         }
287         const attach = {
288           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
289         }
290         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
291       })
292
293       it('Should fail without description', function (done) {
294         const data = {
295           name: 'my super name',
296           tags: [ 'tag1', 'tag2' ]
297         }
298         const attach = {
299           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
300         }
301         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
302       })
303
304       it('Should fail with a long description', function (done) {
305         const data = {
306           name: 'my super name',
307           description: 'my super description which is very very very very very very very very very very very very very very' +
308                        'very very very very very very very very very very very very very very very very very very very very very' +
309                        'very very very very very very very very very very very very very very very long',
310           tags: [ 'tag1', 'tag2' ]
311         }
312         const attach = {
313           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
314         }
315         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
316       })
317
318       it('Should fail without tags', function (done) {
319         const data = {
320           name: 'my super name',
321           description: 'my super description'
322         }
323         const attach = {
324           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
325         }
326         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
327       })
328
329       it('Should fail with too many tags', function (done) {
330         const data = {
331           name: 'my super name',
332           description: 'my super description',
333           tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ]
334         }
335         const attach = {
336           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
337         }
338         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
339       })
340
341       it('Should fail with not enough tags', function (done) {
342         const data = {
343           name: 'my super name',
344           description: 'my super description',
345           tags: [ ]
346         }
347         const attach = {
348           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
349         }
350         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
351       })
352
353       it('Should fail with a tag length too low', function (done) {
354         const data = {
355           name: 'my super name',
356           description: 'my super description',
357           tags: [ 'tag1', 't' ]
358         }
359         const attach = {
360           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
361         }
362         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
363       })
364
365       it('Should fail with a tag length too big', function (done) {
366         const data = {
367           name: 'my super name',
368           description: 'my super description',
369           tags: [ 'mysupertagtoolong', 'tag1' ]
370         }
371         const attach = {
372           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
373         }
374         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
375       })
376
377       it('Should fail with malformed tags', function (done) {
378         const data = {
379           name: 'my super name',
380           description: 'my super description',
381           tags: [ 'my tag' ]
382         }
383         const attach = {
384           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
385         }
386         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
387       })
388
389       it('Should fail without an input file', function (done) {
390         const data = {
391           name: 'my super name',
392           description: 'my super description',
393           tags: [ 'tag1', 'tag2' ]
394         }
395         const attach = {}
396         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
397       })
398
399       it('Should fail without an incorrect input file', function (done) {
400         const data = {
401           name: 'my super name',
402           description: 'my super description',
403           tags: [ 'tag1', 'tag2' ]
404         }
405         const attach = {
406           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short_fake.webm')
407         }
408         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
409       })
410
411       it('Should fail with a too big duration', function (done) {
412         const data = {
413           name: 'my super name',
414           description: 'my super description',
415           tags: [ 'tag1', 'tag2' ]
416         }
417         const attach = {
418           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_too_long.webm')
419         }
420         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done)
421       })
422
423       it('Should succeed with the correct parameters', function (done) {
424         const data = {
425           name: 'my super name',
426           description: 'my super description',
427           tags: [ 'tag1', 'tag2' ]
428         }
429         const attach = {
430           'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm')
431         }
432         requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () {
433           attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.mp4')
434           requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () {
435             attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.ogv')
436             requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done, 204)
437           }, false)
438         }, false)
439       })
440     })
441
442     describe('When getting a video', function () {
443       it('Should return the list of the videos with nothing', function (done) {
444         request(server.url)
445           .get(path)
446           .set('Accept', 'application/json')
447           .expect(200)
448           .expect('Content-Type', /json/)
449           .end(function (err, res) {
450             if (err) throw err
451
452             expect(res.body.data).to.be.an('array')
453             expect(res.body.data.length).to.equal(3)
454
455             done()
456           })
457       })
458
459       it('Should fail without a mongodb id', function (done) {
460         request(server.url)
461           .get(path + 'coucou')
462           .set('Accept', 'application/json')
463           .expect(400, done)
464       })
465
466       it('Should return 404 with an incorrect video', function (done) {
467         request(server.url)
468           .get(path + '123456789012345678901234')
469           .set('Accept', 'application/json')
470           .expect(404, done)
471       })
472
473       it('Should succeed with the correct parameters')
474     })
475
476     describe('When removing a video', function () {
477       it('Should have 404 with nothing', function (done) {
478         request(server.url)
479           .delete(path)
480           .set('Authorization', 'Bearer ' + server.accessToken)
481           .expect(400, done)
482       })
483
484       it('Should fail without a mongodb id', function (done) {
485         request(server.url)
486           .delete(path + 'hello')
487           .set('Authorization', 'Bearer ' + server.accessToken)
488           .expect(400, done)
489       })
490
491       it('Should fail with a video which does not exist', function (done) {
492         request(server.url)
493           .delete(path + '123456789012345678901234')
494           .set('Authorization', 'Bearer ' + server.accessToken)
495           .expect(404, done)
496       })
497
498       it('Should fail with a video of another user')
499
500       it('Should fail with a video of another pod')
501
502       it('Should succeed with the correct parameters')
503     })
504   })
505
506   describe('Of the users API', function () {
507     const path = '/api/v1/users/'
508     let userId = null
509     let rootId = null
510
511     describe('When listing users', function () {
512       it('Should fail with a bad start pagination', function (done) {
513         request(server.url)
514           .get(path)
515           .query({ start: 'hello' })
516           .set('Accept', 'application/json')
517           .expect(400, done)
518       })
519
520       it('Should fail with a bad count pagination', function (done) {
521         request(server.url)
522           .get(path)
523           .query({ count: 'hello' })
524           .set('Accept', 'application/json')
525           .expect(400, done)
526       })
527
528       it('Should fail with an incorrect sort', function (done) {
529         request(server.url)
530           .get(path)
531           .query({ sort: 'hello' })
532           .set('Accept', 'application/json')
533           .expect(400, done)
534       })
535     })
536
537     describe('When adding a new user', function () {
538       it('Should fail with a too small username', function (done) {
539         const data = {
540           username: 'ji',
541           password: 'mysuperpassword'
542         }
543
544         requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
545       })
546
547       it('Should fail with a too long username', function (done) {
548         const data = {
549           username: 'mysuperusernamewhichisverylong',
550           password: 'mysuperpassword'
551         }
552
553         requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
554       })
555
556       it('Should fail with an incorrect username', function (done) {
557         const data = {
558           username: 'my username',
559           password: 'mysuperpassword'
560         }
561
562         requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
563       })
564
565       it('Should fail with a too small password', function (done) {
566         const data = {
567           username: 'myusername',
568           password: 'bla'
569         }
570
571         requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
572       })
573
574       it('Should fail with a too long password', function (done) {
575         const data = {
576           username: 'myusername',
577           password: 'my super long password which is very very very very very very very very very very very very very very' +
578                     'very very very very very very very very very very very very very very very veryv very very very very' +
579                     'very very very very very very very very very very very very very very very very very very very very long'
580         }
581
582         requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done)
583       })
584
585       it('Should fail with an non authenticated user', function (done) {
586         const data = {
587           username: 'myusername',
588           password: 'my super password'
589         }
590
591         requestsUtils.makePostBodyRequest(server.url, path, 'super token', data, done, 401)
592       })
593
594       it('Should fail if we add a user with the same username', function (done) {
595         const data = {
596           username: 'user1',
597           password: 'my super password'
598         }
599
600         requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 409)
601       })
602
603       it('Should succeed with the correct params', function (done) {
604         const data = {
605           username: 'user2',
606           password: 'my super password'
607         }
608
609         requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204)
610       })
611
612       it('Should fail with a non admin user', function (done) {
613         server.user = {
614           username: 'user1',
615           password: 'password'
616         }
617
618         loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
619           if (err) throw err
620
621           userAccessToken = accessToken
622
623           const data = {
624             username: 'user3',
625             password: 'my super password'
626           }
627
628           requestsUtils.makePostBodyRequest(server.url, path, userAccessToken, data, done, 403)
629         })
630       })
631     })
632
633     describe('When updating a user', function () {
634       before(function (done) {
635         usersUtils.getUsersList(server.url, function (err, res) {
636           if (err) throw err
637
638           userId = res.body.data[1].id
639           rootId = res.body.data[2].id
640           done()
641         })
642       })
643
644       it('Should fail with a too small password', function (done) {
645         const data = {
646           password: 'bla'
647         }
648
649         requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done)
650       })
651
652       it('Should fail with a too long password', function (done) {
653         const data = {
654           password: 'my super long password which is very very very very very very very very very very very very very very' +
655                     'very very very very very very very very very very very very very very very veryv very very very very' +
656                     'very very very very very very very very very very very very very very very very very very very very long'
657         }
658
659         requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done)
660       })
661
662       it('Should fail with an non authenticated user', function (done) {
663         const data = {
664           password: 'my super password'
665         }
666
667         requestsUtils.makePutBodyRequest(server.url, path + userId, 'super token', data, done, 401)
668       })
669
670       it('Should succeed with the correct params', function (done) {
671         const data = {
672           password: 'my super password'
673         }
674
675         requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done, 204)
676       })
677     })
678
679     describe('When getting my information', function () {
680       it('Should fail with a non authenticated user', function (done) {
681         request(server.url)
682           .get(path + 'me')
683           .set('Authorization', 'Bearer faketoken')
684           .set('Accept', 'application/json')
685           .expect(401, done)
686       })
687
688       it('Should success with the correct parameters', function (done) {
689         request(server.url)
690           .get(path + 'me')
691           .set('Authorization', 'Bearer ' + userAccessToken)
692           .set('Accept', 'application/json')
693           .expect(200, done)
694       })
695     })
696
697     describe('When removing an user', function () {
698       it('Should fail with an incorrect id', function (done) {
699         request(server.url)
700           .delete(path + 'bla-bla')
701           .set('Authorization', 'Bearer ' + server.accessToken)
702           .expect(400, done)
703       })
704
705       it('Should fail with the root user', function (done) {
706         request(server.url)
707           .delete(path + rootId)
708           .set('Authorization', 'Bearer ' + server.accessToken)
709           .expect(400, done)
710       })
711
712       it('Should return 404 with a non existing id', function (done) {
713         request(server.url)
714           .delete(path + '579f982228c99c221d8092b8')
715           .set('Authorization', 'Bearer ' + server.accessToken)
716           .expect(404, done)
717       })
718     })
719   })
720
721   describe('Of the remote videos API', function () {
722     describe('When making a secure request', function () {
723       it('Should check a secure request')
724     })
725
726     describe('When adding a video', function () {
727       it('Should check when adding a video')
728     })
729
730     describe('When removing a video', function () {
731       it('Should check when removing a video')
732     })
733   })
734
735   describe('Of the requests API', function () {
736     const path = '/api/v1/requests/stats'
737
738     it('Should fail with an non authenticated user', function (done) {
739       request(server.url)
740         .get(path)
741         .set('Accept', 'application/json')
742         .expect(401, done)
743     })
744
745     it('Should fail with a non admin user', function (done) {
746       request(server.url)
747         .get(path)
748         .set('Authorization', 'Bearer ' + userAccessToken)
749         .set('Accept', 'application/json')
750         .expect(403, done)
751     })
752   })
753
754   after(function (done) {
755     process.kill(-server.app.pid)
756
757     // Keep the logs if the test failed
758     if (this.ok) {
759       serversUtils.flushTests(done)
760     } else {
761       done()
762     }
763   })
764 })