Refractor single server test
[oweals/peertube.git] / server / tests / api / videos / single-server.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import { keyBy } from 'lodash'
5 import 'mocha'
6 import { join } from 'path'
7 import { VideoPrivacy } from '../../../../shared/models/videos'
8 import {
9   dateIsValid,
10   flushTests,
11   getVideo,
12   getVideoCategories,
13   getVideoLanguages,
14   getVideoLicences,
15   getVideoPrivacies,
16   getVideosList,
17   getVideosListPagination,
18   getVideosListSort,
19   killallServers,
20   rateVideo,
21   readdirPromise,
22   removeVideo,
23   runServer,
24   searchVideo,
25   searchVideoWithPagination,
26   searchVideoWithSort,
27   ServerInfo,
28   setAccessTokensToServers,
29   testVideoImage,
30   updateVideo,
31   uploadVideo,
32   wait,
33   webtorrentAdd,
34   viewVideo, completeVideoCheck, immutableAssign
35 } from '../../utils'
36
37 const expect = chai.expect
38
39 describe('Test a single server', function () {
40   let server: ServerInfo = null
41   let videoId = -1
42   let videoUUID = ''
43   let videosListBase: any[] = null
44
45   const getCheckAttributes = {
46     name: 'my super name',
47     category: 2,
48     licence: 6,
49     language: 3,
50     nsfw: true,
51     description: 'my super description',
52     host: 'localhost:9001',
53     account: 'root',
54     isLocal: true,
55     tags: [ 'tag1', 'tag2', 'tag3' ],
56     privacy: VideoPrivacy.PUBLIC,
57     channel: {
58       name: 'Default root channel',
59       isLocal: true
60     },
61     fixture: 'video_short.webm',
62     files: [
63       {
64         resolution: 720,
65         size: 218910
66       }
67     ]
68   }
69
70   const updateCheckAttributes = {
71     name: 'my super video updated',
72     category: 4,
73     licence: 2,
74     language: 5,
75     nsfw: true,
76     description: 'my super description updated',
77     host: 'localhost:9001',
78     account: 'root',
79     isLocal: true,
80     tags: [ 'tagup1', 'tagup2' ],
81     privacy: VideoPrivacy.PUBLIC,
82     channel: {
83       name: 'Default root channel',
84       isLocal: true
85     },
86     fixture: 'video_short3.webm',
87     files: [
88       {
89         resolution: 720,
90         size: 292677
91       }
92     ]
93   }
94
95   before(async function () {
96     this.timeout(10000)
97
98     await flushTests()
99
100     server = await runServer(1)
101
102     await setAccessTokensToServers([ server ])
103   })
104
105   it('Should list video categories', async function () {
106     const res = await getVideoCategories(server.url)
107
108     const categories = res.body
109     expect(Object.keys(categories)).to.have.length.above(10)
110
111     expect(categories[11]).to.equal('News')
112   })
113
114   it('Should list video licences', async function () {
115     const res = await getVideoLicences(server.url)
116
117     const licences = res.body
118     expect(Object.keys(licences)).to.have.length.above(5)
119
120     expect(licences[3]).to.equal('Attribution - No Derivatives')
121   })
122
123   it('Should list video languages', async function () {
124     const res = await getVideoLanguages(server.url)
125
126     const languages = res.body
127     expect(Object.keys(languages)).to.have.length.above(5)
128
129     expect(languages[3]).to.equal('Mandarin')
130   })
131
132   it('Should list video privacies', async function () {
133     const res = await getVideoPrivacies(server.url)
134
135     const privacies = res.body
136     expect(Object.keys(privacies)).to.have.length.at.least(3)
137
138     expect(privacies[3]).to.equal('Private')
139   })
140
141   it('Should not have videos', async function () {
142     const res = await getVideosList(server.url)
143
144     expect(res.body.total).to.equal(0)
145     expect(res.body.data).to.be.an('array')
146     expect(res.body.data.length).to.equal(0)
147   })
148
149   it('Should upload the video', async function () {
150     const videoAttributes = {
151       name: 'my super name',
152       category: 2,
153       nsfw: true,
154       licence: 6,
155       tags: [ 'tag1', 'tag2', 'tag3' ]
156     }
157     const res = await uploadVideo(server.url, server.accessToken, videoAttributes)
158     expect(res.body.video).to.not.be.undefined
159     expect(res.body.video.id).to.equal(1)
160     expect(res.body.video.uuid).to.have.length.above(5)
161
162     videoId = res.body.video.id
163     videoUUID = res.body.video.uuid
164   })
165
166   it('Should get and seed the uploaded video', async function () {
167     // Yes, this could be long
168     this.timeout(60000)
169
170     const res = await getVideosList(server.url)
171
172     expect(res.body.total).to.equal(1)
173     expect(res.body.data).to.be.an('array')
174     expect(res.body.data.length).to.equal(1)
175
176     const video = res.body.data[0]
177     await completeVideoCheck(server.url, video, getCheckAttributes)
178   })
179
180   it('Should get the video by UUID', async function () {
181     // Yes, this could be long
182     this.timeout(60000)
183
184     const res = await getVideo(server.url, videoUUID)
185
186     const video = res.body
187     await completeVideoCheck(server.url, video, getCheckAttributes)
188   })
189
190   it('Should have the views updated', async function () {
191     await viewVideo(server.url, videoId)
192     await viewVideo(server.url, videoId)
193     await viewVideo(server.url, videoId)
194
195     const res = await getVideo(server.url, videoId)
196
197     const video = res.body
198     expect(video.views).to.equal(3)
199   })
200
201   it('Should search the video by name', async function () {
202     const res = await searchVideo(server.url, 'my')
203
204     expect(res.body.total).to.equal(1)
205     expect(res.body.data).to.be.an('array')
206     expect(res.body.data.length).to.equal(1)
207
208     const video = res.body.data[0]
209     await completeVideoCheck(server.url, video, getCheckAttributes)
210   })
211
212   // Not implemented yet
213   // it('Should search the video by serverHost', async function () {
214   //     const res = await   videosUtils.searchVideo(server.url, '9001', 'host')
215
216   //     expect(res.body.total).to.equal(1)
217   //     expect(res.body.data).to.be.an('array')
218   //     expect(res.body.data.length).to.equal(1)
219
220   //     const video = res.body.data[0]
221   //     expect(video.name).to.equal('my super name')
222   //     expect(video.description).to.equal('my super description')
223   //     expect(video.serverHost).to.equal('localhost:9001')
224   //     expect(video.author).to.equal('root')
225   //     expect(video.isLocal).to.be.true
226   //     expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
227   //     expect(dateIsValid(video.createdAt)).to.be.true
228   //     expect(dateIsValid(video.updatedAt)).to.be.true
229
230   //     const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
231   //       expect(test).to.equal(true)
232
233   //       done()
234   //     })
235   //   })
236   // })
237
238   // Not implemented yet
239   // it('Should search the video by tag', async function () {
240   //   const res = await searchVideo(server.url, 'tag1')
241   //
242   //   expect(res.body.total).to.equal(1)
243   //   expect(res.body.data).to.be.an('array')
244   //   expect(res.body.data.length).to.equal(1)
245   //
246   //   const video = res.body.data[0]
247   //   expect(video.name).to.equal('my super name')
248   //   expect(video.category).to.equal(2)
249   //   expect(video.categoryLabel).to.equal('Films')
250   //   expect(video.licence).to.equal(6)
251   //   expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
252   //   expect(video.language).to.equal(3)
253   //   expect(video.languageLabel).to.equal('Mandarin')
254   //   expect(video.nsfw).to.be.ok
255   //   expect(video.description).to.equal('my super description')
256   //   expect(video.serverHost).to.equal('localhost:9001')
257   //   expect(video.accountName).to.equal('root')
258   //   expect(video.isLocal).to.be.true
259   //   expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ])
260   //   expect(dateIsValid(video.createdAt)).to.be.true
261   //   expect(dateIsValid(video.updatedAt)).to.be.true
262   //
263   //   const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
264   //   expect(test).to.equal(true)
265   // })
266
267   it('Should not find a search by name', async function () {
268     const res = await searchVideo(server.url, 'hello')
269
270     expect(res.body.total).to.equal(0)
271     expect(res.body.data).to.be.an('array')
272     expect(res.body.data.length).to.equal(0)
273   })
274
275   // Not implemented yet
276   // it('Should not find a search by author', async function () {
277   //   const res = await searchVideo(server.url, 'hello')
278   //
279   //   expect(res.body.total).to.equal(0)
280   //   expect(res.body.data).to.be.an('array')
281   //   expect(res.body.data.length).to.equal(0)
282   // })
283   //
284   // Not implemented yet
285   // it('Should not find a search by tag', async function () {
286   //   const res = await searchVideo(server.url, 'hello')
287   //
288   //   expect(res.body.total).to.equal(0)
289   //   expect(res.body.data).to.be.an('array')
290   //   expect(res.body.data.length).to.equal(0)
291   // })
292
293   it('Should remove the video', async function () {
294     await removeVideo(server.url, server.accessToken, videoId)
295
296     const files1 = await readdirPromise(join(__dirname, '..', '..', '..', '..', 'test1', 'videos'))
297     expect(files1).to.have.lengthOf(0)
298
299     const files2 = await readdirPromise(join(__dirname, '..', '..', '..', '..', 'test1', 'thumbnails'))
300     expect(files2).to.have.lengthOf(0)
301   })
302
303   it('Should not have videos', async function () {
304     const res = await getVideosList(server.url)
305
306     expect(res.body.total).to.equal(0)
307     expect(res.body.data).to.be.an('array')
308     expect(res.body.data).to.have.lengthOf(0)
309   })
310
311   it('Should upload 6 videos', async function () {
312     this.timeout(25000)
313
314     const videos = [
315       'video_short.mp4', 'video_short.ogv', 'video_short.webm',
316       'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
317     ]
318
319     const tasks: Promise<any>[] = []
320     for (const video of videos) {
321       const videoAttributes = {
322         name: video + ' name',
323         description: video + ' description',
324         category: 2,
325         licence: 1,
326         language: 1,
327         nsfw: true,
328         tags: [ 'tag1', 'tag2', 'tag3' ],
329         fixture: video
330       }
331
332       const p = uploadVideo(server.url, server.accessToken, videoAttributes)
333       tasks.push(p)
334     }
335
336     await Promise.all(tasks)
337   })
338
339   it('Should have the correct durations', async function () {
340     const res = await getVideosList(server.url)
341
342     expect(res.body.total).to.equal(6)
343     const videos = res.body.data
344     expect(videos).to.be.an('array')
345     expect(videos).to.have.lengthOf(6)
346
347     const videosByName = keyBy<{ duration: number }>(videos, 'name')
348     expect(videosByName['video_short.mp4 name'].duration).to.equal(5)
349     expect(videosByName['video_short.ogv name'].duration).to.equal(5)
350     expect(videosByName['video_short.webm name'].duration).to.equal(5)
351     expect(videosByName['video_short1.webm name'].duration).to.equal(10)
352     expect(videosByName['video_short2.webm name'].duration).to.equal(5)
353     expect(videosByName['video_short3.webm name'].duration).to.equal(5)
354   })
355
356   it('Should have the correct thumbnails', async function () {
357     const res = await getVideosList(server.url)
358
359     const videos = res.body.data
360     // For the next test
361     videosListBase = videos
362
363     for (const video of videos) {
364       const videoName = video.name.replace(' name', '')
365       const test = await testVideoImage(server.url, videoName, video.thumbnailPath)
366
367       expect(test).to.equal(true)
368     }
369   })
370
371   it('Should list only the two first videos', async function () {
372     const res = await getVideosListPagination(server.url, 0, 2, 'name')
373
374     const videos = res.body.data
375     expect(res.body.total).to.equal(6)
376     expect(videos.length).to.equal(2)
377     expect(videos[0].name).to.equal(videosListBase[0].name)
378     expect(videos[1].name).to.equal(videosListBase[1].name)
379   })
380
381   it('Should list only the next three videos', async function () {
382     const res = await getVideosListPagination(server.url, 2, 3, 'name')
383
384     const videos = res.body.data
385     expect(res.body.total).to.equal(6)
386     expect(videos.length).to.equal(3)
387     expect(videos[0].name).to.equal(videosListBase[2].name)
388     expect(videos[1].name).to.equal(videosListBase[3].name)
389     expect(videos[2].name).to.equal(videosListBase[4].name)
390   })
391
392   it('Should list the last video', async function () {
393     const res = await getVideosListPagination(server.url, 5, 6, 'name')
394
395     const videos = res.body.data
396     expect(res.body.total).to.equal(6)
397     expect(videos.length).to.equal(1)
398     expect(videos[0].name).to.equal(videosListBase[5].name)
399   })
400
401   it('Should search the first video', async function () {
402     const res = await searchVideoWithPagination(server.url, 'webm', 0, 1, 'name')
403
404     const videos = res.body.data
405     expect(res.body.total).to.equal(4)
406     expect(videos.length).to.equal(1)
407     expect(videos[0].name).to.equal('video_short1.webm name')
408   })
409
410   it('Should search the last two videos', async function () {
411     const res = await searchVideoWithPagination(server.url, 'webm', 2, 2, 'name')
412
413     const videos = res.body.data
414     expect(res.body.total).to.equal(4)
415     expect(videos.length).to.equal(2)
416     expect(videos[0].name).to.equal('video_short3.webm name')
417     expect(videos[1].name).to.equal('video_short.webm name')
418   })
419
420   it('Should search all the webm videos', async function () {
421     const res = await searchVideoWithPagination(server.url, 'webm', 0, 15)
422
423     const videos = res.body.data
424     expect(res.body.total).to.equal(4)
425     expect(videos.length).to.equal(4)
426   })
427
428   // Not implemented yet
429   // it('Should search all the root author videos', async function () {
430   //   const res = await searchVideoWithPagination(server.url, 'root', 0, 15)
431   //
432   //   const videos = res.body.data
433   //   expect(res.body.total).to.equal(6)
434   //   expect(videos.length).to.equal(6)
435   // })
436
437   // Not implemented yet
438   // it('Should search all the 9001 port videos', async function () {
439   // const res = await   videosUtils.searchVideoWithPagination(server.url, '9001', 'host', 0, 15)
440
441   //     const videos = res.body.data
442   //     expect(res.body.total).to.equal(6)
443   //     expect(videos.length).to.equal(6)
444
445   //     done()
446   //   })
447   // })
448
449   // it('Should search all the localhost videos', async function () {
450   // const res = await   videosUtils.searchVideoWithPagination(server.url, 'localhost', 'host', 0, 15)
451
452   //     const videos = res.body.data
453   //     expect(res.body.total).to.equal(6)
454   //     expect(videos.length).to.equal(6)
455
456   //     done()
457   //   })
458   // })
459
460   it('Should list and sort by name in descending order', async function () {
461     const res = await getVideosListSort(server.url, '-name')
462
463     const videos = res.body.data
464     expect(res.body.total).to.equal(6)
465     expect(videos.length).to.equal(6)
466     expect(videos[0].name).to.equal('video_short.webm name')
467     expect(videos[1].name).to.equal('video_short.ogv name')
468     expect(videos[2].name).to.equal('video_short.mp4 name')
469     expect(videos[3].name).to.equal('video_short3.webm name')
470     expect(videos[4].name).to.equal('video_short2.webm name')
471     expect(videos[5].name).to.equal('video_short1.webm name')
472   })
473
474   it('Should search and sort by name in ascending order', async function () {
475     const res = await searchVideoWithSort(server.url, 'webm', 'name')
476
477     const videos = res.body.data
478     expect(res.body.total).to.equal(4)
479     expect(videos.length).to.equal(4)
480
481     expect(videos[0].name).to.equal('video_short1.webm name')
482     expect(videos[1].name).to.equal('video_short2.webm name')
483     expect(videos[2].name).to.equal('video_short3.webm name')
484     expect(videos[3].name).to.equal('video_short.webm name')
485
486     videoId = videos[2].id
487   })
488
489   it('Should update a video', async function () {
490     const attributes = {
491       name: 'my super video updated',
492       category: 4,
493       licence: 2,
494       language: 5,
495       nsfw: false,
496       description: 'my super description updated',
497       tags: [ 'tagup1', 'tagup2' ]
498     }
499     await updateVideo(server.url, server.accessToken, videoId, attributes)
500   })
501
502   it('Should have the video updated', async function () {
503     this.timeout(60000)
504
505     const res = await getVideo(server.url, videoId)
506     const video = res.body
507
508     await completeVideoCheck(server.url, video, updateCheckAttributes)
509   })
510
511   it('Should update only the tags of a video', async function () {
512     const attributes = {
513       tags: [ 'supertag', 'tag1', 'tag2' ]
514     }
515     await updateVideo(server.url, server.accessToken, videoId, attributes)
516
517     const res = await getVideo(server.url, videoId)
518     const video = res.body
519
520     await completeVideoCheck(server.url, video, Object.assign(updateCheckAttributes, attributes))
521   })
522
523   it('Should update only the description of a video', async function () {
524     const attributes = {
525       description: 'hello everybody'
526     }
527     await updateVideo(server.url, server.accessToken, videoId, attributes)
528
529     const res = await getVideo(server.url, videoId)
530     const video = res.body
531
532     await completeVideoCheck(server.url, video, Object.assign(updateCheckAttributes, attributes))
533   })
534
535   it('Should like a video', async function () {
536     await rateVideo(server.url, server.accessToken, videoId, 'like')
537
538     const res = await getVideo(server.url, videoId)
539     const video = res.body
540
541     expect(video.likes).to.equal(1)
542     expect(video.dislikes).to.equal(0)
543   })
544
545   it('Should dislike the same video', async function () {
546     await rateVideo(server.url, server.accessToken, videoId, 'dislike')
547
548     const res = await getVideo(server.url, videoId)
549     const video = res.body
550
551     expect(video.likes).to.equal(0)
552     expect(video.dislikes).to.equal(1)
553   })
554
555   after(async function () {
556     killallServers([ server ])
557
558     // Keep the logs if the test failed
559     if (this['ok']) {
560       await flushTests()
561     }
562   })
563 })