]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/videos/multiple-servers.ts
58381a0e50d18b0d839393b3f8be666d698ff0b2
[github/Chocobozzz/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 { VideoPrivacy } from '../../../../shared/models/videos'
8 import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
9
10 import {
11 addVideoChannel,
12 checkVideoFilesWereRemoved,
13 completeVideoCheck,
14 createUser,
15 dateIsValid,
16 doubleFollow,
17 flushAndRunMultipleServers,
18 flushTests,
19 getLocalVideos,
20 getVideo,
21 getVideoChannelsList,
22 getVideosList,
23 killallServers,
24 rateVideo,
25 removeVideo,
26 ServerInfo,
27 setAccessTokensToServers,
28 testImage,
29 updateVideo,
30 uploadVideo,
31 userLogin,
32 viewVideo,
33 wait,
34 webtorrentAdd
35 } from '../../utils'
36 import {
37 addVideoCommentReply,
38 addVideoCommentThread,
39 deleteVideoComment,
40 getVideoCommentThreads,
41 getVideoThreadComments
42 } from '../../utils/videos/video-comments'
43 import { waitJobs } from '../../utils/server/jobs'
44
45 const expect = chai.expect
46
47 describe('Test multiple servers', function () {
48 let servers: ServerInfo[] = []
49 const toRemove = []
50 let videoUUID = ''
51 let videoChannelId: number
52
53 before(async function () {
54 this.timeout(120000)
55
56 servers = await flushAndRunMultipleServers(3)
57
58 // Get the access tokens
59 await setAccessTokensToServers(servers)
60
61 {
62 const videoChannel = {
63 displayName: 'my channel',
64 description: 'super channel'
65 }
66 await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, videoChannel)
67 const channelRes = await getVideoChannelsList(servers[ 0 ].url, 0, 1)
68 videoChannelId = channelRes.body.data[ 0 ].id
69 }
70
71 // Server 1 and server 2 follow each other
72 await doubleFollow(servers[0], servers[1])
73 // Server 1 and server 3 follow each other
74 await doubleFollow(servers[0], servers[2])
75 // Server 2 and server 3 follow each other
76 await doubleFollow(servers[1], servers[2])
77 })
78
79 it('Should not have videos for all servers', async function () {
80 for (const server of servers) {
81 const res = await getVideosList(server.url)
82 const videos = res.body.data
83 expect(videos).to.be.an('array')
84 expect(videos.length).to.equal(0)
85 }
86 })
87
88 describe('Should upload the video and propagate on each server', function () {
89 it('Should upload the video on server 1 and propagate on each server', async function () {
90 this.timeout(25000)
91
92 const videoAttributes = {
93 name: 'my super name for server 1',
94 category: 5,
95 licence: 4,
96 language: 'ja',
97 nsfw: true,
98 description: 'my super description for server 1',
99 support: 'my super support text for server 1',
100 tags: [ 'tag1p1', 'tag2p1' ],
101 channelId: videoChannelId,
102 fixture: 'video_short1.webm'
103 }
104 await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
105
106 await waitJobs(servers)
107
108 // All servers should have this video
109 let publishedAt: string = null
110 for (const server of servers) {
111 const isLocal = server.url === 'http://localhost:9001'
112 const checkAttributes = {
113 name: 'my super name for server 1',
114 category: 5,
115 licence: 4,
116 language: 'ja',
117 nsfw: true,
118 description: 'my super description for server 1',
119 support: 'my super support text for server 1',
120 account: {
121 name: 'root',
122 host: 'localhost:9001'
123 },
124 isLocal,
125 publishedAt,
126 duration: 10,
127 tags: [ 'tag1p1', 'tag2p1' ],
128 privacy: VideoPrivacy.PUBLIC,
129 commentsEnabled: true,
130 channel: {
131 name: 'my channel',
132 description: 'super channel',
133 isLocal
134 },
135 fixture: 'video_short1.webm',
136 files: [
137 {
138 resolution: 720,
139 size: 572456
140 }
141 ]
142 }
143
144 const res = await getVideosList(server.url)
145 const videos = res.body.data
146 expect(videos).to.be.an('array')
147 expect(videos.length).to.equal(1)
148 const video = videos[0]
149
150 await completeVideoCheck(server.url, video, checkAttributes)
151 publishedAt = video.publishedAt
152 }
153 })
154
155 it('Should upload the video on server 2 and propagate on each server', async function () {
156 this.timeout(50000)
157
158 const user = {
159 username: 'user1',
160 password: 'super_password'
161 }
162 await createUser(servers[1].url, servers[1].accessToken, user.username, user.password)
163 const userAccessToken = await userLogin(servers[1], user)
164
165 const videoAttributes = {
166 name: 'my super name for server 2',
167 category: 4,
168 licence: 3,
169 language: 'de',
170 nsfw: true,
171 description: 'my super description for server 2',
172 support: 'my super support text for server 2',
173 tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
174 fixture: 'video_short2.webm',
175 thumbnailfile: 'thumbnail.jpg',
176 previewfile: 'preview.jpg'
177 }
178 await uploadVideo(servers[1].url, userAccessToken, videoAttributes)
179
180 // Transcoding
181 await waitJobs(servers)
182
183 // All servers should have this video
184 for (const server of servers) {
185 const isLocal = server.url === 'http://localhost:9002'
186 const checkAttributes = {
187 name: 'my super name for server 2',
188 category: 4,
189 licence: 3,
190 language: 'de',
191 nsfw: true,
192 description: 'my super description for server 2',
193 support: 'my super support text for server 2',
194 account: {
195 name: 'user1',
196 host: 'localhost:9002'
197 },
198 isLocal,
199 commentsEnabled: true,
200 duration: 5,
201 tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
202 privacy: VideoPrivacy.PUBLIC,
203 channel: {
204 name: 'Default user1 channel',
205 description: 'super channel',
206 isLocal
207 },
208 fixture: 'video_short2.webm',
209 files: [
210 {
211 resolution: 240,
212 size: 342000
213 },
214 {
215 resolution: 360,
216 size: 433000
217 },
218 {
219 resolution: 480,
220 size: 538000
221 },
222 {
223 resolution: 720,
224 size: 861000
225 }
226 ],
227 thumbnailfile: 'thumbnail',
228 previewfile: 'preview'
229 }
230
231 const res = await getVideosList(server.url)
232 const videos = res.body.data
233 expect(videos).to.be.an('array')
234 expect(videos.length).to.equal(2)
235 const video = videos[1]
236
237 await completeVideoCheck(server.url, video, checkAttributes)
238 }
239 })
240
241 it('Should upload two videos on server 3 and propagate on each server', async function () {
242 this.timeout(45000)
243
244 const videoAttributes1 = {
245 name: 'my super name for server 3',
246 category: 6,
247 licence: 5,
248 language: 'de',
249 nsfw: true,
250 description: 'my super description for server 3',
251 support: 'my super support text for server 3',
252 tags: [ 'tag1p3' ],
253 fixture: 'video_short3.webm'
254 }
255 await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes1)
256
257 const videoAttributes2 = {
258 name: 'my super name for server 3-2',
259 category: 7,
260 licence: 6,
261 language: 'ko',
262 nsfw: false,
263 description: 'my super description for server 3-2',
264 support: 'my super support text for server 3-2',
265 tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
266 fixture: 'video_short.webm'
267 }
268 await uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes2)
269
270 await waitJobs(servers)
271
272 // All servers should have this video
273 for (const server of servers) {
274 const isLocal = server.url === 'http://localhost:9003'
275 const res = await getVideosList(server.url)
276
277 const videos = res.body.data
278 expect(videos).to.be.an('array')
279 expect(videos.length).to.equal(4)
280
281 // We not sure about the order of the two last uploads
282 let video1 = null
283 let video2 = null
284 if (videos[2].name === 'my super name for server 3') {
285 video1 = videos[2]
286 video2 = videos[3]
287 } else {
288 video1 = videos[3]
289 video2 = videos[2]
290 }
291
292 const checkAttributesVideo1 = {
293 name: 'my super name for server 3',
294 category: 6,
295 licence: 5,
296 language: 'de',
297 nsfw: true,
298 description: 'my super description for server 3',
299 support: 'my super support text for server 3',
300 account: {
301 name: 'root',
302 host: 'localhost:9003'
303 },
304 isLocal,
305 duration: 5,
306 commentsEnabled: true,
307 tags: [ 'tag1p3' ],
308 privacy: VideoPrivacy.PUBLIC,
309 channel: {
310 name: 'Default root channel',
311 description: '',
312 isLocal
313 },
314 fixture: 'video_short3.webm',
315 files: [
316 {
317 resolution: 720,
318 size: 292677
319 }
320 ]
321 }
322 await completeVideoCheck(server.url, video1, checkAttributesVideo1)
323
324 const checkAttributesVideo2 = {
325 name: 'my super name for server 3-2',
326 category: 7,
327 licence: 6,
328 language: 'ko',
329 nsfw: false,
330 description: 'my super description for server 3-2',
331 support: 'my super support text for server 3-2',
332 account: {
333 name: 'root',
334 host: 'localhost:9003'
335 },
336 commentsEnabled: true,
337 isLocal,
338 duration: 5,
339 tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
340 privacy: VideoPrivacy.PUBLIC,
341 channel: {
342 name: 'Default root channel',
343 description: '',
344 isLocal
345 },
346 fixture: 'video_short.webm',
347 files: [
348 {
349 resolution: 720,
350 size: 218910
351 }
352 ]
353 }
354 await completeVideoCheck(server.url, video2, checkAttributesVideo2)
355 }
356 })
357 })
358
359 describe('It should list local videos', function () {
360 it('Should list only local videos on server 1', async function () {
361 const { body } = await getLocalVideos(servers[0].url)
362
363 expect(body.total).to.equal(1)
364 expect(body.data).to.be.an('array')
365 expect(body.data.length).to.equal(1)
366 expect(body.data[0].name).to.equal('my super name for server 1')
367 })
368
369 it('Should list only local videos on server 2', async function () {
370 const { body } = await getLocalVideos(servers[1].url)
371
372 expect(body.total).to.equal(1)
373 expect(body.data).to.be.an('array')
374 expect(body.data.length).to.equal(1)
375 expect(body.data[0].name).to.equal('my super name for server 2')
376 })
377
378 it('Should list only local videos on server 3', async function () {
379 const { body } = await getLocalVideos(servers[2].url)
380
381 expect(body.total).to.equal(2)
382 expect(body.data).to.be.an('array')
383 expect(body.data.length).to.equal(2)
384 expect(body.data[0].name).to.equal('my super name for server 3')
385 expect(body.data[1].name).to.equal('my super name for server 3-2')
386 })
387 })
388
389 describe('Should seed the uploaded video', function () {
390 it('Should add the file 1 by asking server 3', async function () {
391 this.timeout(10000)
392
393 const res = await getVideosList(servers[2].url)
394
395 const video = res.body.data[0]
396 toRemove.push(res.body.data[2])
397 toRemove.push(res.body.data[3])
398
399 const res2 = await getVideo(servers[2].url, video.id)
400 const videoDetails = res2.body
401
402 const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
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 2 by asking server 1', async function () {
409 this.timeout(10000)
410
411 const res = await getVideosList(servers[0].url)
412
413 const video = res.body.data[1]
414 const res2 = await getVideo(servers[0].url, video.id)
415 const videoDetails = res2.body
416
417 const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
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 by asking server 2', async function () {
424 this.timeout(10000)
425
426 const res = await getVideosList(servers[1].url)
427
428 const video = res.body.data[2]
429 const res2 = await getVideo(servers[1].url, video.id)
430 const videoDetails = res2.body
431
432 const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
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 3-2 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[3]
444 const res2 = await getVideo(servers[0].url, video.id)
445 const videoDetails = res2.body
446
447 const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri)
448 expect(torrent.files).to.be.an('array')
449 expect(torrent.files.length).to.equal(1)
450 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
451 })
452
453 it('Should add the file 2 in 360p by asking server 1', async function () {
454 this.timeout(10000)
455
456 const res = await getVideosList(servers[0].url)
457
458 const video = res.body.data.find(v => v.name === 'my super name for server 2')
459 const res2 = await getVideo(servers[0].url, video.id)
460 const videoDetails = res2.body
461
462 const file = videoDetails.files.find(f => f.resolution.id === 360)
463 expect(file).not.to.be.undefined
464
465 const torrent = await webtorrentAdd(file.magnetUri)
466 expect(torrent.files).to.be.an('array')
467 expect(torrent.files.length).to.equal(1)
468 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
469 })
470 })
471
472 describe('Should update video views, likes and dislikes', function () {
473 let localVideosServer3 = []
474 let remoteVideosServer1 = []
475 let remoteVideosServer2 = []
476 let remoteVideosServer3 = []
477
478 before(async function () {
479 const res1 = await getVideosList(servers[0].url)
480 remoteVideosServer1 = res1.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
481
482 const res2 = await getVideosList(servers[1].url)
483 remoteVideosServer2 = res2.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
484
485 const res3 = await getVideosList(servers[2].url)
486 localVideosServer3 = res3.body.data.filter(video => video.isLocal === true).map(video => video.uuid)
487 remoteVideosServer3 = res3.body.data.filter(video => video.isLocal === false).map(video => video.uuid)
488 })
489
490 it('Should view multiple videos on owned servers', async function () {
491 this.timeout(15000)
492
493 const tasks: Promise<any>[] = []
494 await viewVideo(servers[2].url, localVideosServer3[0])
495 await viewVideo(servers[2].url, localVideosServer3[0])
496 await viewVideo(servers[2].url, localVideosServer3[0])
497 await viewVideo(servers[2].url, localVideosServer3[1])
498
499 await Promise.all(tasks)
500 await waitJobs(servers)
501
502 await viewVideo(servers[2].url, localVideosServer3[0])
503
504 await waitJobs(servers)
505
506 await viewVideo(servers[2].url, localVideosServer3[0])
507
508 await waitJobs(servers)
509
510 for (const server of servers) {
511 const res = await getVideosList(server.url)
512
513 const videos = res.body.data
514 const video0 = videos.find(v => v.uuid === localVideosServer3[0])
515 const video1 = videos.find(v => v.uuid === localVideosServer3[1])
516
517 expect(video0.views).to.equal(3)
518 expect(video1.views).to.equal(1)
519 }
520 })
521
522 it('Should view multiple videos on each servers', async function () {
523 this.timeout(15000)
524
525 const tasks: Promise<any>[] = []
526 tasks.push(viewVideo(servers[0].url, remoteVideosServer1[0]))
527 tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
528 tasks.push(viewVideo(servers[1].url, remoteVideosServer2[0]))
529 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[0]))
530 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
531 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
532 tasks.push(viewVideo(servers[2].url, remoteVideosServer3[1]))
533 tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
534 tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
535 tasks.push(viewVideo(servers[2].url, localVideosServer3[1]))
536
537 await Promise.all(tasks)
538
539 await waitJobs(servers)
540
541 let baseVideos = null
542
543 for (const server of servers) {
544 const res = await getVideosList(server.url)
545
546 const videos = res.body.data
547
548 // Initialize base videos for future comparisons
549 if (baseVideos === null) {
550 baseVideos = videos
551 continue
552 }
553
554 for (const baseVideo of baseVideos) {
555 const sameVideo = videos.find(video => video.name === baseVideo.name)
556 expect(baseVideo.views).to.equal(sameVideo.views)
557 }
558 }
559 })
560
561 it('Should like and dislikes videos on different services', async function () {
562 this.timeout(20000)
563
564 await rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')
565 await wait(200)
566 await rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'dislike')
567 await wait(200)
568 await rateVideo(servers[0].url, servers[0].accessToken, remoteVideosServer1[0], 'like')
569 await rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'like')
570 await wait(200)
571 await rateVideo(servers[2].url, servers[2].accessToken, localVideosServer3[1], 'dislike')
572 await rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[1], 'dislike')
573 await wait(200)
574 await rateVideo(servers[2].url, servers[2].accessToken, remoteVideosServer3[0], 'like')
575
576 await waitJobs(servers)
577
578 let baseVideos = null
579 for (const server of servers) {
580 const res = await getVideosList(server.url)
581
582 const videos = res.body.data
583
584 // Initialize base videos for future comparisons
585 if (baseVideos === null) {
586 baseVideos = videos
587 continue
588 }
589
590 for (const baseVideo of baseVideos) {
591 const sameVideo = videos.find(video => video.name === baseVideo.name)
592 expect(baseVideo.likes).to.equal(sameVideo.likes)
593 expect(baseVideo.dislikes).to.equal(sameVideo.dislikes)
594 }
595 }
596 })
597 })
598
599 describe('Should manipulate these videos', function () {
600 it('Should update the video 3 by asking server 3', async function () {
601 this.timeout(10000)
602
603 const attributes = {
604 name: 'my super video updated',
605 category: 10,
606 licence: 7,
607 language: 'fr',
608 nsfw: true,
609 description: 'my super description updated',
610 support: 'my super support text updated',
611 tags: [ 'tag_up_1', 'tag_up_2' ],
612 thumbnailfile: 'thumbnail.jpg',
613 previewfile: 'preview.jpg'
614 }
615
616 await updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes)
617
618 await waitJobs(servers)
619 })
620
621 it('Should have the video 3 updated on each server', async function () {
622 this.timeout(10000)
623
624 for (const server of servers) {
625 const res = await getVideosList(server.url)
626
627 const videos = res.body.data
628 const videoUpdated = videos.find(video => video.name === 'my super video updated')
629 expect(!!videoUpdated).to.be.true
630
631 const isLocal = server.url === 'http://localhost:9003'
632 const checkAttributes = {
633 name: 'my super video updated',
634 category: 10,
635 licence: 7,
636 language: 'fr',
637 nsfw: true,
638 description: 'my super description updated',
639 support: 'my super support text updated',
640 account: {
641 name: 'root',
642 host: 'localhost:9003'
643 },
644 isLocal,
645 duration: 5,
646 commentsEnabled: true,
647 tags: [ 'tag_up_1', 'tag_up_2' ],
648 privacy: VideoPrivacy.PUBLIC,
649 channel: {
650 name: 'Default root channel',
651 description: '',
652 isLocal
653 },
654 fixture: 'video_short3.webm',
655 files: [
656 {
657 resolution: 720,
658 size: 292677
659 }
660 ],
661 thumbnailfile: 'thumbnail',
662 previewfile: 'preview'
663 }
664 await completeVideoCheck(server.url, videoUpdated, checkAttributes)
665 }
666 })
667
668 it('Should remove the videos 3 and 3-2 by asking server 3', async function () {
669 this.timeout(10000)
670
671 await removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id)
672 await removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id)
673
674 await waitJobs(servers)
675 })
676
677 it('Should not have files of videos 3 and 3-2 on each server', async function () {
678 for (const server of servers) {
679 await checkVideoFilesWereRemoved(toRemove[0].uuid, server.serverNumber)
680 await checkVideoFilesWereRemoved(toRemove[1].uuid, server.serverNumber)
681 }
682 })
683
684 it('Should have videos 1 and 3 on each server', async function () {
685 for (const server of servers) {
686 const res = await getVideosList(server.url)
687
688 const videos = res.body.data
689 expect(videos).to.be.an('array')
690 expect(videos.length).to.equal(2)
691 expect(videos[0].name).not.to.equal(videos[1].name)
692 expect(videos[0].name).not.to.equal(toRemove[0].name)
693 expect(videos[1].name).not.to.equal(toRemove[0].name)
694 expect(videos[0].name).not.to.equal(toRemove[1].name)
695 expect(videos[1].name).not.to.equal(toRemove[1].name)
696
697 videoUUID = videos.find(video => video.name === 'my super name for server 1').uuid
698 }
699 })
700
701 it('Should get the same video by UUID on each server', async function () {
702 let baseVideo = null
703 for (const server of servers) {
704 const res = await getVideo(server.url, videoUUID)
705
706 const video = res.body
707
708 if (baseVideo === null) {
709 baseVideo = video
710 continue
711 }
712
713 expect(baseVideo.name).to.equal(video.name)
714 expect(baseVideo.uuid).to.equal(video.uuid)
715 expect(baseVideo.category.id).to.equal(video.category.id)
716 expect(baseVideo.language.id).to.equal(video.language.id)
717 expect(baseVideo.licence.id).to.equal(video.licence.id)
718 expect(baseVideo.nsfw).to.equal(video.nsfw)
719 expect(baseVideo.account.name).to.equal(video.account.name)
720 expect(baseVideo.account.displayName).to.equal(video.account.displayName)
721 expect(baseVideo.account.url).to.equal(video.account.url)
722 expect(baseVideo.account.host).to.equal(video.account.host)
723 expect(baseVideo.tags).to.deep.equal(video.tags)
724 }
725 })
726
727 it('Should get the preview from each server', async function () {
728 for (const server of servers) {
729 const res = await getVideo(server.url, videoUUID)
730 const video = res.body
731
732 await testImage(server.url, 'video_short1-preview.webm', video.previewPath)
733 }
734 })
735 })
736
737 describe('Should comment these videos', function () {
738 let childOfFirstChild: VideoCommentThreadTree
739
740 it('Should add comment (threads and replies)', async function () {
741 this.timeout(25000)
742
743 {
744 const text = 'my super first comment'
745 await addVideoCommentThread(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, text)
746 }
747
748 {
749 const text = 'my super second comment'
750 await addVideoCommentThread(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, text)
751 }
752
753 await waitJobs(servers)
754
755 {
756 const res = await getVideoCommentThreads(servers[1].url, videoUUID, 0, 5)
757 const threadId = res.body.data.find(c => c.text === 'my super first comment').id
758
759 const text = 'my super answer to thread 1'
760 await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, videoUUID, threadId, text)
761 }
762
763 await waitJobs(servers)
764
765 {
766 const res1 = await getVideoCommentThreads(servers[2].url, videoUUID, 0, 5)
767 const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
768
769 const res2 = await getVideoThreadComments(servers[2].url, videoUUID, threadId)
770 const childCommentId = res2.body.children[0].comment.id
771
772 const text3 = 'my second answer to thread 1'
773 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, threadId, text3)
774
775 const text2 = 'my super answer to answer of thread 1'
776 await addVideoCommentReply(servers[ 2 ].url, servers[ 2 ].accessToken, videoUUID, childCommentId, text2)
777 }
778
779 await waitJobs(servers)
780 })
781
782 it('Should have these threads', async function () {
783 for (const server of servers) {
784 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
785
786 expect(res.body.total).to.equal(2)
787 expect(res.body.data).to.be.an('array')
788 expect(res.body.data).to.have.lengthOf(2)
789
790 {
791 const comment: VideoComment = res.body.data.find(c => c.text === 'my super first comment')
792 expect(comment).to.not.be.undefined
793 expect(comment.inReplyToCommentId).to.be.null
794 expect(comment.account.name).to.equal('root')
795 expect(comment.account.host).to.equal('localhost:9001')
796 expect(comment.totalReplies).to.equal(3)
797 expect(dateIsValid(comment.createdAt as string)).to.be.true
798 expect(dateIsValid(comment.updatedAt as string)).to.be.true
799 }
800
801 {
802 const comment: VideoComment = res.body.data.find(c => c.text === 'my super second comment')
803 expect(comment).to.not.be.undefined
804 expect(comment.inReplyToCommentId).to.be.null
805 expect(comment.account.name).to.equal('root')
806 expect(comment.account.host).to.equal('localhost:9003')
807 expect(comment.totalReplies).to.equal(0)
808 expect(dateIsValid(comment.createdAt as string)).to.be.true
809 expect(dateIsValid(comment.updatedAt as string)).to.be.true
810 }
811 }
812 })
813
814 it('Should have these comments', async function () {
815 for (const server of servers) {
816 const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
817 const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
818
819 const res2 = await getVideoThreadComments(server.url, videoUUID, threadId)
820
821 const tree: VideoCommentThreadTree = res2.body
822 expect(tree.comment.text).equal('my super first comment')
823 expect(tree.comment.account.name).equal('root')
824 expect(tree.comment.account.host).equal('localhost:9001')
825 expect(tree.children).to.have.lengthOf(2)
826
827 const firstChild = tree.children[0]
828 expect(firstChild.comment.text).to.equal('my super answer to thread 1')
829 expect(firstChild.comment.account.name).equal('root')
830 expect(firstChild.comment.account.host).equal('localhost:9002')
831 expect(firstChild.children).to.have.lengthOf(1)
832
833 childOfFirstChild = firstChild.children[0]
834 expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
835 expect(childOfFirstChild.comment.account.name).equal('root')
836 expect(childOfFirstChild.comment.account.host).equal('localhost:9003')
837 expect(childOfFirstChild.children).to.have.lengthOf(0)
838
839 const secondChild = tree.children[1]
840 expect(secondChild.comment.text).to.equal('my second answer to thread 1')
841 expect(secondChild.comment.account.name).equal('root')
842 expect(secondChild.comment.account.host).equal('localhost:9003')
843 expect(secondChild.children).to.have.lengthOf(0)
844 }
845 })
846
847 it('Should delete a reply', async function () {
848 this.timeout(10000)
849
850 await deleteVideoComment(servers[2].url, servers[2].accessToken, videoUUID, childOfFirstChild.comment.id)
851
852 await waitJobs(servers)
853 })
854
855 it('Should not have this comment anymore', async function () {
856 for (const server of servers) {
857 const res1 = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
858 const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
859
860 const res2 = await getVideoThreadComments(server.url, videoUUID, threadId)
861
862 const tree: VideoCommentThreadTree = res2.body
863 expect(tree.comment.text).equal('my super first comment')
864
865 const firstChild = tree.children[0]
866 expect(firstChild.comment.text).to.equal('my super answer to thread 1')
867 expect(firstChild.children).to.have.lengthOf(0)
868
869 const secondChild = tree.children[1]
870 expect(secondChild.comment.text).to.equal('my second answer to thread 1')
871 }
872 })
873
874 it('Should delete the thread comments', async function () {
875 this.timeout(10000)
876
877 const res1 = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5)
878 const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
879 await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId)
880
881 await waitJobs(servers)
882 })
883
884 it('Should have the thread comments deleted on other servers too', async function () {
885 for (const server of servers) {
886 const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
887
888 expect(res.body.total).to.equal(1)
889 expect(res.body.data).to.be.an('array')
890 expect(res.body.data).to.have.lengthOf(1)
891
892 {
893 const comment: VideoComment = res.body.data[0]
894 expect(comment).to.not.be.undefined
895 expect(comment.inReplyToCommentId).to.be.null
896 expect(comment.account.name).to.equal('root')
897 expect(comment.account.host).to.equal('localhost:9003')
898 expect(comment.totalReplies).to.equal(0)
899 expect(dateIsValid(comment.createdAt as string)).to.be.true
900 expect(dateIsValid(comment.updatedAt as string)).to.be.true
901 }
902 }
903 })
904
905 it('Should disable comments', async function () {
906 this.timeout(20000)
907
908 const attributes = {
909 commentsEnabled: false
910 }
911
912 await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, attributes)
913
914 await waitJobs(servers)
915
916 for (const server of servers) {
917 const res = await getVideo(server.url, videoUUID)
918 expect(res.body.commentsEnabled).to.be.false
919
920 const text = 'my super forbidden comment'
921 await addVideoCommentThread(server.url, server.accessToken, videoUUID, text, 409)
922 }
923 })
924 })
925
926 describe('With minimum parameters', function () {
927 it('Should upload and propagate the video', async function () {
928 this.timeout(60000)
929
930 const path = '/api/v1/videos/upload'
931
932 const req = request(servers[1].url)
933 .post(path)
934 .set('Accept', 'application/json')
935 .set('Authorization', 'Bearer ' + servers[1].accessToken)
936 .field('name', 'minimum parameters')
937 .field('privacy', '1')
938 .field('channelId', '1')
939
940 const filePath = join(__dirname, '..', '..', 'fixtures', 'video_short.webm')
941
942 await req.attach('videofile', filePath)
943 .expect(200)
944
945 await waitJobs(servers)
946
947 for (const server of servers) {
948 const res = await getVideosList(server.url)
949 const video = res.body.data.find(v => v.name === 'minimum parameters')
950
951 const isLocal = server.url === 'http://localhost:9002'
952 const checkAttributes = {
953 name: 'minimum parameters',
954 category: null,
955 licence: null,
956 language: null,
957 nsfw: false,
958 description: null,
959 support: null,
960 account: {
961 name: 'root',
962 host: 'localhost:9002'
963 },
964 isLocal,
965 duration: 5,
966 commentsEnabled: false,
967 tags: [ ],
968 privacy: VideoPrivacy.PUBLIC,
969 channel: {
970 name: 'Default root channel',
971 description: '',
972 isLocal
973 },
974 fixture: 'video_short.webm',
975 files: [
976 {
977 resolution: 720,
978 size: 36000
979 },
980 {
981 resolution: 480,
982 size: 21000
983 },
984 {
985 resolution: 360,
986 size: 17000
987 },
988 {
989 resolution: 240,
990 size: 13000
991 }
992 ]
993 }
994 await completeVideoCheck(server.url, video, checkAttributes)
995 }
996 })
997 })
998
999 after(async function () {
1000 killallServers(servers)
1001
1002 // Keep the logs if the test failed
1003 if (this['ok']) {
1004 await flushTests()
1005 }
1006 })
1007 })