Improve check users parameters tests
[oweals/peertube.git] / server / tests / api / videos / multiple-servers.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import { join } from 'path'
6 import * as request from 'supertest'
7 import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
8
9 import {
10   addVideoChannel, dateIsValid, doubleFollow, flushAndRunMultipleServers, flushTests, userLogin, getVideo,
11   getVideoChannelsList, getVideosList, killallServers, rateVideo, removeVideo, ServerInfo, setAccessTokensToServers, testVideoImage,
12   updateVideo, uploadVideo, wait, webtorrentAdd
13 } from '../../utils/index'
14 import { createUser } from '../../utils/users/users'
15 import {
16   addVideoCommentReply, addVideoCommentThread, getVideoCommentThreads,
17   getVideoThreadComments
18 } from '../../utils/videos/video-comments'
19 import { viewVideo } from '../../utils/videos/videos'
20
21 const expect = chai.expect
22
23 describe('Test multiple servers', function () {
24   let servers: ServerInfo[] = []
25   const toRemove = []
26   let videoUUID = ''
27   let videoChannelId: number
28
29   before(async function () {
30     this.timeout(120000)
31
32     servers = await flushAndRunMultipleServers(3)
33
34     // Get the access tokens
35     await setAccessTokensToServers(servers)
36
37     const videoChannel = {
38       name: 'my channel',
39       description: 'super channel'
40     }
41     await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel)
42     const channelRes = await getVideoChannelsList(servers[0].url, 0, 1)
43     videoChannelId = channelRes.body.data[0].id
44
45     // Server 1 and server 2 follow each other
46     await doubleFollow(servers[0], servers[1])
47     // Server 1 and server 3 follow each other
48     await doubleFollow(servers[0], servers[2])
49     // Server 2 and server 3 follow each other
50     await doubleFollow(servers[1], servers[2])
51   })
52
53   it('Should not have videos for all servers', async function () {
54     for (const server of servers) {
55       const res = await getVideosList(server.url)
56       const videos = res.body.data
57       expect(videos).to.be.an('array')
58       expect(videos.length).to.equal(0)
59     }
60   })
61
62   describe('Should upload the video and propagate on each server', function () {
63     it('Should upload the video on server 1 and propagate on each server', async function () {
64       this.timeout(25000)
65
66       const videoAttributes = {
67         name: 'my super name for server 1',
68         category: 5,
69         licence: 4,
70         language: 9,
71         nsfw: true,
72         description: 'my super description for server 1',
73         tags: [ 'tag1p1', 'tag2p1' ],
74         channelId: videoChannelId,
75         fixture: 'video_short1.webm'
76       }
77       await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
78
79       await wait(10000)
80
81       // All servers should have this video
82       for (const server of servers) {
83         let baseMagnet = null
84
85         const res = await getVideosList(server.url)
86
87         const videos = res.body.data
88         expect(videos).to.be.an('array')
89         expect(videos.length).to.equal(1)
90         const video = videos[0]
91         expect(video.name).to.equal('my super name for server 1')
92         expect(video.category).to.equal(5)
93         expect(video.categoryLabel).to.equal('Sports')
94         expect(video.licence).to.equal(4)
95         expect(video.licenceLabel).to.equal('Attribution - Non Commercial')
96         expect(video.language).to.equal(9)
97         expect(video.languageLabel).to.equal('Japanese')
98         expect(video.nsfw).to.be.ok
99         expect(video.description).to.equal('my super description for server 1')
100         expect(video.serverHost).to.equal('localhost:9001')
101         expect(video.duration).to.equal(10)
102         expect(dateIsValid(video.createdAt)).to.be.true
103         expect(dateIsValid(video.updatedAt)).to.be.true
104         expect(video.accountName).to.equal('root')
105
106         const res2 = await getVideo(server.url, video.uuid)
107         const videoDetails = res2.body
108
109         expect(videoDetails.channel.name).to.equal('my channel')
110         expect(videoDetails.channel.description).to.equal('super channel')
111         expect(videoDetails.account.name).to.equal('root')
112         expect(dateIsValid(videoDetails.channel.createdAt)).to.be.true
113         expect(dateIsValid(videoDetails.channel.updatedAt)).to.be.true
114         expect(videoDetails.files).to.have.lengthOf(1)
115         expect(videoDetails.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ])
116
117         const file = videoDetails.files[0]
118         const magnetUri = file.magnetUri
119         expect(file.magnetUri).to.have.lengthOf.above(2)
120         expect(file.torrentUrl).to
121           .equal(`http://${videoDetails.serverHost}/static/torrents/${videoDetails.uuid}-${file.resolution}.torrent`)
122         expect(file.fileUrl).to.equal(`http://${videoDetails.serverHost}/static/webseed/${videoDetails.uuid}-${file.resolution}.webm`)
123         expect(file.resolution).to.equal(720)
124         expect(file.resolutionLabel).to.equal('720p')
125         expect(file.size).to.equal(572456)
126
127         if (server.url !== 'http://localhost:9001') {
128           expect(video.isLocal).to.be.false
129           expect(videoDetails.channel.isLocal).to.be.false
130         } else {
131           expect(video.isLocal).to.be.true
132           expect(videoDetails.channel.isLocal).to.be.true
133         }
134
135         // All servers should have the same magnet Uri
136         if (baseMagnet === null) {
137           baseMagnet = magnetUri
138         } else {
139           expect(baseMagnet).to.equal(magnetUri)
140         }
141
142         const test = await testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath)
143         expect(test).to.equal(true)
144       }
145     })
146
147     it('Should upload the video on server 2 and propagate on each server', async function () {
148       this.timeout(50000)
149
150       const user = {
151         username: 'user1',
152         password: 'super_password'
153       }
154       await createUser(servers[1].url, servers[1].accessToken, user.username, user.password)
155       const userAccessToken = await userLogin(servers[1], user)
156
157       const videoAttributes = {
158         name: 'my super name for server 2',
159         category: 4,
160         licence: 3,
161         language: 11,
162         nsfw: true,
163         description: 'my super description for server 2',
164         tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
165         fixture: 'video_short2.webm'
166       }
167       await uploadVideo(servers[1].url, userAccessToken, videoAttributes)
168
169       // Transcoding
170       await wait(30000)
171
172       // All servers should have this video
173       for (const server of servers) {
174         let baseMagnet = {}
175
176         const res = await getVideosList(server.url)
177
178         const videos = res.body.data
179         expect(videos).to.be.an('array')
180         expect(videos.length).to.equal(2)
181         const video = videos[1]
182         expect(video.name).to.equal('my super name for server 2')
183         expect(video.category).to.equal(4)
184         expect(video.categoryLabel).to.equal('Art')
185         expect(video.licence).to.equal(3)
186         expect(video.licenceLabel).to.equal('Attribution - No Derivatives')
187         expect(video.language).to.equal(11)
188         expect(video.languageLabel).to.equal('German')
189         expect(video.nsfw).to.be.true
190         expect(video.description).to.equal('my super description for server 2')
191         expect(video.serverHost).to.equal('localhost:9002')
192         expect(video.duration).to.equal(5)
193         expect(dateIsValid(video.createdAt)).to.be.true
194         expect(dateIsValid(video.updatedAt)).to.be.true
195         expect(video.accountName).to.equal('user1')
196
197         if (server.url !== 'http://localhost:9002') {
198           expect(video.isLocal).to.be.false
199         } else {
200           expect(video.isLocal).to.be.true
201         }
202
203         const res2 = await getVideo(server.url, video.uuid)
204         const videoDetails = res2.body
205
206         expect(videoDetails.channel.name).to.equal('Default user1 channel')
207         expect(dateIsValid(videoDetails.channel.createdAt)).to.be.true
208         expect(dateIsValid(videoDetails.channel.updatedAt)).to.be.true
209         expect(videoDetails.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ])
210
211         expect(videoDetails.files).to.have.lengthOf(4)
212
213         // Check common attributes
214         for (const file of videoDetails.files) {
215           expect(file.magnetUri).to.have.lengthOf.above(2)
216
217           // All servers should have the same magnet Uri
218           if (baseMagnet[file.resolution] === undefined) {
219             baseMagnet[file.resolution] = file.magnet
220           } else {
221             expect(baseMagnet[file.resolution]).to.equal(file.magnet)
222           }
223         }
224
225         const file240p = videoDetails.files.find(f => f.resolution === 240)
226         expect(file240p).not.to.be.undefined
227         expect(file240p.resolutionLabel).to.equal('240p')
228         expect(file240p.size).to.be.above(180000).and.below(200000)
229
230         const file360p = videoDetails.files.find(f => f.resolution === 360)
231         expect(file360p).not.to.be.undefined
232         expect(file360p.resolutionLabel).to.equal('360p')
233         expect(file360p.size).to.be.above(270000).and.below(290000)
234
235         const file480p = videoDetails.files.find(f => f.resolution === 480)
236         expect(file480p).not.to.be.undefined
237         expect(file480p.resolutionLabel).to.equal('480p')
238         expect(file480p.size).to.be.above(380000).and.below(400000)
239
240         const file720p = videoDetails.files.find(f => f.resolution === 720)
241         expect(file720p).not.to.be.undefined
242         expect(file720p.resolutionLabel).to.equal('720p')
243         expect(file720p.size).to.be.above(700000).and.below(7200000)
244
245         const test = await testVideoImage(server.url, 'video_short2.webm', videoDetails.thumbnailPath)
246         expect(test).to.equal(true)
247       }
248     })
249
250     it('Should upload two videos on server 3 and propagate on each server', async function () {
251       this.timeout(45000)
252
253       const videoAttributes1 = {
254         name: 'my super name for server 3',
255         category: 6,
256         licence: 5,
257         language: 11,
258         nsfw: true,
259         description: 'my super description for server 3',
260         tags: [ 'tag1p3' ],
261         fixture: 'video_short3.webm'
262       }
263       await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes1)
264
265       const videoAttributes2 = {
266         name: 'my super name for server 3-2',
267         category: 7,
268         licence: 6,
269         language: 12,
270         nsfw: false,
271         description: 'my super description for server 3-2',
272         tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
273         fixture: 'video_short.webm'
274       }
275       await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes2)
276
277       await wait(10000)
278
279       let baseMagnet = null
280       // All servers should have this video
281       for (const server of servers) {
282         const res = await getVideosList(server.url)
283
284         const videos = res.body.data
285         expect(videos).to.be.an('array')
286         expect(videos.length).to.equal(4)
287
288         // We not sure about the order of the two last uploads
289         let video1 = null
290         let video2 = null
291         if (videos[2].name === 'my super name for server 3') {
292           video1 = videos[2]
293           video2 = videos[3]
294         } else {
295           video1 = videos[3]
296           video2 = videos[2]
297         }
298
299         expect(video1.name).to.equal('my super name for server 3')
300         expect(video1.category).to.equal(6)
301         expect(video1.categoryLabel).to.equal('Travels')
302         expect(video1.licence).to.equal(5)
303         expect(video1.licenceLabel).to.equal('Attribution - Non Commercial - Share Alike')
304         expect(video1.language).to.equal(11)
305         expect(video1.languageLabel).to.equal('German')
306         expect(video1.nsfw).to.be.ok
307         expect(video1.description).to.equal('my super description for server 3')
308         expect(video1.serverHost).to.equal('localhost:9003')
309         expect(video1.duration).to.equal(5)
310         expect(video1.accountName).to.equal('root')
311         expect(dateIsValid(video1.createdAt)).to.be.true
312         expect(dateIsValid(video1.updatedAt)).to.be.true
313
314         const res2 = await getVideo(server.url, video1.id)
315         const video1Details = res2.body
316         expect(video1Details.files).to.have.lengthOf(1)
317         expect(video1Details.tags).to.deep.equal([ 'tag1p3' ])
318
319         const file1 = video1Details.files[0]
320         expect(file1.magnetUri).to.have.lengthOf.above(2)
321         expect(file1.resolution).to.equal(720)
322         expect(file1.resolutionLabel).to.equal('720p')
323         expect(file1.size).to.equal(292677)
324
325         expect(video2.name).to.equal('my super name for server 3-2')
326         expect(video2.category).to.equal(7)
327         expect(video2.categoryLabel).to.equal('Gaming')
328         expect(video2.licence).to.equal(6)
329         expect(video2.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives')
330         expect(video2.language).to.equal(12)
331         expect(video2.languageLabel).to.equal('Korean')
332         expect(video2.nsfw).to.be.false
333         expect(video2.description).to.equal('my super description for server 3-2')
334         expect(video2.serverHost).to.equal('localhost:9003')
335         expect(video2.duration).to.equal(5)
336         expect(video2.accountName).to.equal('root')
337         expect(dateIsValid(video2.createdAt)).to.be.true
338         expect(dateIsValid(video2.updatedAt)).to.be.true
339
340         const res3 = await getVideo(server.url, video2.id)
341         const video2Details = res3.body
342         expect(video2Details.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ])
343
344         expect(video2Details.files).to.have.lengthOf(1)
345
346         const file2 = video2Details.files[0]
347         const magnetUri2 = file2.magnetUri
348         expect(file2.magnetUri).to.have.lengthOf.above(2)
349         expect(file2.resolution).to.equal(720)
350         expect(file2.resolutionLabel).to.equal('720p')
351         expect(file2.size).to.equal(218910)
352
353         if (server.url !== 'http://localhost:9003') {
354           expect(video1.isLocal).to.be.false
355           expect(video2.isLocal).to.be.false
356         } else {
357           expect(video1.isLocal).to.be.true
358           expect(video2.isLocal).to.be.true
359         }
360
361         // All servers should have the same magnet Uri
362         if (baseMagnet === null) {
363           baseMagnet = magnetUri2
364         } else {
365           expect(baseMagnet).to.equal(magnetUri2)
366         }
367
368         const test1 = await testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath)
369         expect(test1).to.equal(true)
370
371         const test2 = await testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath)
372         expect(test2).to.equal(true)
373       }
374     })
375   })
376
377   describe('Should seed the uploaded video', function () {
378     it('Should add the file 1 by asking server 3', async function () {
379       this.timeout(10000)
380
381       const res = await getVideosList(servers[2].url)
382
383       const video = res.body.data[0]
384       toRemove.push(res.body.data[2])
385       toRemove.push(res.body.data[3])
386
387       const res2 = await getVideo(servers[2].url, video.id)
388       const videoDetails = res2.body
389
390       const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri)
391       expect(torrent.files).to.be.an('array')
392       expect(torrent.files.length).to.equal(1)
393       expect(torrent.files[0].path).to.exist.and.to.not.equal('')
394     })
395
396     it('Should add the file 2 by asking server 1', async function () {
397       this.timeout(10000)
398
399       const res = await getVideosList(servers[0].url)
400
401       const video = res.body.data[1]
402       const res2 = await getVideo(servers[0].url, video.id)
403       const videoDetails = res2.body
404
405       const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri)
406       expect(torrent.files).to.be.an('array')
407       expect(torrent.files.length).to.equal(1)
408       expect(torrent.files[0].path).to.exist.and.to.not.equal('')
409     })
410
411     it('Should add the file 3 by asking server 2', async function () {
412       this.timeout(10000)
413
414       const res = await getVideosList(servers[1].url)
415
416       const video = res.body.data[2]
417       const res2 = await getVideo(servers[1].url, video.id)
418       const videoDetails = res2.body
419
420       const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri)
421       expect(torrent.files).to.be.an('array')
422       expect(torrent.files.length).to.equal(1)
423       expect(torrent.files[0].path).to.exist.and.to.not.equal('')
424     })
425
426     it('Should add the file 3-2 by asking server 1', async function () {
427       this.timeout(10000)
428
429       const res = await getVideosList(servers[0].url)
430
431       const video = res.body.data[3]
432       const res2 = await getVideo(servers[0].url, video.id)
433       const videoDetails = res2.body
434
435       const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri)
436       expect(torrent.files).to.be.an('array')
437       expect(torrent.files.length).to.equal(1)
438       expect(torrent.files[0].path).to.exist.and.to.not.equal('')
439     })
440
441     it('Should add the file 2 in 360p by asking server 1', async function () {
442       this.timeout(10000)
443
444       const res = await getVideosList(servers[0].url)
445
446       const video = res.body.data.find(v => v.name === 'my super name for server 2')
447       const res2 = await getVideo(servers[0].url, video.id)
448       const videoDetails = res2.body
449
450       const file = videoDetails.files.find(f => f.resolution === 360)
451       expect(file).not.to.be.undefined
452
453       const torrent = await webtorrentAdd(file.magnetUri)
454       expect(torrent.files).to.be.an('array')
455       expect(torrent.files.length).to.equal(1)
456       expect(torrent.files[0].path).to.exist.and.to.not.equal('')
457     })
458   })
459
460   describe('Should update video views, likes and dislikes', function () {
461     let localVideosServer3 = []
462     let remoteVideosServer1 = []
463     let remoteVideosServer2 = []
464     let remoteVideosServer3 = []
465
466     before(async function () {
467       const res1 = await getVideosList(servers[0].url)
468       remoteVideosServer1 = res1.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
469
470       const res2 = await getVideosList(servers[1].url)
471       remoteVideosServer2 = res2.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
472
473       const res3 = await getVideosList(servers[2].url)
474       localVideosServer3 = res3.body.data.filter(video => video.isLocal === true).map(video => video.uuid)
475       remoteVideosServer3 = res3.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
476     })
477
478     it('Should view multiple videos on owned servers', async function () {
479       this.timeout(10000)
480
481       const tasks: Promise<any>[] = []
482       tasks.push(viewVideo(servers[2].url, localVideosServer3[0]))
483       tasks.push(viewVideo(servers[2].url, localVideosServer3[0]))
484       tasks.push(viewVideo(servers[2].url, localVideosServer3[0]))
485       tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
486
487       await Promise.all(tasks)
488
489       await wait(5000)
490
491       for (const server of servers) {
492         const res = await getVideosList(server.url)
493
494         const videos = res.body.data
495         const video0 = videos.find(v => v.uuid === localVideosServer3[0])
496         const video1 = videos.find(v => v.uuid === localVideosServer3[1])
497
498         expect(video0.views).to.equal(3)
499         expect(video1.views).to.equal(1)
500       }
501     })
502
503     it('Should view multiple videos on each servers', async function () {
504       this.timeout(15000)
505
506       const tasks: Promise<any>[] = []
507       tasks.push(viewVideo(servers[0].url, remoteVideosServer1[0]))
508       tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
509       tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
510       tasks.push(viewVideo(servers[2].url, remoteVideosServer3[0]))
511       tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
512       tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
513       tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
514       tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
515       tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
516       tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
517
518       await Promise.all(tasks)
519
520       await wait(10000)
521
522       let baseVideos = null
523
524       for (const server of servers) {
525         const res = await getVideosList(server.url)
526
527         const videos = res.body.data
528
529         // Initialize base videos for future comparisons
530         if (baseVideos === null) {
531           baseVideos = videos
532           continue
533         }
534
535         for (const baseVideo of baseVideos) {
536           const sameVideo = videos.find(video => video.name === baseVideo.name)
537           expect(baseVideo.views).to.equal(sameVideo.views)
538         }
539       }
540     })
541
542     it('Should like and dislikes videos on different services', async function () {
543       this.timeout(20000)
544
545       const tasks: Promise<any>[] = []
546       tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like'))
547       tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'dislike'))
548       tasks.push(rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like'))
549       tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'like'))
550       tasks.push(rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'dislike'))
551       tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[1], 'dislike'))
552       tasks.push(rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[0], 'like'))
553
554       await Promise.all(tasks)
555
556       await wait(10000)
557
558       let baseVideos = null
559       for (const server of servers) {
560         const res = await getVideosList(server.url)
561
562         const videos = res.body.data
563
564         // Initialize base videos for future comparisons
565         if (baseVideos === null) {
566           baseVideos = videos
567           continue
568         }
569
570         for (const baseVideo of baseVideos) {
571           const sameVideo = videos.find(video => video.name === baseVideo.name)
572           expect(baseVideo.likes).to.equal(sameVideo.likes)
573           expect(baseVideo.dislikes).to.equal(sameVideo.dislikes)
574         }
575       }
576     })
577   })
578
579   describe('Should manipulate these videos', function () {
580     it('Should update the video 3 by asking server 3', async function () {
581       this.timeout(10000)
582
583       const attributes = {
584         name: 'my super video updated',
585         category: 10,
586         licence: 7,
587         language: 13,
588         nsfw: true,
589         description: 'my super description updated',
590         tags: [ 'tag_up_1', 'tag_up_2' ]
591       }
592
593       await updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes)
594
595       await wait(5000)
596     })
597
598     it('Should have the video 3 updated on each server', async function () {
599       this.timeout(10000)
600
601       for (const server of servers) {
602         const res = await getVideosList(server.url)
603
604         const videos = res.body.data
605         const videoUpdated = videos.find(video => video.name === 'my super video updated')
606
607         expect(!!videoUpdated).to.be.true
608         expect(videoUpdated.category).to.equal(10)
609         expect(videoUpdated.categoryLabel).to.equal('Entertainment')
610         expect(videoUpdated.licence).to.equal(7)
611         expect(videoUpdated.licenceLabel).to.equal('Public Domain Dedication')
612         expect(videoUpdated.language).to.equal(13)
613         expect(videoUpdated.languageLabel).to.equal('French')
614         expect(videoUpdated.nsfw).to.be.ok
615         expect(videoUpdated.description).to.equal('my super description updated')
616         expect(dateIsValid(videoUpdated.updatedAt, 20000)).to.be.true
617
618         const res2 = await getVideo(server.url, videoUpdated.uuid)
619         const videoUpdatedDetails = res2.body
620         expect(videoUpdatedDetails.tags).to.deep.equal([ 'tag_up_1', 'tag_up_2' ])
621
622         const file = videoUpdatedDetails.files[0]
623         expect(file.magnetUri).to.have.lengthOf.above(2)
624         expect(file.resolution).to.equal(720)
625         expect(file.resolutionLabel).to.equal('720p')
626         expect(file.size).to.equal(292677)
627
628         const test = await testVideoImage(server.url, 'video_short3.webm', videoUpdated.thumbnailPath)
629         expect(test).to.equal(true)
630
631         // Avoid "duplicate torrent" errors
632         const refreshWebTorrent = true
633         const torrent = await webtorrentAdd(videoUpdatedDetails .files[0].magnetUri, refreshWebTorrent)
634         expect(torrent.files).to.be.an('array')
635         expect(torrent.files.length).to.equal(1)
636         expect(torrent.files[0].path).to.exist.and.to.not.equal('')
637       }
638     })
639
640     it('Should remove the videos 3 and 3-2 by asking server 3', async function () {
641       this.timeout(10000)
642
643       await removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id)
644       await removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id)
645
646       await wait(5000)
647     })
648
649     it('Should have videos 1 and 3 on each server', async function () {
650       for (const server of servers) {
651         const res = await getVideosList(server.url)
652
653         const videos = res.body.data
654         expect(videos).to.be.an('array')
655         expect(videos.length).to.equal(2)
656         expect(videos[0].name).not.to.equal(videos[1].name)
657         expect(videos[0].name).not.to.equal(toRemove[0].name)
658         expect(videos[1].name).not.to.equal(toRemove[0].name)
659         expect(videos[0].name).not.to.equal(toRemove[1].name)
660         expect(videos[1].name).not.to.equal(toRemove[1].name)
661
662         videoUUID = videos.find(video => video.name === 'my super name for server 1').uuid
663       }
664     })
665
666     it('Should get the same video by UUID on each server', async function () {
667       let baseVideo = null
668       for (const server of servers) {
669         const res = await getVideo(server.url, videoUUID)
670
671         const video = res.body
672
673         if (baseVideo === null) {
674           baseVideo = video
675           continue
676         }
677
678         expect(baseVideo.name).to.equal(video.name)
679         expect(baseVideo.uuid).to.equal(video.uuid)
680         expect(baseVideo.category).to.equal(video.category)
681         expect(baseVideo.language).to.equal(video.language)
682         expect(baseVideo.licence).to.equal(video.licence)
683         expect(baseVideo.category).to.equal(video.category)
684         expect(baseVideo.nsfw).to.equal(video.nsfw)
685         expect(baseVideo.accountName).to.equal(video.accountName)
686         expect(baseVideo.tags).to.deep.equal(video.tags)
687       }
688     })
689
690     it('Should get the preview from each server', async function () {
691       for (const server of servers) {
692         const res = await getVideo(server.url, videoUUID)
693         const video = res.body
694
695         const test = await testVideoImage(server.url, 'video_short1-preview.webm', video.previewPath)
696         expect(test).to.equal(true)
697       }
698     })
699   })
700
701   describe('Should comment these videos', function () {
702     it('Should add comment (threads and replies)', async function () {
703       this.timeout(25000)
704
705       {
706         const text = 'my super first comment'
707         await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, text)
708       }
709
710       {
711         const text = 'my super second comment'
712         await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, text)
713       }
714
715       await wait(5000)
716
717       {
718         const res = await getVideoCommentThreads(servers[1].url, videoUUID, 0, 5)
719         const threadId = res.body.data.find(c => c.text === 'my super first comment').id
720
721         const text = 'my super answer to thread 1'
722         await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, videoUUID, threadId, text)
723       }
724
725       await wait(5000)
726
727       {
728         const res1 = await getVideoCommentThreads(servers[2].url, videoUUID, 0, 5)
729         const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
730
731         const res2 = await getVideoThreadComments(servers[2].url, videoUUID, threadId)
732         const childCommentId = res2.body.children[0].comment.id
733
734         const text3 = 'my second answer to thread 1'
735         await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, threadId, text3)
736
737         const text2 = 'my super answer to answer of thread 1'
738         await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, childCommentId, text2)
739       }
740
741       await wait(5000)
742     })
743
744     it('Should have these threads', async function () {
745       for (const server of servers) {
746         const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
747
748         expect(res.body.total).to.equal(2)
749         expect(res.body.data).to.be.an('array')
750         expect(res.body.data).to.have.lengthOf(2)
751
752         {
753           const comment: VideoComment = res.body.data.find(c => c.text === 'my super first comment')
754           expect(comment).to.not.be.undefined
755           expect(comment.inReplyToCommentId).to.be.null
756           expect(comment.account.name).to.equal('root')
757           expect(comment.account.host).to.equal('localhost:9001')
758           expect(comment.totalReplies).to.equal(3)
759           expect(dateIsValid(comment.createdAt as string)).to.be.true
760           expect(dateIsValid(comment.updatedAt as string)).to.be.true
761         }
762
763         {
764           const comment: VideoComment = res.body.data.find(c => c.text === 'my super second comment')
765           expect(comment).to.not.be.undefined
766           expect(comment.inReplyToCommentId).to.be.null
767           expect(comment.account.name).to.equal('root')
768           expect(comment.account.host).to.equal('localhost:9003')
769           expect(comment.totalReplies).to.equal(0)
770           expect(dateIsValid(comment.createdAt as string)).to.be.true
771           expect(dateIsValid(comment.updatedAt as string)).to.be.true
772         }
773       }
774     })
775
776     it('Should have these comments', async function () {
777       for (const server of servers) {
778         const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
779         const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
780
781         const res2 = await getVideoThreadComments(server.url, videoUUID, threadId)
782
783         const tree: VideoCommentThreadTree = res2.body
784         expect(tree.comment.text).equal('my super first comment')
785         expect(tree.comment.account.name).equal('root')
786         expect(tree.comment.account.host).equal('localhost:9001')
787         expect(tree.children).to.have.lengthOf(2)
788
789         const firstChild = tree.children[0]
790         expect(firstChild.comment.text).to.equal('my super answer to thread 1')
791         expect(firstChild.comment.account.name).equal('root')
792         expect(firstChild.comment.account.host).equal('localhost:9002')
793         expect(firstChild.children).to.have.lengthOf(1)
794
795         const childOfFirstChild = firstChild.children[0]
796         expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
797         expect(childOfFirstChild.comment.account.name).equal('root')
798         expect(childOfFirstChild.comment.account.host).equal('localhost:9003')
799         expect(childOfFirstChild.children).to.have.lengthOf(0)
800
801         const secondChild = tree.children[1]
802         expect(secondChild.comment.text).to.equal('my second answer to thread 1')
803         expect(secondChild.comment.account.name).equal('root')
804         expect(secondChild.comment.account.host).equal('localhost:9003')
805         expect(secondChild.children).to.have.lengthOf(0)
806       }
807     })
808   })
809
810   describe('With minimum parameters', function () {
811     it('Should upload and propagate the video', async function () {
812       this.timeout(50000)
813
814       const path = '/api/v1/videos/upload'
815
816       const req = request(servers[1].url)
817         .post(path)
818         .set('Accept', 'application/json')
819         .set('Authorization', 'Bearer ' + servers[1].accessToken)
820         .field('name', 'minimum parameters')
821         .field('privacy', '1')
822         .field('nsfw', 'false')
823         .field('channelId', '1')
824
825       const filePath = join(__dirname, '..', 'api', 'fixtures', 'video_short.webm')
826
827       await req.attach('videofile', filePath)
828         .expect(200)
829
830       await wait(25000)
831
832       for (const server of servers) {
833         const res = await getVideosList(server.url)
834         const video = res.body.data.find(v => v.name === 'minimum parameters')
835
836         expect(video.name).to.equal('minimum parameters')
837         expect(video.category).to.equal(null)
838         expect(video.categoryLabel).to.equal('Misc')
839         expect(video.licence).to.equal(null)
840         expect(video.licenceLabel).to.equal('Unknown')
841         expect(video.language).to.equal(null)
842         expect(video.languageLabel).to.equal('Unknown')
843         expect(video.nsfw).to.not.be.ok
844         expect(video.description).to.equal(null)
845         expect(video.serverHost).to.equal('localhost:9002')
846         expect(video.accountName).to.equal('root')
847         expect(dateIsValid(video.createdAt)).to.be.true
848         expect(dateIsValid(video.updatedAt)).to.be.true
849       }
850     })
851   })
852
853   after(async function () {
854     killallServers(servers)
855
856     // Keep the logs if the test failed
857     if (this['ok']) {
858       await flushTests()
859     }
860   })
861 })