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