]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/videos/video-imports.ts
f6ae8cab145c06c87566f41e980a93aeeb85016b
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-imports.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import 'mocha'
4 import * as chai from 'chai'
5 import {
6 areHttpImportTestsDisabled,
7 cleanupTests,
8 doubleFollow,
9 flushAndRunMultipleServers,
10 getMyUserInformation,
11 getMyVideos,
12 getVideo,
13 getVideosList,
14 ImportsCommand,
15 ServerInfo,
16 setAccessTokensToServers,
17 testCaptionFile,
18 testImage,
19 waitJobs
20 } from '@shared/extra-utils'
21 import { VideoDetails, VideoPrivacy, VideoResolution } from '@shared/models'
22
23 const expect = chai.expect
24
25 describe('Test video imports', function () {
26 let servers: ServerInfo[] = []
27 let channelIdServer1: number
28 let channelIdServer2: number
29
30 if (areHttpImportTestsDisabled()) return
31
32 async function checkVideosServer1 (server: ServerInfo, idHttp: string, idMagnet: string, idTorrent: string) {
33 const resHttp = await getVideo(server.url, idHttp)
34 const videoHttp: VideoDetails = resHttp.body
35
36 expect(videoHttp.name).to.equal('small video - youtube')
37 // FIXME: youtube-dl seems broken
38 // expect(videoHttp.category.label).to.equal('News & Politics')
39 // expect(videoHttp.licence.label).to.equal('Attribution')
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)
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)
50
51 const resMagnet = await getVideo(server.url, idMagnet)
52 const videoMagnet: VideoDetails = resMagnet.body
53 const resTorrent = await getVideo(server.url, idTorrent)
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 }
65
66 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4')
67 expect(videoMagnet.name).to.contain('super peertube2 video')
68
69 const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: idHttp })
70 expect(bodyCaptions.total).to.equal(2)
71 }
72
73 async function checkVideoServer2 (server: ServerInfo, id: number | string) {
74 const res = await getVideo(server.url, id)
75 const video: VideoDetails = res.body
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)
86
87 const bodyCaptions = await server.captionsCommand.listVideoCaptions({ videoId: id })
88 expect(bodyCaptions.total).to.equal(2)
89 }
90
91 before(async function () {
92 this.timeout(30_000)
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)
101 channelIdServer1 = res.body.videoChannels[0].id
102 }
103
104 {
105 const res = await getMyUserInformation(servers[1].url, servers[1].accessToken)
106 channelIdServer2 = res.body.videoChannels[0].id
107 }
108
109 await doubleFollow(servers[0], servers[1])
110 })
111
112 it('Should import videos on server 1', async function () {
113 this.timeout(60_000)
114
115 const baseAttributes = {
116 channelId: channelIdServer1,
117 privacy: VideoPrivacy.PUBLIC
118 }
119
120 {
121 const attributes = { ...baseAttributes, targetUrl: ImportsCommand.getYoutubeVideoUrl() }
122 const { video } = await servers[0].importsCommand.importVideo({ attributes })
123 expect(video.name).to.equal('small video - youtube')
124
125 expect(video.thumbnailPath).to.match(new RegExp(`^/static/thumbnails/.+.jpg$`))
126 expect(video.previewPath).to.match(new RegExp(`^/lazy-static/previews/.+.jpg$`))
127
128 await testImage(servers[0].url, 'video_import_thumbnail', video.thumbnailPath)
129 await testImage(servers[0].url, 'video_import_preview', video.previewPath)
130
131 const bodyCaptions = await servers[0].captionsCommand.listVideoCaptions({ videoId: video.id })
132 const videoCaptions = bodyCaptions.data
133 expect(videoCaptions).to.have.lengthOf(2)
134
135 const enCaption = videoCaptions.find(caption => caption.language.id === 'en')
136 expect(enCaption).to.exist
137 expect(enCaption.language.label).to.equal('English')
138 expect(enCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-en.vtt$`))
139 await testCaptionFile(servers[0].url, enCaption.captionPath, `WEBVTT
140 Kind: captions
141 Language: en
142
143 00:00:01.600 --> 00:00:04.200
144 English (US)
145
146 00:00:05.900 --> 00:00:07.999
147 This is a subtitle in American English
148
149 00:00:10.000 --> 00:00:14.000
150 Adding subtitles is very easy to do`)
151
152 const frCaption = videoCaptions.find(caption => caption.language.id === 'fr')
153 expect(frCaption).to.exist
154 expect(frCaption.language.label).to.equal('French')
155 expect(frCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-fr.vtt`))
156 await testCaptionFile(servers[0].url, frCaption.captionPath, `WEBVTT
157 Kind: captions
158 Language: fr
159
160 00:00:01.600 --> 00:00:04.200
161 Français (FR)
162
163 00:00:05.900 --> 00:00:07.999
164 C'est un sous-titre français
165
166 00:00:10.000 --> 00:00:14.000
167 Ajouter un sous-titre est vraiment facile`)
168 }
169
170 {
171 const attributes = {
172 ...baseAttributes,
173 magnetUri: ImportsCommand.getMagnetURI(),
174 description: 'this is a super torrent description',
175 tags: [ 'tag_torrent1', 'tag_torrent2' ]
176 }
177 const { video } = await servers[0].importsCommand.importVideo({ attributes })
178 expect(video.name).to.equal('super peertube2 video')
179 }
180
181 {
182 const attributes = {
183 ...baseAttributes,
184 torrentfile: 'video-720p.torrent' as any,
185 description: 'this is a super torrent description',
186 tags: [ 'tag_torrent1', 'tag_torrent2' ]
187 }
188 const { video } = await servers[0].importsCommand.importVideo({ attributes })
189 expect(video.name).to.equal('你好 世界 720p.mp4')
190 }
191 })
192
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')
195
196 expect(res.body.total).to.equal(3)
197
198 const videos = res.body.data
199 expect(videos).to.have.lengthOf(3)
200 expect(videos[0].name).to.equal('small video - youtube')
201 expect(videos[1].name).to.equal('super peertube2 video')
202 expect(videos[2].name).to.equal('你好 世界 720p.mp4')
203 })
204
205 it('Should list the videos to import in my imports on server 1', async function () {
206 const { total, data: videoImports } = await servers[0].importsCommand.getMyVideoImports({ sort: '-createdAt' })
207 expect(total).to.equal(3)
208
209 expect(videoImports).to.have.lengthOf(3)
210
211 expect(videoImports[2].targetUrl).to.equal(ImportsCommand.getYoutubeVideoUrl())
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')
215
216 expect(videoImports[1].targetUrl).to.be.null
217 expect(videoImports[1].magnetUri).to.equal(ImportsCommand.getMagnetURI())
218 expect(videoImports[1].torrentName).to.be.null
219 expect(videoImports[1].video.name).to.equal('super peertube2 video')
220
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')
225 })
226
227 it('Should have the video listed on the two instances', async function () {
228 this.timeout(120_000)
229
230 await waitJobs(servers)
231
232 for (const server of servers) {
233 const res = await getVideosList(server.url)
234 expect(res.body.total).to.equal(3)
235 expect(res.body.data).to.have.lengthOf(3)
236
237 const [ videoHttp, videoMagnet, videoTorrent ] = res.body.data
238 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
239 }
240 })
241
242 it('Should import a video on server 2 with some fields', async function () {
243 this.timeout(60_000)
244
245 const attributes = {
246 targetUrl: ImportsCommand.getYoutubeVideoUrl(),
247 channelId: channelIdServer2,
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 }
256 const { video } = await servers[1].importsCommand.importVideo({ attributes })
257 expect(video.name).to.equal('my super name')
258 })
259
260 it('Should have the videos listed on the two instances', async function () {
261 this.timeout(120_000)
262
263 await waitJobs(servers)
264
265 for (const server of servers) {
266 const res = await getVideosList(server.url)
267 expect(res.body.total).to.equal(4)
268 expect(res.body.data).to.have.lengthOf(4)
269
270 await checkVideoServer2(server, res.body.data[0].uuid)
271
272 const [ , videoHttp, videoMagnet, videoTorrent ] = res.body.data
273 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
274 }
275 })
276
277 it('Should import a video that will be transcoded', async function () {
278 this.timeout(120_000)
279
280 const attributes = {
281 name: 'transcoded video',
282 magnetUri: ImportsCommand.getMagnetURI(),
283 channelId: channelIdServer2,
284 privacy: VideoPrivacy.PUBLIC
285 }
286 const { video } = await servers[1].importsCommand.importVideo({ attributes })
287 const videoUUID = video.uuid
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)
297 }
298 })
299
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 }
329 await servers[0].configCommand.updateCustomSubConfig({ newConfig: config })
330
331 const attributes = {
332 name: 'hdr video',
333 targetUrl: ImportsCommand.getYoutubeHDRVideoUrl(),
334 channelId: channelIdServer1,
335 privacy: VideoPrivacy.PUBLIC
336 }
337 const { video: videoImported } = await servers[0].importsCommand.importVideo({ attributes })
338 const videoUUID = videoImported.uuid
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
350 after(async function () {
351 await cleanupTests(servers)
352 })
353 })