]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/videos/video-imports.ts
Adapt CLI to new commands
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-imports.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
590fb506 2
590fb506 3import 'mocha'
b488ba1e 4import * as chai from 'chai'
590fb506 5import {
6910f20f 6 areHttpImportTestsDisabled,
7c3b7976 7 cleanupTests,
590fb506
C
8 doubleFollow,
9 flushAndRunMultipleServers,
10 getMyUserInformation,
11 getMyVideos,
12 getVideo,
13 getVideosList,
6910f20f 14 ImportsCommand,
590fb506 15 ServerInfo,
b488ba1e 16 setAccessTokensToServers,
6910f20f
C
17 testCaptionFile,
18 testImage,
19 waitJobs
20} from '@shared/extra-utils'
21import { VideoDetails, VideoPrivacy, VideoResolution } from '@shared/models'
590fb506
C
22
23const expect = chai.expect
24
25describe('Test video imports', function () {
26 let servers: ServerInfo[] = []
27 let channelIdServer1: number
28 let channelIdServer2: number
29
b488ba1e
C
30 if (areHttpImportTestsDisabled()) return
31
a2470c9f
C
32 async function checkVideosServer1 (server: ServerInfo, idHttp: string, idMagnet: string, idTorrent: string) {
33 const resHttp = await getVideo(server.url, idHttp)
3e17515e
C
34 const videoHttp: VideoDetails = resHttp.body
35
36 expect(videoHttp.name).to.equal('small video - youtube')
f9b6d51f
C
37 // FIXME: youtube-dl seems broken
38 // expect(videoHttp.category.label).to.equal('News & Politics')
1dee8d68 39 // expect(videoHttp.licence.label).to.equal('Attribution')
3e17515e
C
40 expect(videoHttp.language.label).to.equal('Unknown')
41 expect(videoHttp.nsfw).to.be.false
42 expect(videoHttp.description).to.equal('this is a super description')
43 expect(videoHttp.tags).to.deep.equal([ 'tag1', 'tag2' ])
44 expect(videoHttp.files).to.have.lengthOf(1)
17036be5
C
45
46 const originallyPublishedAt = new Date(videoHttp.originallyPublishedAt)
47 expect(originallyPublishedAt.getDate()).to.equal(14)
48 expect(originallyPublishedAt.getMonth()).to.equal(0)
49 expect(originallyPublishedAt.getFullYear()).to.equal(2019)
3e17515e 50
a2470c9f 51 const resMagnet = await getVideo(server.url, idMagnet)
3e17515e 52 const videoMagnet: VideoDetails = resMagnet.body
a2470c9f 53 const resTorrent = await getVideo(server.url, idTorrent)
3e17515e
C
54 const videoTorrent: VideoDetails = resTorrent.body
55
56 for (const video of [ videoMagnet, videoTorrent ]) {
57 expect(video.category.label).to.equal('Misc')
58 expect(video.licence.label).to.equal('Unknown')
59 expect(video.language.label).to.equal('Unknown')
60 expect(video.nsfw).to.be.false
61 expect(video.description).to.equal('this is a super torrent description')
62 expect(video.tags).to.deep.equal([ 'tag_torrent1', 'tag_torrent2' ])
63 expect(video.files).to.have.lengthOf(1)
64 }
590fb506 65
3e17515e
C
66 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4')
67 expect(videoMagnet.name).to.contain('super peertube2 video')
652c6416 68
a2470c9f
C
69 const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: idHttp })
70 expect(bodyCaptions.total).to.equal(2)
590fb506
C
71 }
72
a2470c9f
C
73 async function checkVideoServer2 (server: ServerInfo, id: number | string) {
74 const res = await getVideo(server.url, id)
652c6416 75 const video: VideoDetails = res.body
590fb506
C
76
77 expect(video.name).to.equal('my super name')
78 expect(video.category.label).to.equal('Entertainment')
79 expect(video.licence.label).to.equal('Public Domain Dedication')
80 expect(video.language.label).to.equal('English')
81 expect(video.nsfw).to.be.false
82 expect(video.description).to.equal('my super description')
83 expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
84
85 expect(video.files).to.have.lengthOf(1)
652c6416 86
a2470c9f
C
87 const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: id })
88 expect(bodyCaptions.total).to.equal(2)
590fb506
C
89 }
90
91 before(async function () {
454c20fa 92 this.timeout(30_000)
590fb506
C
93
94 // Run servers
95 servers = await flushAndRunMultipleServers(2)
96
97 await setAccessTokensToServers(servers)
98
99 {
100 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
a1587156 101 channelIdServer1 = res.body.videoChannels[0].id
590fb506
C
102 }
103
104 {
105 const res = await getMyUserInformation(servers[1].url, servers[1].accessToken)
a1587156 106 channelIdServer2 = res.body.videoChannels[0].id
590fb506
C
107 }
108
109 await doubleFollow(servers[0], servers[1])
110 })
111
3e17515e 112 it('Should import videos on server 1', async function () {
454c20fa 113 this.timeout(60_000)
590fb506 114
3e17515e 115 const baseAttributes = {
590fb506
C
116 channelId: channelIdServer1,
117 privacy: VideoPrivacy.PUBLIC
118 }
3e17515e
C
119
120 {
6c5065a0 121 const attributes = { ...baseAttributes, targetUrl: ImportsCommand.getYoutubeVideoUrl() }
6910f20f
C
122 const { video } = await servers[0].importsCommand.importVideo({ attributes })
123 expect(video.name).to.equal('small video - youtube')
53c06121 124
6910f20f
C
125 expect(video.thumbnailPath).to.match(new RegExp(`^/static/thumbnails/.+.jpg$`))
126 expect(video.previewPath).to.match(new RegExp(`^/lazy-static/previews/.+.jpg$`))
53c06121 127
6910f20f
C
128 await testImage(servers[0].url, 'video_import_thumbnail', video.thumbnailPath)
129 await testImage(servers[0].url, 'video_import_preview', video.previewPath)
ba6e9e8f 130
6910f20f 131 const bodyCaptions = await servers[0].captionsCommand.listVideoCaptions({ videoId: video.id })
a2470c9f 132 const videoCaptions = bodyCaptions.data
ba6e9e8f 133 expect(videoCaptions).to.have.lengthOf(2)
134
652c6416
C
135 const enCaption = videoCaptions.find(caption => caption.language.id === 'en')
136 expect(enCaption).to.exist
137 expect(enCaption.language.label).to.equal('English')
53c06121 138 expect(enCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-en.vtt$`))
ba6e9e8f 139 await testCaptionFile(servers[0].url, enCaption.captionPath, `WEBVTT
652c6416
C
140Kind: captions
141Language: en
ba6e9e8f 142
652c6416
C
14300:00:01.600 --> 00:00:04.200
144English (US)
ba6e9e8f 145
652c6416
C
14600:00:05.900 --> 00:00:07.999
147This is a subtitle in American English
ba6e9e8f 148
652c6416
C
14900:00:10.000 --> 00:00:14.000
150Adding subtitles is very easy to do`)
ba6e9e8f 151
652c6416
C
152 const frCaption = videoCaptions.find(caption => caption.language.id === 'fr')
153 expect(frCaption).to.exist
154 expect(frCaption.language.label).to.equal('French')
53c06121 155 expect(frCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-fr.vtt`))
ba6e9e8f 156 await testCaptionFile(servers[0].url, frCaption.captionPath, `WEBVTT
652c6416
C
157Kind: captions
158Language: fr
ba6e9e8f 159
652c6416
C
16000:00:01.600 --> 00:00:04.200
161Français (FR)
ba6e9e8f 162
652c6416
C
16300:00:05.900 --> 00:00:07.999
164C'est un sous-titre français
ba6e9e8f 165
652c6416
C
16600:00:10.000 --> 00:00:14.000
167Ajouter un sous-titre est vraiment facile`)
3e17515e
C
168 }
169
170 {
6c5065a0
C
171 const attributes = {
172 ...baseAttributes,
6910f20f 173 magnetUri: ImportsCommand.getMagnetURI(),
3e17515e
C
174 description: 'this is a super torrent description',
175 tags: [ 'tag_torrent1', 'tag_torrent2' ]
6c5065a0 176 }
6910f20f
C
177 const { video } = await servers[0].importsCommand.importVideo({ attributes })
178 expect(video.name).to.equal('super peertube2 video')
3e17515e
C
179 }
180
181 {
6c5065a0
C
182 const attributes = {
183 ...baseAttributes,
9a7fd960 184 torrentfile: 'video-720p.torrent' as any,
3e17515e
C
185 description: 'this is a super torrent description',
186 tags: [ 'tag_torrent1', 'tag_torrent2' ]
6c5065a0 187 }
6910f20f
C
188 const { video } = await servers[0].importsCommand.importVideo({ attributes })
189 expect(video.name).to.equal('你好 世界 720p.mp4')
3e17515e 190 }
590fb506
C
191 })
192
3e17515e
C
193 it('Should list the videos to import in my videos on server 1', async function () {
194 const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5, 'createdAt')
590fb506 195
3e17515e 196 expect(res.body.total).to.equal(3)
590fb506
C
197
198 const videos = res.body.data
3e17515e 199 expect(videos).to.have.lengthOf(3)
590fb506 200 expect(videos[0].name).to.equal('small video - youtube')
3e17515e
C
201 expect(videos[1].name).to.equal('super peertube2 video')
202 expect(videos[2].name).to.equal('你好 世界 720p.mp4')
590fb506
C
203 })
204
3e17515e 205 it('Should list the videos to import in my imports on server 1', async function () {
6910f20f
C
206 const { total, data: videoImports } = await servers[0].importsCommand.getMyVideoImports({ sort: '-createdAt' })
207 expect(total).to.equal(3)
3e17515e 208
3e17515e
C
209 expect(videoImports).to.have.lengthOf(3)
210
6910f20f 211 expect(videoImports[2].targetUrl).to.equal(ImportsCommand.getYoutubeVideoUrl())
3e17515e
C
212 expect(videoImports[2].magnetUri).to.be.null
213 expect(videoImports[2].torrentName).to.be.null
214 expect(videoImports[2].video.name).to.equal('small video - youtube')
590fb506 215
3e17515e 216 expect(videoImports[1].targetUrl).to.be.null
6910f20f 217 expect(videoImports[1].magnetUri).to.equal(ImportsCommand.getMagnetURI())
3e17515e
C
218 expect(videoImports[1].torrentName).to.be.null
219 expect(videoImports[1].video.name).to.equal('super peertube2 video')
590fb506 220
3e17515e
C
221 expect(videoImports[0].targetUrl).to.be.null
222 expect(videoImports[0].magnetUri).to.be.null
223 expect(videoImports[0].torrentName).to.equal('video-720p.torrent')
224 expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4')
590fb506
C
225 })
226
3e17515e 227 it('Should have the video listed on the two instances', async function () {
454c20fa 228 this.timeout(120_000)
590fb506
C
229
230 await waitJobs(servers)
231
232 for (const server of servers) {
233 const res = await getVideosList(server.url)
3e17515e
C
234 expect(res.body.total).to.equal(3)
235 expect(res.body.data).to.have.lengthOf(3)
590fb506 236
3e17515e 237 const [ videoHttp, videoMagnet, videoTorrent ] = res.body.data
a2470c9f 238 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
590fb506
C
239 }
240 })
241
242 it('Should import a video on server 2 with some fields', async function () {
454c20fa 243 this.timeout(60_000)
590fb506
C
244
245 const attributes = {
6910f20f 246 targetUrl: ImportsCommand.getYoutubeVideoUrl(),
3e17515e 247 channelId: channelIdServer2,
590fb506
C
248 privacy: VideoPrivacy.PUBLIC,
249 category: 10,
250 licence: 7,
251 language: 'en',
252 name: 'my super name',
253 description: 'my super description',
254 tags: [ 'supertag1', 'supertag2' ]
255 }
6910f20f
C
256 const { video } = await servers[1].importsCommand.importVideo({ attributes })
257 expect(video.name).to.equal('my super name')
590fb506
C
258 })
259
3e17515e 260 it('Should have the videos listed on the two instances', async function () {
454c20fa 261 this.timeout(120_000)
590fb506
C
262
263 await waitJobs(servers)
264
265 for (const server of servers) {
266 const res = await getVideosList(server.url)
3e17515e
C
267 expect(res.body.total).to.equal(4)
268 expect(res.body.data).to.have.lengthOf(4)
590fb506 269
a2470c9f 270 await checkVideoServer2(server, res.body.data[0].uuid)
3e17515e 271
a1587156 272 const [ , videoHttp, videoMagnet, videoTorrent ] = res.body.data
a2470c9f 273 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
3e17515e
C
274 }
275 })
276
277 it('Should import a video that will be transcoded', async function () {
454c20fa 278 this.timeout(120_000)
3e17515e
C
279
280 const attributes = {
281 name: 'transcoded video',
6910f20f 282 magnetUri: ImportsCommand.getMagnetURI(),
3e17515e
C
283 channelId: channelIdServer2,
284 privacy: VideoPrivacy.PUBLIC
285 }
6910f20f
C
286 const { video } = await servers[1].importsCommand.importVideo({ attributes })
287 const videoUUID = video.uuid
3e17515e
C
288
289 await waitJobs(servers)
290
291 for (const server of servers) {
292 const res = await getVideo(server.url, videoUUID)
293 const video: VideoDetails = res.body
294
295 expect(video.name).to.equal('transcoded video')
296 expect(video.files).to.have.lengthOf(4)
590fb506
C
297 }
298 })
299
454c20fa
RK
300 it('Should import no HDR version on a HDR video', async function () {
301 this.timeout(120_000)
302
303 const config = {
304 transcoding: {
305 enabled: true,
306 resolutions: {
307 '240p': false,
308 '360p': false,
309 '480p': false,
310 '720p': false,
311 '1080p': true, // the resulting resolution shouldn't be higher than this, and not vp9.2/av01
312 '1440p': false,
313 '2160p': false
314 },
315 webtorrent: { enabled: true },
316 hls: { enabled: false }
317 },
318 import: {
319 videos: {
320 http: {
321 enabled: true
322 },
323 torrent: {
324 enabled: true
325 }
326 }
327 }
328 }
65e6e260 329 await servers[0].configCommand.updateCustomSubConfig({ newConfig: config })
454c20fa
RK
330
331 const attributes = {
332 name: 'hdr video',
6910f20f 333 targetUrl: ImportsCommand.getYoutubeHDRVideoUrl(),
454c20fa
RK
334 channelId: channelIdServer1,
335 privacy: VideoPrivacy.PUBLIC
336 }
6910f20f
C
337 const { video: videoImported } = await servers[0].importsCommand.importVideo({ attributes })
338 const videoUUID = videoImported.uuid
454c20fa
RK
339
340 await waitJobs(servers)
341
342 // test resolution
343 const res2 = await getVideo(servers[0].url, videoUUID)
344 const video: VideoDetails = res2.body
345 expect(video.name).to.equal('hdr video')
346 const maxResolution = Math.max.apply(Math, video.files.map(function (o) { return o.resolution.id }))
347 expect(maxResolution, 'expected max resolution not met').to.equals(VideoResolution.H_1080P)
348 })
349
7c3b7976
C
350 after(async function () {
351 await cleanupTests(servers)
590fb506
C
352 })
353})