1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import * as request from 'supertest'
7 buildAbsoluteFixturePath,
9 checkVideoFilesWereRemoved,
12 createMultipleServers,
16 setAccessTokensToServers,
21 } from '@shared/extra-utils'
22 import { HttpStatusCode, VideoCommentThreadTree, VideoPrivacy } from '@shared/models'
24 const expect = chai.expect
26 describe('Test multiple servers', function () {
27 let servers: PeerTubeServer[] = []
30 let videoChannelId: number
32 before(async function () {
35 servers = await createMultipleServers(3)
37 // Get the access tokens
38 await setAccessTokensToServers(servers)
41 const videoChannel = {
42 name: 'super_channel_name',
43 displayName: 'my channel',
44 description: 'super channel'
46 await servers[0].channels.create({ attributes: videoChannel })
47 const { data } = await servers[0].channels.list({ start: 0, count: 1 })
48 videoChannelId = data[0].id
51 // Server 1 and server 2 follow each other
52 await doubleFollow(servers[0], servers[1])
53 // Server 1 and server 3 follow each other
54 await doubleFollow(servers[0], servers[2])
55 // Server 2 and server 3 follow each other
56 await doubleFollow(servers[1], servers[2])
59 it('Should not have videos for all servers', async function () {
60 for (const server of servers) {
61 const { data } = await server.videos.list()
62 expect(data).to.be.an('array')
63 expect(data.length).to.equal(0)
67 describe('Should upload the video and propagate on each server', function () {
68 it('Should upload the video on server 1 and propagate on each server', async function () {
72 name: 'my super name for server 1',
77 description: 'my super description for server 1',
78 support: 'my super support text for server 1',
79 originallyPublishedAt: '2019-02-10T13:38:14.449Z',
80 tags: [ 'tag1p1', 'tag2p1' ],
81 channelId: videoChannelId,
82 fixture: 'video_short1.webm'
84 await servers[0].videos.upload({ attributes })
86 await waitJobs(servers)
88 // All servers should have this video
89 let publishedAt: string = null
90 for (const server of servers) {
91 const isLocal = server.port === servers[0].port
92 const checkAttributes = {
93 name: 'my super name for server 1',
98 description: 'my super description for server 1',
99 support: 'my super support text for server 1',
100 originallyPublishedAt: '2019-02-10T13:38:14.449Z',
103 host: 'localhost:' + servers[0].port
108 tags: [ 'tag1p1', 'tag2p1' ],
109 privacy: VideoPrivacy.PUBLIC,
110 commentsEnabled: true,
111 downloadEnabled: true,
113 displayName: 'my channel',
114 name: 'super_channel_name',
115 description: 'super channel',
118 fixture: 'video_short1.webm',
127 const { data } = await server.videos.list()
128 expect(data).to.be.an('array')
129 expect(data.length).to.equal(1)
130 const video = data[0]
132 await completeVideoCheck(server, video, checkAttributes)
133 publishedAt = video.publishedAt as string
137 it('Should upload the video on server 2 and propagate on each server', async function () {
142 password: 'super_password'
144 await servers[1].users.create({ username: user.username, password: user.password })
145 const userAccessToken = await servers[1].login.getAccessToken(user)
148 name: 'my super name for server 2',
153 description: 'my super description for server 2',
154 support: 'my super support text for server 2',
155 tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
156 fixture: 'video_short2.webm',
157 thumbnailfile: 'thumbnail.jpg',
158 previewfile: 'preview.jpg'
160 await servers[1].videos.upload({ token: userAccessToken, attributes, mode: 'resumable' })
163 await waitJobs(servers)
165 // All servers should have this video
166 for (const server of servers) {
167 const isLocal = server.url === 'http://localhost:' + servers[1].port
168 const checkAttributes = {
169 name: 'my super name for server 2',
174 description: 'my super description for server 2',
175 support: 'my super support text for server 2',
178 host: 'localhost:' + servers[1].port
181 commentsEnabled: true,
182 downloadEnabled: true,
184 tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
185 privacy: VideoPrivacy.PUBLIC,
187 displayName: 'Main user1 channel',
188 name: 'user1_channel',
189 description: 'super channel',
192 fixture: 'video_short2.webm',
211 thumbnailfile: 'thumbnail',
212 previewfile: 'preview'
215 const { data } = await server.videos.list()
216 expect(data).to.be.an('array')
217 expect(data.length).to.equal(2)
218 const video = data[1]
220 await completeVideoCheck(server, video, checkAttributes)
224 it('Should upload two videos on server 3 and propagate on each server', async function () {
229 name: 'my super name for server 3',
234 description: 'my super description for server 3',
235 support: 'my super support text for server 3',
237 fixture: 'video_short3.webm'
239 await servers[2].videos.upload({ attributes })
244 name: 'my super name for server 3-2',
249 description: 'my super description for server 3-2',
250 support: 'my super support text for server 3-2',
251 tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
252 fixture: 'video_short.webm'
254 await servers[2].videos.upload({ attributes })
257 await waitJobs(servers)
259 // All servers should have this video
260 for (const server of servers) {
261 const isLocal = server.url === 'http://localhost:' + servers[2].port
262 const { data } = await server.videos.list()
264 expect(data).to.be.an('array')
265 expect(data.length).to.equal(4)
267 // We not sure about the order of the two last uploads
270 if (data[2].name === 'my super name for server 3') {
278 const checkAttributesVideo1 = {
279 name: 'my super name for server 3',
284 description: 'my super description for server 3',
285 support: 'my super support text for server 3',
288 host: 'localhost:' + servers[2].port
292 commentsEnabled: true,
293 downloadEnabled: true,
295 privacy: VideoPrivacy.PUBLIC,
297 displayName: 'Main root channel',
298 name: 'root_channel',
302 fixture: 'video_short3.webm',
310 await completeVideoCheck(server, video1, checkAttributesVideo1)
312 const checkAttributesVideo2 = {
313 name: 'my super name for server 3-2',
318 description: 'my super description for server 3-2',
319 support: 'my super support text for server 3-2',
322 host: 'localhost:' + servers[2].port
324 commentsEnabled: true,
325 downloadEnabled: true,
328 tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
329 privacy: VideoPrivacy.PUBLIC,
331 displayName: 'Main root channel',
332 name: 'root_channel',
336 fixture: 'video_short.webm',
344 await completeVideoCheck(server, video2, checkAttributesVideo2)
349 describe('It should list local videos', function () {
350 it('Should list only local videos on server 1', async function () {
351 const { data, total } = await servers[0].videos.list({ filter: 'local' })
353 expect(total).to.equal(1)
354 expect(data).to.be.an('array')
355 expect(data.length).to.equal(1)
356 expect(data[0].name).to.equal('my super name for server 1')
359 it('Should list only local videos on server 2', async function () {
360 const { data, total } = await servers[1].videos.list({ filter: 'local' })
362 expect(total).to.equal(1)
363 expect(data).to.be.an('array')
364 expect(data.length).to.equal(1)
365 expect(data[0].name).to.equal('my super name for server 2')
368 it('Should list only local videos on server 3', async function () {
369 const { data, total } = await servers[2].videos.list({ filter: 'local' })
371 expect(total).to.equal(2)
372 expect(data).to.be.an('array')
373 expect(data.length).to.equal(2)
374 expect(data[0].name).to.equal('my super name for server 3')
375 expect(data[1].name).to.equal('my super name for server 3-2')
379 describe('Should seed the uploaded video', function () {
380 it('Should add the file 1 by asking server 3', async function () {
383 const { data } = await servers[2].videos.list()
385 const video = data[0]
386 toRemove.push(data[2])
387 toRemove.push(data[3])
389 const videoDetails = await servers[2].videos.get({ id: video.id })
390 const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
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('')
396 it('Should add the file 2 by asking server 1', async function () {
399 const { data } = await servers[0].videos.list()
401 const video = data[1]
402 const videoDetails = await servers[0].videos.get({ id: video.id })
404 const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
405 expect(torrent.files).to.be.an('array')
406 expect(torrent.files.length).to.equal(1)
407 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
410 it('Should add the file 3 by asking server 2', async function () {
413 const { data } = await servers[1].videos.list()
415 const video = data[2]
416 const videoDetails = await servers[1].videos.get({ id: video.id })
418 const torrent = await webtorrentAdd(videoDetails.files[0].magnetUri, true)
419 expect(torrent.files).to.be.an('array')
420 expect(torrent.files.length).to.equal(1)
421 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
424 it('Should add the file 3-2 by asking server 1', async function () {
427 const { data } = await servers[0].videos.list()
429 const video = data[3]
430 const videoDetails = await servers[0].videos.get({ id: video.id })
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('')
438 it('Should add the file 2 in 360p by asking server 1', async function () {
441 const { data } = await servers[0].videos.list()
443 const video = data.find(v => v.name === 'my super name for server 2')
444 const videoDetails = await servers[0].videos.get({ id: video.id })
446 const file = videoDetails.files.find(f => f.resolution.id === 360)
447 expect(file).not.to.be.undefined
449 const torrent = await webtorrentAdd(file.magnetUri)
450 expect(torrent.files).to.be.an('array')
451 expect(torrent.files.length).to.equal(1)
452 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
456 describe('Should update video views, likes and dislikes', function () {
457 let localVideosServer3 = []
458 let remoteVideosServer1 = []
459 let remoteVideosServer2 = []
460 let remoteVideosServer3 = []
462 before(async function () {
464 const { data } = await servers[0].videos.list()
465 remoteVideosServer1 = data.filter(video => video.isLocal === false).map(video => video.uuid)
469 const { data } = await servers[1].videos.list()
470 remoteVideosServer2 = data.filter(video => video.isLocal === false).map(video => video.uuid)
474 const { data } = await servers[2].videos.list()
475 localVideosServer3 = data.filter(video => video.isLocal === true).map(video => video.uuid)
476 remoteVideosServer3 = data.filter(video => video.isLocal === false).map(video => video.uuid)
480 it('Should view multiple videos on owned servers', async function () {
483 await servers[2].videos.view({ id: localVideosServer3[0] })
486 await servers[2].videos.view({ id: localVideosServer3[0] })
487 await servers[2].videos.view({ id: localVideosServer3[1] })
491 await servers[2].videos.view({ id: localVideosServer3[0] })
492 await servers[2].videos.view({ id: localVideosServer3[0] })
494 await waitJobs(servers)
496 // Wait the repeatable job
499 await waitJobs(servers)
501 for (const server of servers) {
502 const { data } = await server.videos.list()
504 const video0 = data.find(v => v.uuid === localVideosServer3[0])
505 const video1 = data.find(v => v.uuid === localVideosServer3[1])
507 expect(video0.views).to.equal(3)
508 expect(video1.views).to.equal(1)
512 it('Should view multiple videos on each servers', async function () {
515 const tasks: Promise<any>[] = []
516 tasks.push(servers[0].videos.view({ id: remoteVideosServer1[0] }))
517 tasks.push(servers[1].videos.view({ id: remoteVideosServer2[0] }))
518 tasks.push(servers[1].videos.view({ id: remoteVideosServer2[0] }))
519 tasks.push(servers[2].videos.view({ id: remoteVideosServer3[0] }))
520 tasks.push(servers[2].videos.view({ id: remoteVideosServer3[1] }))
521 tasks.push(servers[2].videos.view({ id: remoteVideosServer3[1] }))
522 tasks.push(servers[2].videos.view({ id: remoteVideosServer3[1] }))
523 tasks.push(servers[2].videos.view({ id: localVideosServer3[1] }))
524 tasks.push(servers[2].videos.view({ id: localVideosServer3[1] }))
525 tasks.push(servers[2].videos.view({ id: localVideosServer3[1] }))
527 await Promise.all(tasks)
529 await waitJobs(servers)
531 // Wait the repeatable job
534 await waitJobs(servers)
536 let baseVideos = null
538 for (const server of servers) {
539 const { data } = await server.videos.list()
541 // Initialize base videos for future comparisons
542 if (baseVideos === null) {
547 for (const baseVideo of baseVideos) {
548 const sameVideo = data.find(video => video.name === baseVideo.name)
549 expect(baseVideo.views).to.equal(sameVideo.views)
554 it('Should like and dislikes videos on different services', async function () {
557 await servers[0].videos.rate({ id: remoteVideosServer1[0], rating: 'like' })
559 await servers[0].videos.rate({ id: remoteVideosServer1[0], rating: 'dislike' })
561 await servers[0].videos.rate({ id: remoteVideosServer1[0], rating: 'like' })
562 await servers[2].videos.rate({ id: localVideosServer3[1], rating: 'like' })
564 await servers[2].videos.rate({ id: localVideosServer3[1], rating: 'dislike' })
565 await servers[2].videos.rate({ id: remoteVideosServer3[1], rating: 'dislike' })
567 await servers[2].videos.rate({ id: remoteVideosServer3[0], rating: 'like' })
569 await waitJobs(servers)
571 await waitJobs(servers)
573 let baseVideos = null
574 for (const server of servers) {
575 const { data } = await server.videos.list()
577 // Initialize base videos for future comparisons
578 if (baseVideos === null) {
583 for (const baseVideo of baseVideos) {
584 const sameVideo = data.find(video => video.name === baseVideo.name)
585 expect(baseVideo.likes).to.equal(sameVideo.likes)
586 expect(baseVideo.dislikes).to.equal(sameVideo.dislikes)
592 describe('Should manipulate these videos', function () {
593 it('Should update the video 3 by asking server 3', async function () {
597 name: 'my super video updated',
602 description: 'my super description updated',
603 support: 'my super support text updated',
604 tags: [ 'tag_up_1', 'tag_up_2' ],
605 thumbnailfile: 'thumbnail.jpg',
606 originallyPublishedAt: '2019-02-11T13:38:14.449Z',
607 previewfile: 'preview.jpg'
610 await servers[2].videos.update({ id: toRemove[0].id, attributes })
612 await waitJobs(servers)
615 it('Should have the video 3 updated on each server', async function () {
618 for (const server of servers) {
619 const { data } = await server.videos.list()
621 const videoUpdated = data.find(video => video.name === 'my super video updated')
622 expect(!!videoUpdated).to.be.true
624 const isLocal = server.url === 'http://localhost:' + servers[2].port
625 const checkAttributes = {
626 name: 'my super video updated',
631 description: 'my super description updated',
632 support: 'my super support text updated',
633 originallyPublishedAt: '2019-02-11T13:38:14.449Z',
636 host: 'localhost:' + servers[2].port
640 commentsEnabled: true,
641 downloadEnabled: true,
642 tags: [ 'tag_up_1', 'tag_up_2' ],
643 privacy: VideoPrivacy.PUBLIC,
645 displayName: 'Main root channel',
646 name: 'root_channel',
650 fixture: 'video_short3.webm',
657 thumbnailfile: 'thumbnail',
658 previewfile: 'preview'
660 await completeVideoCheck(server, videoUpdated, checkAttributes)
664 it('Should remove the videos 3 and 3-2 by asking server 3', async function () {
667 await servers[2].videos.remove({ id: toRemove[0].id })
668 await servers[2].videos.remove({ id: toRemove[1].id })
670 await waitJobs(servers)
673 it('Should not have files of videos 3 and 3-2 on each server', async function () {
674 for (const server of servers) {
675 await checkVideoFilesWereRemoved(toRemove[0].uuid, server)
676 await checkVideoFilesWereRemoved(toRemove[1].uuid, server)
680 it('Should have videos 1 and 3 on each server', async function () {
681 for (const server of servers) {
682 const { data } = await server.videos.list()
684 expect(data).to.be.an('array')
685 expect(data.length).to.equal(2)
686 expect(data[0].name).not.to.equal(data[1].name)
687 expect(data[0].name).not.to.equal(toRemove[0].name)
688 expect(data[1].name).not.to.equal(toRemove[0].name)
689 expect(data[0].name).not.to.equal(toRemove[1].name)
690 expect(data[1].name).not.to.equal(toRemove[1].name)
692 videoUUID = data.find(video => video.name === 'my super name for server 1').uuid
696 it('Should get the same video by UUID on each server', async function () {
698 for (const server of servers) {
699 const video = await server.videos.get({ id: videoUUID })
701 if (baseVideo === null) {
706 expect(baseVideo.name).to.equal(video.name)
707 expect(baseVideo.uuid).to.equal(video.uuid)
708 expect(baseVideo.category.id).to.equal(video.category.id)
709 expect(baseVideo.language.id).to.equal(video.language.id)
710 expect(baseVideo.licence.id).to.equal(video.licence.id)
711 expect(baseVideo.nsfw).to.equal(video.nsfw)
712 expect(baseVideo.account.name).to.equal(video.account.name)
713 expect(baseVideo.account.displayName).to.equal(video.account.displayName)
714 expect(baseVideo.account.url).to.equal(video.account.url)
715 expect(baseVideo.account.host).to.equal(video.account.host)
716 expect(baseVideo.tags).to.deep.equal(video.tags)
720 it('Should get the preview from each server', async function () {
721 for (const server of servers) {
722 const video = await server.videos.get({ id: videoUUID })
724 await testImage(server.url, 'video_short1-preview.webm', video.previewPath)
729 describe('Should comment these videos', function () {
730 let childOfFirstChild: VideoCommentThreadTree
732 it('Should add comment (threads and replies)', async function () {
736 const text = 'my super first comment'
737 await servers[0].comments.createThread({ videoId: videoUUID, text })
741 const text = 'my super second comment'
742 await servers[2].comments.createThread({ videoId: videoUUID, text })
745 await waitJobs(servers)
748 const threadId = await servers[1].comments.findCommentId({ videoId: videoUUID, text: 'my super first comment' })
750 const text = 'my super answer to thread 1'
751 await servers[1].comments.addReply({ videoId: videoUUID, toCommentId: threadId, text })
754 await waitJobs(servers)
757 const threadId = await servers[2].comments.findCommentId({ videoId: videoUUID, text: 'my super first comment' })
759 const body = await servers[2].comments.getThread({ videoId: videoUUID, threadId })
760 const childCommentId = body.children[0].comment.id
762 const text3 = 'my second answer to thread 1'
763 await servers[2].comments.addReply({ videoId: videoUUID, toCommentId: threadId, text: text3 })
765 const text2 = 'my super answer to answer of thread 1'
766 await servers[2].comments.addReply({ videoId: videoUUID, toCommentId: childCommentId, text: text2 })
769 await waitJobs(servers)
772 it('Should have these threads', async function () {
773 for (const server of servers) {
774 const body = await server.comments.listThreads({ videoId: videoUUID })
776 expect(body.total).to.equal(2)
777 expect(body.data).to.be.an('array')
778 expect(body.data).to.have.lengthOf(2)
781 const comment = body.data.find(c => c.text === 'my super first comment')
782 expect(comment).to.not.be.undefined
783 expect(comment.inReplyToCommentId).to.be.null
784 expect(comment.account.name).to.equal('root')
785 expect(comment.account.host).to.equal('localhost:' + servers[0].port)
786 expect(comment.totalReplies).to.equal(3)
787 expect(dateIsValid(comment.createdAt as string)).to.be.true
788 expect(dateIsValid(comment.updatedAt as string)).to.be.true
792 const comment = body.data.find(c => c.text === 'my super second comment')
793 expect(comment).to.not.be.undefined
794 expect(comment.inReplyToCommentId).to.be.null
795 expect(comment.account.name).to.equal('root')
796 expect(comment.account.host).to.equal('localhost:' + servers[2].port)
797 expect(comment.totalReplies).to.equal(0)
798 expect(dateIsValid(comment.createdAt as string)).to.be.true
799 expect(dateIsValid(comment.updatedAt as string)).to.be.true
804 it('Should have these comments', async function () {
805 for (const server of servers) {
806 const body = await server.comments.listThreads({ videoId: videoUUID })
807 const threadId = body.data.find(c => c.text === 'my super first comment').id
809 const tree = await server.comments.getThread({ videoId: videoUUID, threadId })
811 expect(tree.comment.text).equal('my super first comment')
812 expect(tree.comment.account.name).equal('root')
813 expect(tree.comment.account.host).equal('localhost:' + servers[0].port)
814 expect(tree.children).to.have.lengthOf(2)
816 const firstChild = tree.children[0]
817 expect(firstChild.comment.text).to.equal('my super answer to thread 1')
818 expect(firstChild.comment.account.name).equal('root')
819 expect(firstChild.comment.account.host).equal('localhost:' + servers[1].port)
820 expect(firstChild.children).to.have.lengthOf(1)
822 childOfFirstChild = firstChild.children[0]
823 expect(childOfFirstChild.comment.text).to.equal('my super answer to answer of thread 1')
824 expect(childOfFirstChild.comment.account.name).equal('root')
825 expect(childOfFirstChild.comment.account.host).equal('localhost:' + servers[2].port)
826 expect(childOfFirstChild.children).to.have.lengthOf(0)
828 const secondChild = tree.children[1]
829 expect(secondChild.comment.text).to.equal('my second answer to thread 1')
830 expect(secondChild.comment.account.name).equal('root')
831 expect(secondChild.comment.account.host).equal('localhost:' + servers[2].port)
832 expect(secondChild.children).to.have.lengthOf(0)
836 it('Should delete a reply', async function () {
839 await servers[2].comments.delete({ videoId: videoUUID, commentId: childOfFirstChild.comment.id })
841 await waitJobs(servers)
844 it('Should have this comment marked as deleted', async function () {
845 for (const server of servers) {
846 const { data } = await server.comments.listThreads({ videoId: videoUUID })
847 const threadId = data.find(c => c.text === 'my super first comment').id
849 const tree = await server.comments.getThread({ videoId: videoUUID, threadId })
850 expect(tree.comment.text).equal('my super first comment')
852 const firstChild = tree.children[0]
853 expect(firstChild.comment.text).to.equal('my super answer to thread 1')
854 expect(firstChild.children).to.have.lengthOf(1)
856 const deletedComment = firstChild.children[0].comment
857 expect(deletedComment.isDeleted).to.be.true
858 expect(deletedComment.deletedAt).to.not.be.null
859 expect(deletedComment.account).to.be.null
860 expect(deletedComment.text).to.equal('')
862 const secondChild = tree.children[1]
863 expect(secondChild.comment.text).to.equal('my second answer to thread 1')
867 it('Should delete the thread comments', async function () {
870 const { data } = await servers[0].comments.listThreads({ videoId: videoUUID })
871 const commentId = data.find(c => c.text === 'my super first comment').id
872 await servers[0].comments.delete({ videoId: videoUUID, commentId })
874 await waitJobs(servers)
877 it('Should have the threads marked as deleted on other servers too', async function () {
878 for (const server of servers) {
879 const body = await server.comments.listThreads({ videoId: videoUUID })
881 expect(body.total).to.equal(2)
882 expect(body.data).to.be.an('array')
883 expect(body.data).to.have.lengthOf(2)
886 const comment = body.data[0]
887 expect(comment).to.not.be.undefined
888 expect(comment.inReplyToCommentId).to.be.null
889 expect(comment.account.name).to.equal('root')
890 expect(comment.account.host).to.equal('localhost:' + servers[2].port)
891 expect(comment.totalReplies).to.equal(0)
892 expect(dateIsValid(comment.createdAt as string)).to.be.true
893 expect(dateIsValid(comment.updatedAt as string)).to.be.true
897 const deletedComment = body.data[1]
898 expect(deletedComment).to.not.be.undefined
899 expect(deletedComment.isDeleted).to.be.true
900 expect(deletedComment.deletedAt).to.not.be.null
901 expect(deletedComment.text).to.equal('')
902 expect(deletedComment.inReplyToCommentId).to.be.null
903 expect(deletedComment.account).to.be.null
904 expect(deletedComment.totalReplies).to.equal(2)
905 expect(dateIsValid(deletedComment.createdAt as string)).to.be.true
906 expect(dateIsValid(deletedComment.updatedAt as string)).to.be.true
907 expect(dateIsValid(deletedComment.deletedAt as string)).to.be.true
912 it('Should delete a remote thread by the origin server', async function () {
915 const { data } = await servers[0].comments.listThreads({ videoId: videoUUID })
916 const commentId = data.find(c => c.text === 'my super second comment').id
917 await servers[0].comments.delete({ videoId: videoUUID, commentId })
919 await waitJobs(servers)
922 it('Should have the threads marked as deleted on other servers too', async function () {
923 for (const server of servers) {
924 const body = await server.comments.listThreads({ videoId: videoUUID })
926 expect(body.total).to.equal(2)
927 expect(body.data).to.have.lengthOf(2)
930 const comment = body.data[0]
931 expect(comment.text).to.equal('')
932 expect(comment.isDeleted).to.be.true
933 expect(comment.createdAt).to.not.be.null
934 expect(comment.deletedAt).to.not.be.null
935 expect(comment.account).to.be.null
936 expect(comment.totalReplies).to.equal(0)
940 const comment = body.data[1]
941 expect(comment.text).to.equal('')
942 expect(comment.isDeleted).to.be.true
943 expect(comment.createdAt).to.not.be.null
944 expect(comment.deletedAt).to.not.be.null
945 expect(comment.account).to.be.null
946 expect(comment.totalReplies).to.equal(2)
951 it('Should disable comments and download', async function () {
955 commentsEnabled: false,
956 downloadEnabled: false
959 await servers[0].videos.update({ id: videoUUID, attributes })
961 await waitJobs(servers)
963 for (const server of servers) {
964 const video = await server.videos.get({ id: videoUUID })
965 expect(video.commentsEnabled).to.be.false
966 expect(video.downloadEnabled).to.be.false
968 const text = 'my super forbidden comment'
969 await server.comments.createThread({ videoId: videoUUID, text, expectedStatus: HttpStatusCode.CONFLICT_409 })
974 describe('With minimum parameters', function () {
975 it('Should upload and propagate the video', async function () {
978 const path = '/api/v1/videos/upload'
980 const req = request(servers[1].url)
982 .set('Accept', 'application/json')
983 .set('Authorization', 'Bearer ' + servers[1].accessToken)
984 .field('name', 'minimum parameters')
985 .field('privacy', '1')
986 .field('channelId', '1')
988 await req.attach('videofile', buildAbsoluteFixturePath('video_short.webm'))
989 .expect(HttpStatusCode.OK_200)
991 await waitJobs(servers)
993 for (const server of servers) {
994 const { data } = await server.videos.list()
995 const video = data.find(v => v.name === 'minimum parameters')
997 const isLocal = server.url === 'http://localhost:' + servers[1].port
998 const checkAttributes = {
999 name: 'minimum parameters',
1008 host: 'localhost:' + servers[1].port
1012 commentsEnabled: true,
1013 downloadEnabled: true,
1015 privacy: VideoPrivacy.PUBLIC,
1017 displayName: 'Main root channel',
1018 name: 'root_channel',
1022 fixture: 'video_short.webm',
1042 await completeVideoCheck(server, video, checkAttributes)
1047 describe('TMP directory', function () {
1048 it('Should have an empty tmp directory', async function () {
1049 for (const server of servers) {
1050 await checkTmpIsEmpty(server)
1055 after(async function () {
1056 await cleanupTests(servers)