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