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