diff options
author | Chocobozzz <me@florianbigard.com> | 2023-06-01 14:51:16 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2023-06-29 10:16:55 +0200 |
commit | d8f39b126d9fe4bec1c12fb213548cc6edc87867 (patch) | |
tree | 7f0f1cb23165cf4dd789b2d78b1fef7ee116f647 /server/tests | |
parent | 1fb7d094229acdc190c3f7551b43ac5445814dee (diff) | |
download | PeerTube-d8f39b126d9fe4bec1c12fb213548cc6edc87867.tar.gz PeerTube-d8f39b126d9fe4bec1c12fb213548cc6edc87867.tar.zst PeerTube-d8f39b126d9fe4bec1c12fb213548cc6edc87867.zip |
Add storyboard support
Diffstat (limited to 'server/tests')
-rw-r--r-- | server/tests/api/check-params/config.ts | 3 | ||||
-rw-r--r-- | server/tests/api/check-params/index.ts | 1 | ||||
-rw-r--r-- | server/tests/api/check-params/video-storyboards.ts | 45 | ||||
-rw-r--r-- | server/tests/api/check-params/videos-overviews.ts | 2 | ||||
-rw-r--r-- | server/tests/api/server/config.ts | 5 | ||||
-rw-r--r-- | server/tests/api/videos/index.ts | 1 | ||||
-rw-r--r-- | server/tests/api/videos/video-storyboard.ts | 184 | ||||
-rw-r--r-- | server/tests/fixtures/video_very_long_10p.mp4 | bin | 0 -> 185338 bytes |
8 files changed, 240 insertions, 1 deletions
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index 472cad182..3c752cc3e 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts | |||
@@ -74,6 +74,9 @@ describe('Test config API validators', function () { | |||
74 | }, | 74 | }, |
75 | torrents: { | 75 | torrents: { |
76 | size: 4 | 76 | size: 4 |
77 | }, | ||
78 | storyboards: { | ||
79 | size: 5 | ||
77 | } | 80 | } |
78 | }, | 81 | }, |
79 | signup: { | 82 | signup: { |
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts index 400d312d3..c2a7ccd78 100644 --- a/server/tests/api/check-params/index.ts +++ b/server/tests/api/check-params/index.ts | |||
@@ -34,6 +34,7 @@ import './video-comments' | |||
34 | import './video-files' | 34 | import './video-files' |
35 | import './video-imports' | 35 | import './video-imports' |
36 | import './video-playlists' | 36 | import './video-playlists' |
37 | import './video-storyboards' | ||
37 | import './video-source' | 38 | import './video-source' |
38 | import './video-studio' | 39 | import './video-studio' |
39 | import './video-token' | 40 | import './video-token' |
diff --git a/server/tests/api/check-params/video-storyboards.ts b/server/tests/api/check-params/video-storyboards.ts new file mode 100644 index 000000000..a43d8fc48 --- /dev/null +++ b/server/tests/api/check-params/video-storyboards.ts | |||
@@ -0,0 +1,45 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' | ||
4 | import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' | ||
5 | |||
6 | describe('Test video storyboards API validator', function () { | ||
7 | let server: PeerTubeServer | ||
8 | |||
9 | let publicVideo: { uuid: string } | ||
10 | let privateVideo: { uuid: string } | ||
11 | |||
12 | // --------------------------------------------------------------- | ||
13 | |||
14 | before(async function () { | ||
15 | this.timeout(30000) | ||
16 | |||
17 | server = await createSingleServer(1) | ||
18 | await setAccessTokensToServers([ server ]) | ||
19 | |||
20 | publicVideo = await server.videos.quickUpload({ name: 'public' }) | ||
21 | privateVideo = await server.videos.quickUpload({ name: 'private', privacy: VideoPrivacy.PRIVATE }) | ||
22 | }) | ||
23 | |||
24 | it('Should fail without a valid uuid', async function () { | ||
25 | await server.storyboard.list({ id: '4da6fde3-88f7-4d16-b119-108df563d0b0', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
26 | }) | ||
27 | |||
28 | it('Should receive 404 when passing a non existing video id', async function () { | ||
29 | await server.storyboard.list({ id: '4da6fde3-88f7-4d16-b119-108df5630b06', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
30 | }) | ||
31 | |||
32 | it('Should not get the private storyboard without the appropriate token', async function () { | ||
33 | await server.storyboard.list({ id: privateVideo.uuid, expectedStatus: HttpStatusCode.UNAUTHORIZED_401, token: null }) | ||
34 | await server.storyboard.list({ id: publicVideo.uuid, expectedStatus: HttpStatusCode.OK_200, token: null }) | ||
35 | }) | ||
36 | |||
37 | it('Should succeed with the correct parameters', async function () { | ||
38 | await server.storyboard.list({ id: privateVideo.uuid }) | ||
39 | await server.storyboard.list({ id: publicVideo.uuid }) | ||
40 | }) | ||
41 | |||
42 | after(async function () { | ||
43 | await cleanupTests([ server ]) | ||
44 | }) | ||
45 | }) | ||
diff --git a/server/tests/api/check-params/videos-overviews.ts b/server/tests/api/check-params/videos-overviews.ts index f9cdb7ab3..ae7de24dd 100644 --- a/server/tests/api/check-params/videos-overviews.ts +++ b/server/tests/api/check-params/videos-overviews.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { cleanupTests, createSingleServer, PeerTubeServer } from '@shared/server-commands' | 3 | import { cleanupTests, createSingleServer, PeerTubeServer } from '@shared/server-commands' |
4 | 4 | ||
5 | describe('Test videos overview', function () { | 5 | describe('Test videos overview API validator', function () { |
6 | let server: PeerTubeServer | 6 | let server: PeerTubeServer |
7 | 7 | ||
8 | // --------------------------------------------------------------- | 8 | // --------------------------------------------------------------- |
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts index 011ba268c..efa7b50e3 100644 --- a/server/tests/api/server/config.ts +++ b/server/tests/api/server/config.ts | |||
@@ -46,6 +46,7 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) { | |||
46 | expect(data.cache.previews.size).to.equal(1) | 46 | expect(data.cache.previews.size).to.equal(1) |
47 | expect(data.cache.captions.size).to.equal(1) | 47 | expect(data.cache.captions.size).to.equal(1) |
48 | expect(data.cache.torrents.size).to.equal(1) | 48 | expect(data.cache.torrents.size).to.equal(1) |
49 | expect(data.cache.storyboards.size).to.equal(1) | ||
49 | 50 | ||
50 | expect(data.signup.enabled).to.be.true | 51 | expect(data.signup.enabled).to.be.true |
51 | expect(data.signup.limit).to.equal(4) | 52 | expect(data.signup.limit).to.equal(4) |
@@ -154,6 +155,7 @@ function checkUpdatedConfig (data: CustomConfig) { | |||
154 | expect(data.cache.previews.size).to.equal(2) | 155 | expect(data.cache.previews.size).to.equal(2) |
155 | expect(data.cache.captions.size).to.equal(3) | 156 | expect(data.cache.captions.size).to.equal(3) |
156 | expect(data.cache.torrents.size).to.equal(4) | 157 | expect(data.cache.torrents.size).to.equal(4) |
158 | expect(data.cache.storyboards.size).to.equal(5) | ||
157 | 159 | ||
158 | expect(data.signup.enabled).to.be.false | 160 | expect(data.signup.enabled).to.be.false |
159 | expect(data.signup.limit).to.equal(5) | 161 | expect(data.signup.limit).to.equal(5) |
@@ -290,6 +292,9 @@ const newCustomConfig: CustomConfig = { | |||
290 | }, | 292 | }, |
291 | torrents: { | 293 | torrents: { |
292 | size: 4 | 294 | size: 4 |
295 | }, | ||
296 | storyboards: { | ||
297 | size: 5 | ||
293 | } | 298 | } |
294 | }, | 299 | }, |
295 | signup: { | 300 | signup: { |
diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts index 357c08199..9c79b3aa6 100644 --- a/server/tests/api/videos/index.ts +++ b/server/tests/api/videos/index.ts | |||
@@ -20,3 +20,4 @@ import './videos-history' | |||
20 | import './videos-overview' | 20 | import './videos-overview' |
21 | import './video-source' | 21 | import './video-source' |
22 | import './video-static-file-privacy' | 22 | import './video-static-file-privacy' |
23 | import './video-storyboard' | ||
diff --git a/server/tests/api/videos/video-storyboard.ts b/server/tests/api/videos/video-storyboard.ts new file mode 100644 index 000000000..7ccdca8f7 --- /dev/null +++ b/server/tests/api/videos/video-storyboard.ts | |||
@@ -0,0 +1,184 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { expect } from 'chai' | ||
4 | import { FIXTURE_URLS } from '@server/tests/shared' | ||
5 | import { areHttpImportTestsDisabled } from '@shared/core-utils' | ||
6 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' | ||
7 | import { | ||
8 | cleanupTests, | ||
9 | createMultipleServers, | ||
10 | doubleFollow, | ||
11 | makeGetRequest, | ||
12 | PeerTubeServer, | ||
13 | sendRTMPStream, | ||
14 | setAccessTokensToServers, | ||
15 | setDefaultVideoChannel, | ||
16 | stopFfmpeg, | ||
17 | waitJobs | ||
18 | } from '@shared/server-commands' | ||
19 | |||
20 | async function checkStoryboard (options: { | ||
21 | server: PeerTubeServer | ||
22 | uuid: string | ||
23 | tilesCount?: number | ||
24 | minSize?: number | ||
25 | }) { | ||
26 | const { server, uuid, tilesCount, minSize = 1000 } = options | ||
27 | |||
28 | const { storyboards } = await server.storyboard.list({ id: uuid }) | ||
29 | |||
30 | expect(storyboards).to.have.lengthOf(1) | ||
31 | |||
32 | const storyboard = storyboards[0] | ||
33 | |||
34 | expect(storyboard.spriteDuration).to.equal(1) | ||
35 | expect(storyboard.spriteHeight).to.equal(108) | ||
36 | expect(storyboard.spriteWidth).to.equal(192) | ||
37 | expect(storyboard.storyboardPath).to.exist | ||
38 | |||
39 | if (tilesCount) { | ||
40 | expect(storyboard.totalWidth).to.equal(192 * Math.min(tilesCount, 10)) | ||
41 | expect(storyboard.totalHeight).to.equal(108 * Math.max((tilesCount / 10), 1)) | ||
42 | } | ||
43 | |||
44 | const { body } = await makeGetRequest({ url: server.url, path: storyboard.storyboardPath, expectedStatus: HttpStatusCode.OK_200 }) | ||
45 | expect(body.length).to.be.above(minSize) | ||
46 | } | ||
47 | |||
48 | describe('Test video storyboard', function () { | ||
49 | let servers: PeerTubeServer[] | ||
50 | |||
51 | before(async function () { | ||
52 | this.timeout(120000) | ||
53 | |||
54 | servers = await createMultipleServers(2) | ||
55 | await setAccessTokensToServers(servers) | ||
56 | await setDefaultVideoChannel(servers) | ||
57 | |||
58 | await doubleFollow(servers[0], servers[1]) | ||
59 | }) | ||
60 | |||
61 | it('Should generate a storyboard after upload without transcoding', async function () { | ||
62 | this.timeout(60000) | ||
63 | |||
64 | // 5s video | ||
65 | const { uuid } = await servers[0].videos.quickUpload({ name: 'upload', fixture: 'video_short.webm' }) | ||
66 | await waitJobs(servers) | ||
67 | |||
68 | for (const server of servers) { | ||
69 | await checkStoryboard({ server, uuid, tilesCount: 5 }) | ||
70 | } | ||
71 | }) | ||
72 | |||
73 | it('Should generate a storyboard after upload without transcoding with a long video', async function () { | ||
74 | this.timeout(60000) | ||
75 | |||
76 | // 124s video | ||
77 | const { uuid } = await servers[0].videos.quickUpload({ name: 'upload', fixture: 'video_very_long_10p.mp4' }) | ||
78 | await waitJobs(servers) | ||
79 | |||
80 | for (const server of servers) { | ||
81 | await checkStoryboard({ server, uuid, tilesCount: 100 }) | ||
82 | } | ||
83 | }) | ||
84 | |||
85 | it('Should generate a storyboard after upload with transcoding', async function () { | ||
86 | this.timeout(60000) | ||
87 | |||
88 | await servers[0].config.enableMinimumTranscoding() | ||
89 | |||
90 | // 5s video | ||
91 | const { uuid } = await servers[0].videos.quickUpload({ name: 'upload', fixture: 'video_short.webm' }) | ||
92 | await waitJobs(servers) | ||
93 | |||
94 | for (const server of servers) { | ||
95 | await checkStoryboard({ server, uuid, tilesCount: 5 }) | ||
96 | } | ||
97 | }) | ||
98 | |||
99 | it('Should generate a storyboard after an audio upload', async function () { | ||
100 | this.timeout(60000) | ||
101 | |||
102 | // 6s audio | ||
103 | const attributes = { name: 'audio', fixture: 'sample.ogg' } | ||
104 | const { uuid } = await servers[0].videos.upload({ attributes, mode: 'legacy' }) | ||
105 | await waitJobs(servers) | ||
106 | |||
107 | for (const server of servers) { | ||
108 | await checkStoryboard({ server, uuid, tilesCount: 6, minSize: 250 }) | ||
109 | } | ||
110 | }) | ||
111 | |||
112 | it('Should generate a storyboard after HTTP import', async function () { | ||
113 | this.timeout(60000) | ||
114 | |||
115 | if (areHttpImportTestsDisabled()) return | ||
116 | |||
117 | // 3s video | ||
118 | const { video } = await servers[0].imports.importVideo({ | ||
119 | attributes: { | ||
120 | targetUrl: FIXTURE_URLS.goodVideo, | ||
121 | channelId: servers[0].store.channel.id, | ||
122 | privacy: VideoPrivacy.PUBLIC | ||
123 | } | ||
124 | }) | ||
125 | await waitJobs(servers) | ||
126 | |||
127 | for (const server of servers) { | ||
128 | await checkStoryboard({ server, uuid: video.uuid, tilesCount: 3 }) | ||
129 | } | ||
130 | }) | ||
131 | |||
132 | it('Should generate a storyboard after torrent import', async function () { | ||
133 | this.timeout(60000) | ||
134 | |||
135 | if (areHttpImportTestsDisabled()) return | ||
136 | |||
137 | // 10s video | ||
138 | const { video } = await servers[0].imports.importVideo({ | ||
139 | attributes: { | ||
140 | magnetUri: FIXTURE_URLS.magnet, | ||
141 | channelId: servers[0].store.channel.id, | ||
142 | privacy: VideoPrivacy.PUBLIC | ||
143 | } | ||
144 | }) | ||
145 | await waitJobs(servers) | ||
146 | |||
147 | for (const server of servers) { | ||
148 | await checkStoryboard({ server, uuid: video.uuid, tilesCount: 10 }) | ||
149 | } | ||
150 | }) | ||
151 | |||
152 | it('Should generate a storyboard after a live', async function () { | ||
153 | this.timeout(240000) | ||
154 | |||
155 | await servers[0].config.enableLive({ allowReplay: true, transcoding: true, resolutions: 'min' }) | ||
156 | |||
157 | const { live, video } = await servers[0].live.quickCreate({ | ||
158 | saveReplay: true, | ||
159 | permanentLive: false, | ||
160 | privacy: VideoPrivacy.PUBLIC | ||
161 | }) | ||
162 | |||
163 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: live.rtmpUrl, streamKey: live.streamKey }) | ||
164 | await servers[0].live.waitUntilPublished({ videoId: video.id }) | ||
165 | |||
166 | await stopFfmpeg(ffmpegCommand) | ||
167 | |||
168 | await servers[0].live.waitUntilReplacedByReplay({ videoId: video.id }) | ||
169 | await waitJobs(servers) | ||
170 | |||
171 | for (const server of servers) { | ||
172 | await checkStoryboard({ server, uuid: video.uuid }) | ||
173 | } | ||
174 | }) | ||
175 | |||
176 | it('Should generate a storyboard with different video durations', async function () { | ||
177 | this.timeout(60000) | ||
178 | |||
179 | }) | ||
180 | |||
181 | after(async function () { | ||
182 | await cleanupTests(servers) | ||
183 | }) | ||
184 | }) | ||
diff --git a/server/tests/fixtures/video_very_long_10p.mp4 b/server/tests/fixtures/video_very_long_10p.mp4 new file mode 100644 index 000000000..852297933 --- /dev/null +++ b/server/tests/fixtures/video_very_long_10p.mp4 | |||
Binary files differ | |||