aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-10-21 16:28:39 +0200
committerChocobozzz <me@florianbigard.com>2021-10-22 10:25:24 +0200
commit62549e6c9818f422698f030e0b242609115493ed (patch)
tree12a969f694239fe5f926f779698df9523605ee80 /server/tests
parenta71d4140a5b7831dbe2eb7a0dfaa6a755cb2e906 (diff)
downloadPeerTube-62549e6c9818f422698f030e0b242609115493ed.tar.gz
PeerTube-62549e6c9818f422698f030e0b242609115493ed.tar.zst
PeerTube-62549e6c9818f422698f030e0b242609115493ed.zip
Rewrite youtube-dl import
Use python3 binary Allows to use a custom youtube-dl release URL Allows to use yt-dlp (youtube-dl fork) Remove proxy config from configuration to use HTTP_PROXY and HTTPS_PROXY env variables
Diffstat (limited to 'server/tests')
-rw-r--r--server/tests/api/server/proxy.ts107
-rw-r--r--server/tests/api/videos/video-imports.ts632
-rw-r--r--server/tests/fixtures/video_import_preview_yt_dlp.jpgbin0 -> 15844 bytes
-rw-r--r--server/tests/fixtures/video_import_thumbnail_yt_dlp.jpgbin0 -> 10163 bytes
4 files changed, 436 insertions, 303 deletions
diff --git a/server/tests/api/server/proxy.ts b/server/tests/api/server/proxy.ts
index 72bd49078..29f3e10d8 100644
--- a/server/tests/api/server/proxy.ts
+++ b/server/tests/api/server/proxy.ts
@@ -2,8 +2,18 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { cleanupTests, createMultipleServers, doubleFollow, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/extra-utils' 5import {
6 cleanupTests,
7 createMultipleServers,
8 doubleFollow,
9 FIXTURE_URLS,
10 PeerTubeServer,
11 setAccessTokensToServers,
12 setDefaultVideoChannel,
13 waitJobs
14} from '@shared/extra-utils'
6import { MockProxy } from '@shared/extra-utils/mock-servers/mock-proxy' 15import { MockProxy } from '@shared/extra-utils/mock-servers/mock-proxy'
16import { HttpStatusCode, VideoPrivacy } from '@shared/models'
7 17
8const expect = chai.expect 18const expect = chai.expect
9 19
@@ -25,43 +35,90 @@ describe('Test proxy', function () {
25 goodEnv.HTTP_PROXY = 'http://localhost:' + proxyPort 35 goodEnv.HTTP_PROXY = 'http://localhost:' + proxyPort
26 36
27 await setAccessTokensToServers(servers) 37 await setAccessTokensToServers(servers)
38 await setDefaultVideoChannel(servers)
28 await doubleFollow(servers[0], servers[1]) 39 await doubleFollow(servers[0], servers[1])
29 }) 40 })
30 41
31 it('Should succeed federation with the appropriate proxy config', async function () { 42 describe('Federation', function () {
32 await servers[0].kill()
33 await servers[0].run({}, { env: goodEnv })
34 43
35 await servers[0].videos.quickUpload({ name: 'video 1' }) 44 it('Should succeed federation with the appropriate proxy config', async function () {
45 this.timeout(40000)
36 46
37 await waitJobs(servers) 47 await servers[0].kill()
48 await servers[0].run({}, { env: goodEnv })
38 49
39 for (const server of servers) { 50 await servers[0].videos.quickUpload({ name: 'video 1' })
40 const { total, data } = await server.videos.list() 51
41 expect(total).to.equal(1) 52 await waitJobs(servers)
42 expect(data).to.have.lengthOf(1) 53
43 } 54 for (const server of servers) {
55 const { total, data } = await server.videos.list()
56 expect(total).to.equal(1)
57 expect(data).to.have.lengthOf(1)
58 }
59 })
60
61 it('Should fail federation with a wrong proxy config', async function () {
62 this.timeout(40000)
63
64 await servers[0].kill()
65 await servers[0].run({}, { env: badEnv })
66
67 await servers[0].videos.quickUpload({ name: 'video 2' })
68
69 await waitJobs(servers)
70
71 {
72 const { total, data } = await servers[0].videos.list()
73 expect(total).to.equal(2)
74 expect(data).to.have.lengthOf(2)
75 }
76
77 {
78 const { total, data } = await servers[1].videos.list()
79 expect(total).to.equal(1)
80 expect(data).to.have.lengthOf(1)
81 }
82 })
44 }) 83 })
45 84
46 it('Should fail federation with a wrong proxy config', async function () { 85 describe('Videos import', async function () {
47 await servers[0].kill() 86
48 await servers[0].run({}, { env: badEnv }) 87 function quickImport (expectedStatus: HttpStatusCode = HttpStatusCode.OK_200) {
88 return servers[0].imports.importVideo({
89 attributes: {
90 name: 'video import',
91 channelId: servers[0].store.channel.id,
92 privacy: VideoPrivacy.PUBLIC,
93 targetUrl: FIXTURE_URLS.peertube_long
94 },
95 expectedStatus
96 })
97 }
98
99 it('Should succeed import with the appropriate proxy config', async function () {
100 this.timeout(40000)
101
102 await servers[0].kill()
103 await servers[0].run({}, { env: goodEnv })
49 104
50 await servers[0].videos.quickUpload({ name: 'video 2' }) 105 await quickImport()
51 106
52 await waitJobs(servers) 107 await waitJobs(servers)
53 108
54 {
55 const { total, data } = await servers[0].videos.list() 109 const { total, data } = await servers[0].videos.list()
56 expect(total).to.equal(2) 110 expect(total).to.equal(3)
57 expect(data).to.have.lengthOf(2) 111 expect(data).to.have.lengthOf(3)
58 } 112 })
59 113
60 { 114 it('Should fail import with a wrong proxy config', async function () {
61 const { total, data } = await servers[1].videos.list() 115 this.timeout(40000)
62 expect(total).to.equal(1) 116
63 expect(data).to.have.lengthOf(1) 117 await servers[0].kill()
64 } 118 await servers[0].run({}, { env: badEnv })
119
120 await quickImport(HttpStatusCode.BAD_REQUEST_400)
121 })
65 }) 122 })
66 123
67 after(async function () { 124 after(async function () {
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts
index 948c779e8..cfb188060 100644
--- a/server/tests/api/videos/video-imports.ts
+++ b/server/tests/api/videos/video-imports.ts
@@ -1,368 +1,444 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import { expect } from 'chai'
5import { pathExists, remove } from 'fs-extra'
6import { join } from 'path'
5import { 7import {
6 areHttpImportTestsDisabled, 8 areHttpImportTestsDisabled,
7 cleanupTests, 9 cleanupTests,
8 createMultipleServers, 10 createMultipleServers,
11 createSingleServer,
9 doubleFollow, 12 doubleFollow,
10 FIXTURE_URLS, 13 FIXTURE_URLS,
11 PeerTubeServer, 14 PeerTubeServer,
12 setAccessTokensToServers, 15 setAccessTokensToServers,
16 setDefaultVideoChannel,
13 testCaptionFile, 17 testCaptionFile,
14 testImage, 18 testImage,
15 waitJobs 19 waitJobs
16} from '@shared/extra-utils' 20} from '@shared/extra-utils'
17import { VideoPrivacy, VideoResolution } from '@shared/models' 21import { VideoPrivacy, VideoResolution } from '@shared/models'
18 22
19const expect = chai.expect 23async function checkVideosServer1 (server: PeerTubeServer, idHttp: string, idMagnet: string, idTorrent: string) {
24 const videoHttp = await server.videos.get({ id: idHttp })
25
26 expect(videoHttp.name).to.equal('small video - youtube')
27 // FIXME: youtube-dl seems broken
28 // expect(videoHttp.category.label).to.equal('News & Politics')
29 // expect(videoHttp.licence.label).to.equal('Attribution')
30 expect(videoHttp.language.label).to.equal('Unknown')
31 expect(videoHttp.nsfw).to.be.false
32 expect(videoHttp.description).to.equal('this is a super description')
33 expect(videoHttp.tags).to.deep.equal([ 'tag1', 'tag2' ])
34 expect(videoHttp.files).to.have.lengthOf(1)
35
36 const originallyPublishedAt = new Date(videoHttp.originallyPublishedAt)
37 expect(originallyPublishedAt.getDate()).to.equal(14)
38 expect(originallyPublishedAt.getMonth()).to.equal(0)
39 expect(originallyPublishedAt.getFullYear()).to.equal(2019)
40
41 const videoMagnet = await server.videos.get({ id: idMagnet })
42 const videoTorrent = await server.videos.get({ id: idTorrent })
43
44 for (const video of [ videoMagnet, videoTorrent ]) {
45 expect(video.category.label).to.equal('Misc')
46 expect(video.licence.label).to.equal('Unknown')
47 expect(video.language.label).to.equal('Unknown')
48 expect(video.nsfw).to.be.false
49 expect(video.description).to.equal('this is a super torrent description')
50 expect(video.tags).to.deep.equal([ 'tag_torrent1', 'tag_torrent2' ])
51 expect(video.files).to.have.lengthOf(1)
52 }
53
54 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4')
55 expect(videoMagnet.name).to.contain('super peertube2 video')
56
57 const bodyCaptions = await server.captions.list({ videoId: idHttp })
58 expect(bodyCaptions.total).to.equal(2)
59}
60
61async function checkVideoServer2 (server: PeerTubeServer, id: number | string) {
62 const video = await server.videos.get({ id })
63
64 expect(video.name).to.equal('my super name')
65 expect(video.category.label).to.equal('Entertainment')
66 expect(video.licence.label).to.equal('Public Domain Dedication')
67 expect(video.language.label).to.equal('English')
68 expect(video.nsfw).to.be.false
69 expect(video.description).to.equal('my super description')
70 expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
71
72 expect(video.files).to.have.lengthOf(1)
73
74 const bodyCaptions = await server.captions.list({ videoId: id })
75 expect(bodyCaptions.total).to.equal(2)
76}
20 77
21describe('Test video imports', function () { 78describe('Test video imports', function () {
22 let servers: PeerTubeServer[] = []
23 let channelIdServer1: number
24 let channelIdServer2: number
25 79
26 if (areHttpImportTestsDisabled()) return 80 if (areHttpImportTestsDisabled()) return
27 81
28 async function checkVideosServer1 (server: PeerTubeServer, idHttp: string, idMagnet: string, idTorrent: string) { 82 function runSuite (mode: 'youtube-dl' | 'yt-dlp') {
29 const videoHttp = await server.videos.get({ id: idHttp })
30
31 expect(videoHttp.name).to.equal('small video - youtube')
32 // FIXME: youtube-dl seems broken
33 // expect(videoHttp.category.label).to.equal('News & Politics')
34 // expect(videoHttp.licence.label).to.equal('Attribution')
35 expect(videoHttp.language.label).to.equal('Unknown')
36 expect(videoHttp.nsfw).to.be.false
37 expect(videoHttp.description).to.equal('this is a super description')
38 expect(videoHttp.tags).to.deep.equal([ 'tag1', 'tag2' ])
39 expect(videoHttp.files).to.have.lengthOf(1)
40
41 const originallyPublishedAt = new Date(videoHttp.originallyPublishedAt)
42 expect(originallyPublishedAt.getDate()).to.equal(14)
43 expect(originallyPublishedAt.getMonth()).to.equal(0)
44 expect(originallyPublishedAt.getFullYear()).to.equal(2019)
45
46 const videoMagnet = await server.videos.get({ id: idMagnet })
47 const videoTorrent = await server.videos.get({ id: idTorrent })
48
49 for (const video of [ videoMagnet, videoTorrent ]) {
50 expect(video.category.label).to.equal('Misc')
51 expect(video.licence.label).to.equal('Unknown')
52 expect(video.language.label).to.equal('Unknown')
53 expect(video.nsfw).to.be.false
54 expect(video.description).to.equal('this is a super torrent description')
55 expect(video.tags).to.deep.equal([ 'tag_torrent1', 'tag_torrent2' ])
56 expect(video.files).to.have.lengthOf(1)
57 }
58 83
59 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4') 84 describe('Import ' + mode, function () {
60 expect(videoMagnet.name).to.contain('super peertube2 video') 85 let servers: PeerTubeServer[] = []
61 86
62 const bodyCaptions = await server.captions.list({ videoId: idHttp }) 87 before(async function () {
63 expect(bodyCaptions.total).to.equal(2) 88 this.timeout(30_000)
64 }
65 89
66 async function checkVideoServer2 (server: PeerTubeServer, id: number | string) { 90 // Run servers
67 const video = await server.videos.get({ id }) 91 servers = await createMultipleServers(2, {
92 import: {
93 videos: {
94 http: {
95 youtube_dl_release: {
96 url: mode === 'youtube-dl'
97 ? 'https://yt-dl.org/downloads/latest/youtube-dl'
98 : 'https://api.github.com/repos/yt-dlp/yt-dlp/releases',
68 99
69 expect(video.name).to.equal('my super name') 100 name: mode
70 expect(video.category.label).to.equal('Entertainment') 101 }
71 expect(video.licence.label).to.equal('Public Domain Dedication') 102 }
72 expect(video.language.label).to.equal('English') 103 }
73 expect(video.nsfw).to.be.false 104 }
74 expect(video.description).to.equal('my super description') 105 })
75 expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
76 106
77 expect(video.files).to.have.lengthOf(1) 107 await setAccessTokensToServers(servers)
108 await setDefaultVideoChannel(servers)
78 109
79 const bodyCaptions = await server.captions.list({ videoId: id }) 110 await doubleFollow(servers[0], servers[1])
80 expect(bodyCaptions.total).to.equal(2) 111 })
81 }
82 112
83 before(async function () { 113 it('Should import videos on server 1', async function () {
84 this.timeout(30_000) 114 this.timeout(60_000)
85 115
86 // Run servers 116 const baseAttributes = {
87 servers = await createMultipleServers(2) 117 channelId: servers[0].store.channel.id,
118 privacy: VideoPrivacy.PUBLIC
119 }
88 120
89 await setAccessTokensToServers(servers) 121 {
122 const attributes = { ...baseAttributes, targetUrl: FIXTURE_URLS.youtube }
123 const { video } = await servers[0].imports.importVideo({ attributes })
124 expect(video.name).to.equal('small video - youtube')
90 125
91 { 126 {
92 const { videoChannels } = await servers[0].users.getMyInfo() 127 expect(video.thumbnailPath).to.match(new RegExp(`^/static/thumbnails/.+.jpg$`))
93 channelIdServer1 = videoChannels[0].id 128 expect(video.previewPath).to.match(new RegExp(`^/lazy-static/previews/.+.jpg$`))
94 }
95 129
96 { 130 const suffix = mode === 'yt-dlp'
97 const { videoChannels } = await servers[1].users.getMyInfo() 131 ? '_yt_dlp'
98 channelIdServer2 = videoChannels[0].id 132 : ''
99 }
100 133
101 await doubleFollow(servers[0], servers[1]) 134 await testImage(servers[0].url, 'video_import_thumbnail' + suffix, video.thumbnailPath)
102 }) 135 await testImage(servers[0].url, 'video_import_preview' + suffix, video.previewPath)
136 }
103 137
104 it('Should import videos on server 1', async function () { 138 const bodyCaptions = await servers[0].captions.list({ videoId: video.id })
105 this.timeout(60_000) 139 const videoCaptions = bodyCaptions.data
140 expect(videoCaptions).to.have.lengthOf(2)
106 141
107 const baseAttributes = { 142 {
108 channelId: channelIdServer1, 143 const enCaption = videoCaptions.find(caption => caption.language.id === 'en')
109 privacy: VideoPrivacy.PUBLIC 144 expect(enCaption).to.exist
110 } 145 expect(enCaption.language.label).to.equal('English')
146 expect(enCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-en.vtt$`))
111 147
112 { 148 const regex = `WEBVTT[ \n]+Kind: captions[ \n]+Language: en[ \n]+00:00:01.600 --> 00:00:04.200[ \n]+English \\(US\\)[ \n]+` +
113 const attributes = { ...baseAttributes, targetUrl: FIXTURE_URLS.youtube } 149 `00:00:05.900 --> 00:00:07.999[ \n]+This is a subtitle in American English[ \n]+` +
114 const { video } = await servers[0].imports.importVideo({ attributes }) 150 `00:00:10.000 --> 00:00:14.000[ \n]+Adding subtitles is very easy to do`
115 expect(video.name).to.equal('small video - youtube') 151 await testCaptionFile(servers[0].url, enCaption.captionPath, new RegExp(regex))
152 }
116 153
117 expect(video.thumbnailPath).to.match(new RegExp(`^/static/thumbnails/.+.jpg$`)) 154 {
118 expect(video.previewPath).to.match(new RegExp(`^/lazy-static/previews/.+.jpg$`)) 155 const frCaption = videoCaptions.find(caption => caption.language.id === 'fr')
156 expect(frCaption).to.exist
157 expect(frCaption.language.label).to.equal('French')
158 expect(frCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-fr.vtt`))
119 159
120 await testImage(servers[0].url, 'video_import_thumbnail', video.thumbnailPath) 160 const regex = `WEBVTT[ \n]+Kind: captions[ \n]+Language: fr[ \n]+00:00:01.600 --> 00:00:04.200[ \n]+` +
121 await testImage(servers[0].url, 'video_import_preview', video.previewPath) 161 `Français \\(FR\\)[ \n]+00:00:05.900 --> 00:00:07.999[ \n]+C'est un sous-titre français[ \n]+` +
162 `00:00:10.000 --> 00:00:14.000[ \n]+Ajouter un sous-titre est vraiment facile`
122 163
123 const bodyCaptions = await servers[0].captions.list({ videoId: video.id }) 164 await testCaptionFile(servers[0].url, frCaption.captionPath, new RegExp(regex))
124 const videoCaptions = bodyCaptions.data 165 }
125 expect(videoCaptions).to.have.lengthOf(2) 166 }
126 167
127 const enCaption = videoCaptions.find(caption => caption.language.id === 'en') 168 {
128 expect(enCaption).to.exist 169 const attributes = {
129 expect(enCaption.language.label).to.equal('English') 170 ...baseAttributes,
130 expect(enCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-en.vtt$`)) 171 magnetUri: FIXTURE_URLS.magnet,
131 await testCaptionFile(servers[0].url, enCaption.captionPath, `WEBVTT 172 description: 'this is a super torrent description',
132Kind: captions 173 tags: [ 'tag_torrent1', 'tag_torrent2' ]
133Language: en 174 }
175 const { video } = await servers[0].imports.importVideo({ attributes })
176 expect(video.name).to.equal('super peertube2 video')
177 }
134 178
13500:00:01.600 --> 00:00:04.200 179 {
136English (US) 180 const attributes = {
181 ...baseAttributes,
182 torrentfile: 'video-720p.torrent' as any,
183 description: 'this is a super torrent description',
184 tags: [ 'tag_torrent1', 'tag_torrent2' ]
185 }
186 const { video } = await servers[0].imports.importVideo({ attributes })
187 expect(video.name).to.equal('你好 世界 720p.mp4')
188 }
189 })
137 190
13800:00:05.900 --> 00:00:07.999 191 it('Should list the videos to import in my videos on server 1', async function () {
139This is a subtitle in American English 192 const { total, data } = await servers[0].videos.listMyVideos({ sort: 'createdAt' })
140 193
14100:00:10.000 --> 00:00:14.000 194 expect(total).to.equal(3)
142Adding subtitles is very easy to do`)
143 195
144 const frCaption = videoCaptions.find(caption => caption.language.id === 'fr') 196 expect(data).to.have.lengthOf(3)
145 expect(frCaption).to.exist 197 expect(data[0].name).to.equal('small video - youtube')
146 expect(frCaption.language.label).to.equal('French') 198 expect(data[1].name).to.equal('super peertube2 video')
147 expect(frCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-fr.vtt`)) 199 expect(data[2].name).to.equal('你好 世界 720p.mp4')
148 await testCaptionFile(servers[0].url, frCaption.captionPath, `WEBVTT 200 })
149Kind: captions
150Language: fr
151 201
15200:00:01.600 --> 00:00:04.200 202 it('Should list the videos to import in my imports on server 1', async function () {
153Français (FR) 203 const { total, data: videoImports } = await servers[0].imports.getMyVideoImports({ sort: '-createdAt' })
204 expect(total).to.equal(3)
154 205
15500:00:05.900 --> 00:00:07.999 206 expect(videoImports).to.have.lengthOf(3)
156C'est un sous-titre français
157 207
15800:00:10.000 --> 00:00:14.000 208 expect(videoImports[2].targetUrl).to.equal(FIXTURE_URLS.youtube)
159Ajouter un sous-titre est vraiment facile`) 209 expect(videoImports[2].magnetUri).to.be.null
160 } 210 expect(videoImports[2].torrentName).to.be.null
211 expect(videoImports[2].video.name).to.equal('small video - youtube')
161 212
162 { 213 expect(videoImports[1].targetUrl).to.be.null
163 const attributes = { 214 expect(videoImports[1].magnetUri).to.equal(FIXTURE_URLS.magnet)
164 ...baseAttributes, 215 expect(videoImports[1].torrentName).to.be.null
165 magnetUri: FIXTURE_URLS.magnet, 216 expect(videoImports[1].video.name).to.equal('super peertube2 video')
166 description: 'this is a super torrent description',
167 tags: [ 'tag_torrent1', 'tag_torrent2' ]
168 }
169 const { video } = await servers[0].imports.importVideo({ attributes })
170 expect(video.name).to.equal('super peertube2 video')
171 }
172 217
173 { 218 expect(videoImports[0].targetUrl).to.be.null
174 const attributes = { 219 expect(videoImports[0].magnetUri).to.be.null
175 ...baseAttributes, 220 expect(videoImports[0].torrentName).to.equal('video-720p.torrent')
176 torrentfile: 'video-720p.torrent' as any, 221 expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4')
177 description: 'this is a super torrent description', 222 })
178 tags: [ 'tag_torrent1', 'tag_torrent2' ]
179 }
180 const { video } = await servers[0].imports.importVideo({ attributes })
181 expect(video.name).to.equal('你好 世界 720p.mp4')
182 }
183 })
184 223
185 it('Should list the videos to import in my videos on server 1', async function () { 224 it('Should have the video listed on the two instances', async function () {
186 const { total, data } = await servers[0].videos.listMyVideos({ sort: 'createdAt' }) 225 this.timeout(120_000)
187 226
188 expect(total).to.equal(3) 227 await waitJobs(servers)
189 228
190 expect(data).to.have.lengthOf(3) 229 for (const server of servers) {
191 expect(data[0].name).to.equal('small video - youtube') 230 const { total, data } = await server.videos.list()
192 expect(data[1].name).to.equal('super peertube2 video') 231 expect(total).to.equal(3)
193 expect(data[2].name).to.equal('你好 世界 720p.mp4') 232 expect(data).to.have.lengthOf(3)
194 })
195 233
196 it('Should list the videos to import in my imports on server 1', async function () { 234 const [ videoHttp, videoMagnet, videoTorrent ] = data
197 const { total, data: videoImports } = await servers[0].imports.getMyVideoImports({ sort: '-createdAt' }) 235 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
198 expect(total).to.equal(3) 236 }
237 })
238
239 it('Should import a video on server 2 with some fields', async function () {
240 this.timeout(60_000)
241
242 const attributes = {
243 targetUrl: FIXTURE_URLS.youtube,
244 channelId: servers[1].store.channel.id,
245 privacy: VideoPrivacy.PUBLIC,
246 category: 10,
247 licence: 7,
248 language: 'en',
249 name: 'my super name',
250 description: 'my super description',
251 tags: [ 'supertag1', 'supertag2' ]
252 }
253 const { video } = await servers[1].imports.importVideo({ attributes })
254 expect(video.name).to.equal('my super name')
255 })
199 256
200 expect(videoImports).to.have.lengthOf(3) 257 it('Should have the videos listed on the two instances', async function () {
258 this.timeout(120_000)
201 259
202 expect(videoImports[2].targetUrl).to.equal(FIXTURE_URLS.youtube) 260 await waitJobs(servers)
203 expect(videoImports[2].magnetUri).to.be.null
204 expect(videoImports[2].torrentName).to.be.null
205 expect(videoImports[2].video.name).to.equal('small video - youtube')
206 261
207 expect(videoImports[1].targetUrl).to.be.null 262 for (const server of servers) {
208 expect(videoImports[1].magnetUri).to.equal(FIXTURE_URLS.magnet) 263 const { total, data } = await server.videos.list()
209 expect(videoImports[1].torrentName).to.be.null 264 expect(total).to.equal(4)
210 expect(videoImports[1].video.name).to.equal('super peertube2 video') 265 expect(data).to.have.lengthOf(4)
211 266
212 expect(videoImports[0].targetUrl).to.be.null 267 await checkVideoServer2(server, data[0].uuid)
213 expect(videoImports[0].magnetUri).to.be.null
214 expect(videoImports[0].torrentName).to.equal('video-720p.torrent')
215 expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4')
216 })
217 268
218 it('Should have the video listed on the two instances', async function () { 269 const [ , videoHttp, videoMagnet, videoTorrent ] = data
219 this.timeout(120_000) 270 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
271 }
272 })
220 273
221 await waitJobs(servers) 274 it('Should import a video that will be transcoded', async function () {
275 this.timeout(240_000)
222 276
223 for (const server of servers) { 277 const attributes = {
224 const { total, data } = await server.videos.list() 278 name: 'transcoded video',
225 expect(total).to.equal(3) 279 magnetUri: FIXTURE_URLS.magnet,
226 expect(data).to.have.lengthOf(3) 280 channelId: servers[1].store.channel.id,
281 privacy: VideoPrivacy.PUBLIC
282 }
283 const { video } = await servers[1].imports.importVideo({ attributes })
284 const videoUUID = video.uuid
227 285
228 const [ videoHttp, videoMagnet, videoTorrent ] = data 286 await waitJobs(servers)
229 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
230 }
231 })
232 287
233 it('Should import a video on server 2 with some fields', async function () { 288 for (const server of servers) {
234 this.timeout(60_000) 289 const video = await server.videos.get({ id: videoUUID })
235
236 const attributes = {
237 targetUrl: FIXTURE_URLS.youtube,
238 channelId: channelIdServer2,
239 privacy: VideoPrivacy.PUBLIC,
240 category: 10,
241 licence: 7,
242 language: 'en',
243 name: 'my super name',
244 description: 'my super description',
245 tags: [ 'supertag1', 'supertag2' ]
246 }
247 const { video } = await servers[1].imports.importVideo({ attributes })
248 expect(video.name).to.equal('my super name')
249 })
250 290
251 it('Should have the videos listed on the two instances', async function () { 291 expect(video.name).to.equal('transcoded video')
252 this.timeout(120_000) 292 expect(video.files).to.have.lengthOf(4)
293 }
294 })
295
296 it('Should import no HDR version on a HDR video', async function () {
297 this.timeout(300_000)
298
299 const config = {
300 transcoding: {
301 enabled: true,
302 resolutions: {
303 '240p': true,
304 '360p': false,
305 '480p': false,
306 '720p': false,
307 '1080p': false, // the resulting resolution shouldn't be higher than this, and not vp9.2/av01
308 '1440p': false,
309 '2160p': false
310 },
311 webtorrent: { enabled: true },
312 hls: { enabled: false }
313 },
314 import: {
315 videos: {
316 http: {
317 enabled: true
318 },
319 torrent: {
320 enabled: true
321 }
322 }
323 }
324 }
325 await servers[0].config.updateCustomSubConfig({ newConfig: config })
253 326
254 await waitJobs(servers) 327 const attributes = {
328 name: 'hdr video',
329 targetUrl: FIXTURE_URLS.youtubeHDR,
330 channelId: servers[0].store.channel.id,
331 privacy: VideoPrivacy.PUBLIC
332 }
333 const { video: videoImported } = await servers[0].imports.importVideo({ attributes })
334 const videoUUID = videoImported.uuid
335
336 await waitJobs(servers)
337
338 // test resolution
339 const video = await servers[0].videos.get({ id: videoUUID })
340 expect(video.name).to.equal('hdr video')
341 const maxResolution = Math.max.apply(Math, video.files.map(function (o) { return o.resolution.id }))
342 expect(maxResolution, 'expected max resolution not met').to.equals(VideoResolution.H_240P)
343 })
344
345 it('Should import a peertube video', async function () {
346 this.timeout(120_000)
347
348 // TODO: include peertube_short when https://github.com/ytdl-org/youtube-dl/pull/29475 is merged
349 for (const targetUrl of [ FIXTURE_URLS.peertube_long ]) {
350 // for (const targetUrl of [ FIXTURE_URLS.peertube_long, FIXTURE_URLS.peertube_short ]) {
351 await servers[0].config.disableTranscoding()
352
353 const attributes = {
354 targetUrl,
355 channelId: servers[0].store.channel.id,
356 privacy: VideoPrivacy.PUBLIC
357 }
358 const { video } = await servers[0].imports.importVideo({ attributes })
359 const videoUUID = video.uuid
255 360
256 for (const server of servers) { 361 await waitJobs(servers)
257 const { total, data } = await server.videos.list()
258 expect(total).to.equal(4)
259 expect(data).to.have.lengthOf(4)
260 362
261 await checkVideoServer2(server, data[0].uuid) 363 for (const server of servers) {
364 const video = await server.videos.get({ id: videoUUID })
262 365
263 const [ , videoHttp, videoMagnet, videoTorrent ] = data 366 expect(video.name).to.equal('E2E tests')
264 await checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid) 367 }
265 } 368 }
266 }) 369 })
267 370
268 it('Should import a video that will be transcoded', async function () { 371 after(async function () {
269 this.timeout(240_000) 372 await cleanupTests(servers)
373 })
374 })
375 }
270 376
271 const attributes = { 377 runSuite('youtube-dl')
272 name: 'transcoded video',
273 magnetUri: FIXTURE_URLS.magnet,
274 channelId: channelIdServer2,
275 privacy: VideoPrivacy.PUBLIC
276 }
277 const { video } = await servers[1].imports.importVideo({ attributes })
278 const videoUUID = video.uuid
279 378
280 await waitJobs(servers) 379 runSuite('yt-dlp')
281 380
282 for (const server of servers) { 381 describe('Auto update', function () {
283 const video = await server.videos.get({ id: videoUUID }) 382 let server: PeerTubeServer
284 383
285 expect(video.name).to.equal('transcoded video') 384 function quickPeerTubeImport () {
286 expect(video.files).to.have.lengthOf(4) 385 const attributes = {
386 targetUrl: FIXTURE_URLS.peertube_long,
387 channelId: server.store.channel.id,
388 privacy: VideoPrivacy.PUBLIC
389 }
390
391 return server.imports.importVideo({ attributes })
287 } 392 }
288 })
289 393
290 it('Should import no HDR version on a HDR video', async function () { 394 async function testBinaryUpdate (releaseUrl: string, releaseName: string) {
291 this.timeout(300_000) 395 await remove(join(server.servers.buildDirectory('bin'), releaseName))
292 396
293 const config = { 397 await server.kill()
294 transcoding: { 398 await server.run({
295 enabled: true, 399 import: {
296 resolutions: { 400 videos: {
297 '240p': true, 401 http: {
298 '360p': false, 402 youtube_dl_release: {
299 '480p': false, 403 url: releaseUrl,
300 '720p': false, 404 name: releaseName
301 '1080p': false, // the resulting resolution shouldn't be higher than this, and not vp9.2/av01 405 }
302 '1440p': false, 406 }
303 '2160p': false
304 },
305 webtorrent: { enabled: true },
306 hls: { enabled: false }
307 },
308 import: {
309 videos: {
310 http: {
311 enabled: true
312 },
313 torrent: {
314 enabled: true
315 } 407 }
316 } 408 }
317 } 409 })
318 } 410
319 await servers[0].config.updateCustomSubConfig({ newConfig: config }) 411 await quickPeerTubeImport()
320 412
321 const attributes = { 413 expect(await pathExists(join(server.servers.buildDirectory('bin'), releaseName))).to.be.true
322 name: 'hdr video',
323 targetUrl: FIXTURE_URLS.youtubeHDR,
324 channelId: channelIdServer1,
325 privacy: VideoPrivacy.PUBLIC
326 } 414 }
327 const { video: videoImported } = await servers[0].imports.importVideo({ attributes })
328 const videoUUID = videoImported.uuid
329 415
330 await waitJobs(servers) 416 before(async function () {
417 this.timeout(30_000)
331 418
332 // test resolution 419 // Run servers
333 const video = await servers[0].videos.get({ id: videoUUID }) 420 server = await createSingleServer(1)
334 expect(video.name).to.equal('hdr video')
335 const maxResolution = Math.max.apply(Math, video.files.map(function (o) { return o.resolution.id }))
336 expect(maxResolution, 'expected max resolution not met').to.equals(VideoResolution.H_240P)
337 })
338 421
339 it('Should import a peertube video', async function () { 422 await setAccessTokensToServers([ server ])
340 this.timeout(120_000) 423 await setDefaultVideoChannel([ server ])
424 })
341 425
342 // TODO: include peertube_short when https://github.com/ytdl-org/youtube-dl/pull/29475 is merged 426 it('Should update youtube-dl from github URL', async function () {
343 for (const targetUrl of [ FIXTURE_URLS.peertube_long ]) { 427 this.timeout(120_000)
344 // for (const targetUrl of [ FIXTURE_URLS.peertube_long, FIXTURE_URLS.peertube_short ]) {
345 await servers[0].config.disableTranscoding()
346 428
347 const attributes = { 429 await testBinaryUpdate('https://api.github.com/repos/ytdl-org/youtube-dl/releases', 'youtube-dl')
348 targetUrl, 430 })
349 channelId: channelIdServer1,
350 privacy: VideoPrivacy.PUBLIC
351 }
352 const { video } = await servers[0].imports.importVideo({ attributes })
353 const videoUUID = video.uuid
354 431
355 await waitJobs(servers) 432 it('Should update youtube-dl from raw URL', async function () {
433 this.timeout(120_000)
356 434
357 for (const server of servers) { 435 await testBinaryUpdate('https://yt-dl.org/downloads/latest/youtube-dl', 'youtube-dl')
358 const video = await server.videos.get({ id: videoUUID }) 436 })
359 437
360 expect(video.name).to.equal('E2E tests') 438 it('Should update youtube-dl from youtube-dl fork', async function () {
361 } 439 this.timeout(120_000)
362 }
363 })
364 440
365 after(async function () { 441 await testBinaryUpdate('https://api.github.com/repos/yt-dlp/yt-dlp/releases', 'yt-dlp')
366 await cleanupTests(servers) 442 })
367 }) 443 })
368}) 444})
diff --git a/server/tests/fixtures/video_import_preview_yt_dlp.jpg b/server/tests/fixtures/video_import_preview_yt_dlp.jpg
new file mode 100644
index 000000000..9e8833bf9
--- /dev/null
+++ b/server/tests/fixtures/video_import_preview_yt_dlp.jpg
Binary files differ
diff --git a/server/tests/fixtures/video_import_thumbnail_yt_dlp.jpg b/server/tests/fixtures/video_import_thumbnail_yt_dlp.jpg
new file mode 100644
index 000000000..f672a785a
--- /dev/null
+++ b/server/tests/fixtures/video_import_thumbnail_yt_dlp.jpg
Binary files differ