diff options
author | Chocobozzz <me@florianbigard.com> | 2021-10-21 16:28:39 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-10-22 10:25:24 +0200 |
commit | 62549e6c9818f422698f030e0b242609115493ed (patch) | |
tree | 12a969f694239fe5f926f779698df9523605ee80 /server/tests/api | |
parent | a71d4140a5b7831dbe2eb7a0dfaa6a755cb2e906 (diff) | |
download | PeerTube-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/api')
-rw-r--r-- | server/tests/api/server/proxy.ts | 107 | ||||
-rw-r--r-- | server/tests/api/videos/video-imports.ts | 632 |
2 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 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import * as chai from 'chai' | 4 | import * as chai from 'chai' |
5 | import { cleanupTests, createMultipleServers, doubleFollow, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/extra-utils' | 5 | import { |
6 | cleanupTests, | ||
7 | createMultipleServers, | ||
8 | doubleFollow, | ||
9 | FIXTURE_URLS, | ||
10 | PeerTubeServer, | ||
11 | setAccessTokensToServers, | ||
12 | setDefaultVideoChannel, | ||
13 | waitJobs | ||
14 | } from '@shared/extra-utils' | ||
6 | import { MockProxy } from '@shared/extra-utils/mock-servers/mock-proxy' | 15 | import { MockProxy } from '@shared/extra-utils/mock-servers/mock-proxy' |
16 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' | ||
7 | 17 | ||
8 | const expect = chai.expect | 18 | const 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 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import * as chai from 'chai' | 4 | import { expect } from 'chai' |
5 | import { pathExists, remove } from 'fs-extra' | ||
6 | import { join } from 'path' | ||
5 | import { | 7 | import { |
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' |
17 | import { VideoPrivacy, VideoResolution } from '@shared/models' | 21 | import { VideoPrivacy, VideoResolution } from '@shared/models' |
18 | 22 | ||
19 | const expect = chai.expect | 23 | async 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 | |||
61 | async 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 | ||
21 | describe('Test video imports', function () { | 78 | describe('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', |
132 | Kind: captions | 173 | tags: [ 'tag_torrent1', 'tag_torrent2' ] |
133 | Language: en | 174 | } |
175 | const { video } = await servers[0].imports.importVideo({ attributes }) | ||
176 | expect(video.name).to.equal('super peertube2 video') | ||
177 | } | ||
134 | 178 | ||
135 | 00:00:01.600 --> 00:00:04.200 | 179 | { |
136 | English (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 | ||
138 | 00:00:05.900 --> 00:00:07.999 | 191 | it('Should list the videos to import in my videos on server 1', async function () { |
139 | This is a subtitle in American English | 192 | const { total, data } = await servers[0].videos.listMyVideos({ sort: 'createdAt' }) |
140 | 193 | ||
141 | 00:00:10.000 --> 00:00:14.000 | 194 | expect(total).to.equal(3) |
142 | Adding 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 | }) |
149 | Kind: captions | ||
150 | Language: fr | ||
151 | 201 | ||
152 | 00:00:01.600 --> 00:00:04.200 | 202 | it('Should list the videos to import in my imports on server 1', async function () { |
153 | Français (FR) | 203 | const { total, data: videoImports } = await servers[0].imports.getMyVideoImports({ sort: '-createdAt' }) |
204 | expect(total).to.equal(3) | ||
154 | 205 | ||
155 | 00:00:05.900 --> 00:00:07.999 | 206 | expect(videoImports).to.have.lengthOf(3) |
156 | C'est un sous-titre français | ||
157 | 207 | ||
158 | 00:00:10.000 --> 00:00:14.000 | 208 | expect(videoImports[2].targetUrl).to.equal(FIXTURE_URLS.youtube) |
159 | Ajouter 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 | }) |