1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
8 flushAndRunMultipleServers,
15 setAccessTokensToServers,
17 } from '../../../../shared/extra-utils'
18 import { areHttpImportTestsDisabled, testImage } from '../../../../shared/extra-utils/miscs/miscs'
19 import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
23 getYoutubeHDRVideoUrl,
26 } from '../../../../shared/extra-utils/videos/video-imports'
27 import { VideoDetails, VideoImport, VideoPrivacy, VideoResolution } from '../../../../shared/models/videos'
29 const expect = chai.expect
31 describe('Test video imports', function () {
32 let servers: ServerInfo[] = []
33 let channelIdServer1: number
34 let channelIdServer2: number
36 if (areHttpImportTestsDisabled()) return
38 async function checkVideosServer1 (server: ServerInfo, idHttp: string, idMagnet: string, idTorrent: string) {
39 const resHttp = await getVideo(server.url, idHttp)
40 const videoHttp: VideoDetails = resHttp.body
42 expect(videoHttp.name).to.equal('small video - youtube')
43 // FIXME: youtube-dl seems broken
44 // expect(videoHttp.category.label).to.equal('News & Politics')
45 // expect(videoHttp.licence.label).to.equal('Attribution')
46 expect(videoHttp.language.label).to.equal('Unknown')
47 expect(videoHttp.nsfw).to.be.false
48 expect(videoHttp.description).to.equal('this is a super description')
49 expect(videoHttp.tags).to.deep.equal([ 'tag1', 'tag2' ])
50 expect(videoHttp.files).to.have.lengthOf(1)
52 const originallyPublishedAt = new Date(videoHttp.originallyPublishedAt)
53 expect(originallyPublishedAt.getDate()).to.equal(14)
54 expect(originallyPublishedAt.getMonth()).to.equal(0)
55 expect(originallyPublishedAt.getFullYear()).to.equal(2019)
57 const resMagnet = await getVideo(server.url, idMagnet)
58 const videoMagnet: VideoDetails = resMagnet.body
59 const resTorrent = await getVideo(server.url, idTorrent)
60 const videoTorrent: VideoDetails = resTorrent.body
62 for (const video of [ videoMagnet, videoTorrent ]) {
63 expect(video.category.label).to.equal('Misc')
64 expect(video.licence.label).to.equal('Unknown')
65 expect(video.language.label).to.equal('Unknown')
66 expect(video.nsfw).to.be.false
67 expect(video.description).to.equal('this is a super torrent description')
68 expect(video.tags).to.deep.equal([ 'tag_torrent1', 'tag_torrent2' ])
69 expect(video.files).to.have.lengthOf(1)
72 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4')
73 expect(videoMagnet.name).to.contain('super peertube2 video')
75 const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: idHttp })
76 expect(bodyCaptions.total).to.equal(2)
79 async function checkVideoServer2 (server: ServerInfo, id: number | string) {
80 const res = await getVideo(server.url, id)
81 const video: VideoDetails = res.body
83 expect(video.name).to.equal('my super name')
84 expect(video.category.label).to.equal('Entertainment')
85 expect(video.licence.label).to.equal('Public Domain Dedication')
86 expect(video.language.label).to.equal('English')
87 expect(video.nsfw).to.be.false
88 expect(video.description).to.equal('my super description')
89 expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
91 expect(video.files).to.have.lengthOf(1)
93 const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: id })
94 expect(bodyCaptions.total).to.equal(2)
97 before(async function () {
101 servers = await flushAndRunMultipleServers(2)
103 await setAccessTokensToServers(servers)
106 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
107 channelIdServer1 = res.body.videoChannels[0].id
111 const res = await getMyUserInformation(servers[1].url, servers[1].accessToken)
112 channelIdServer2 = res.body.videoChannels[0].id
115 await doubleFollow(servers[0], servers[1])
118 it('Should import videos on server 1', async function () {
121 const baseAttributes = {
122 channelId: channelIdServer1,
123 privacy: VideoPrivacy.PUBLIC
127 const attributes = immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() })
128 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
129 expect(res.body.video.name).to.equal('small video - youtube')
131 expect(res.body.video.thumbnailPath).to.match(new RegExp(`^/static/thumbnails/.+.jpg$`))
132 expect(res.body.video.previewPath).to.match(new RegExp(`^/lazy-static/previews/.+.jpg$`))
134 await testImage(servers[0].url, 'video_import_thumbnail', res.body.video.thumbnailPath)
135 await testImage(servers[0].url, 'video_import_preview', res.body.video.previewPath)
137 const bodyCaptions = await servers[0].captionsCommand.listVideoCaptions({ videoId: res.body.video.id })
138 const videoCaptions = bodyCaptions.data
139 expect(videoCaptions).to.have.lengthOf(2)
141 const enCaption = videoCaptions.find(caption => caption.language.id === 'en')
142 expect(enCaption).to.exist
143 expect(enCaption.language.label).to.equal('English')
144 expect(enCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-en.vtt$`))
145 await testCaptionFile(servers[0].url, enCaption.captionPath, `WEBVTT
149 00:00:01.600 --> 00:00:04.200
152 00:00:05.900 --> 00:00:07.999
153 This is a subtitle in American English
155 00:00:10.000 --> 00:00:14.000
156 Adding subtitles is very easy to do`)
158 const frCaption = videoCaptions.find(caption => caption.language.id === 'fr')
159 expect(frCaption).to.exist
160 expect(frCaption.language.label).to.equal('French')
161 expect(frCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-fr.vtt`))
162 await testCaptionFile(servers[0].url, frCaption.captionPath, `WEBVTT
166 00:00:01.600 --> 00:00:04.200
169 00:00:05.900 --> 00:00:07.999
170 C'est un sous-titre français
172 00:00:10.000 --> 00:00:14.000
173 Ajouter un sous-titre est vraiment facile`)
177 const attributes = immutableAssign(baseAttributes, {
178 magnetUri: getMagnetURI(),
179 description: 'this is a super torrent description',
180 tags: [ 'tag_torrent1', 'tag_torrent2' ]
182 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
183 expect(res.body.video.name).to.equal('super peertube2 video')
187 const attributes = immutableAssign(baseAttributes, {
188 torrentfile: 'video-720p.torrent' as any,
189 description: 'this is a super torrent description',
190 tags: [ 'tag_torrent1', 'tag_torrent2' ]
192 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
193 expect(res.body.video.name).to.equal('你好 世界 720p.mp4')
197 it('Should list the videos to import in my videos on server 1', async function () {
198 const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5, 'createdAt')
200 expect(res.body.total).to.equal(3)
202 const videos = res.body.data
203 expect(videos).to.have.lengthOf(3)
204 expect(videos[0].name).to.equal('small video - youtube')
205 expect(videos[1].name).to.equal('super peertube2 video')
206 expect(videos[2].name).to.equal('你好 世界 720p.mp4')
209 it('Should list the videos to import in my imports on server 1', async function () {
210 const res = await getMyVideoImports(servers[0].url, servers[0].accessToken, '-createdAt')
212 expect(res.body.total).to.equal(3)
213 const videoImports: VideoImport[] = res.body.data
214 expect(videoImports).to.have.lengthOf(3)
216 expect(videoImports[2].targetUrl).to.equal(getYoutubeVideoUrl())
217 expect(videoImports[2].magnetUri).to.be.null
218 expect(videoImports[2].torrentName).to.be.null
219 expect(videoImports[2].video.name).to.equal('small video - youtube')
221 expect(videoImports[1].targetUrl).to.be.null
222 expect(videoImports[1].magnetUri).to.equal(getMagnetURI())
223 expect(videoImports[1].torrentName).to.be.null
224 expect(videoImports[1].video.name).to.equal('super peertube2 video')
226 expect(videoImports[0].targetUrl).to.be.null
227 expect(videoImports[0].magnetUri).to.be.null
228 expect(videoImports[0].torrentName).to.equal('video-720p.torrent')
229 expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4')
232 it('Should have the video listed on the two instances', async function () {
233 this.timeout(120_000)
235 await waitJobs(servers)
237 for (const server of servers) {
238 const res = await getVideosList(server.url)
239 expect(res.body.total).to.equal(3)
240 expect(res.body.data).to.have.lengthOf(3)
242 const [ videoHttp, videoMagnet, videoTorrent ] = res.body.data
243 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
247 it('Should import a video on server 2 with some fields', async function () {
251 targetUrl: getYoutubeVideoUrl(),
252 channelId: channelIdServer2,
253 privacy: VideoPrivacy.PUBLIC,
257 name: 'my super name',
258 description: 'my super description',
259 tags: [ 'supertag1', 'supertag2' ]
261 const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
262 expect(res.body.video.name).to.equal('my super name')
265 it('Should have the videos listed on the two instances', async function () {
266 this.timeout(120_000)
268 await waitJobs(servers)
270 for (const server of servers) {
271 const res = await getVideosList(server.url)
272 expect(res.body.total).to.equal(4)
273 expect(res.body.data).to.have.lengthOf(4)
275 await checkVideoServer2(server, res.body.data[0].uuid)
277 const [ , videoHttp, videoMagnet, videoTorrent ] = res.body.data
278 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
282 it('Should import a video that will be transcoded', async function () {
283 this.timeout(120_000)
286 name: 'transcoded video',
287 magnetUri: getMagnetURI(),
288 channelId: channelIdServer2,
289 privacy: VideoPrivacy.PUBLIC
291 const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
292 const videoUUID = res.body.video.uuid
294 await waitJobs(servers)
296 for (const server of servers) {
297 const res = await getVideo(server.url, videoUUID)
298 const video: VideoDetails = res.body
300 expect(video.name).to.equal('transcoded video')
301 expect(video.files).to.have.lengthOf(4)
305 it('Should import no HDR version on a HDR video', async function () {
306 this.timeout(120_000)
316 '1080p': true, // the resulting resolution shouldn't be higher than this, and not vp9.2/av01
320 webtorrent: { enabled: true },
321 hls: { enabled: false }
334 await servers[0].configCommand.updateCustomSubConfig({ newConfig: config })
338 targetUrl: getYoutubeHDRVideoUrl(),
339 channelId: channelIdServer1,
340 privacy: VideoPrivacy.PUBLIC
342 const res1 = await importVideo(servers[0].url, servers[0].accessToken, attributes)
343 const videoUUID = res1.body.video.uuid
345 await waitJobs(servers)
348 const res2 = await getVideo(servers[0].url, videoUUID)
349 const video: VideoDetails = res2.body
350 expect(video.name).to.equal('hdr video')
351 const maxResolution = Math.max.apply(Math, video.files.map(function (o) { return o.resolution.id }))
352 expect(maxResolution, 'expected max resolution not met').to.equals(VideoResolution.H_1080P)
355 after(async function () {
356 await cleanupTests(servers)