diff options
Diffstat (limited to 'server/tests/api/live')
-rw-r--r-- | server/tests/api/live/index.ts | 1 | ||||
-rw-r--r-- | server/tests/api/live/live.ts | 351 |
2 files changed, 352 insertions, 0 deletions
diff --git a/server/tests/api/live/index.ts b/server/tests/api/live/index.ts new file mode 100644 index 000000000..280daf423 --- /dev/null +++ b/server/tests/api/live/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './live' | |||
diff --git a/server/tests/api/live/live.ts b/server/tests/api/live/live.ts new file mode 100644 index 000000000..e66c0cb26 --- /dev/null +++ b/server/tests/api/live/live.ts | |||
@@ -0,0 +1,351 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import 'mocha' | ||
4 | import * as chai from 'chai' | ||
5 | import { LiveVideo, LiveVideoCreate, VideoDetails, VideoPrivacy } from '@shared/models' | ||
6 | import { | ||
7 | acceptChangeOwnership, | ||
8 | cleanupTests, | ||
9 | createLive, | ||
10 | doubleFollow, | ||
11 | flushAndRunMultipleServers, | ||
12 | getLive, | ||
13 | getVideo, | ||
14 | getVideosList, | ||
15 | makeRawRequest, | ||
16 | removeVideo, | ||
17 | ServerInfo, | ||
18 | setAccessTokensToServers, | ||
19 | setDefaultVideoChannel, | ||
20 | testImage, | ||
21 | updateCustomSubConfig, | ||
22 | updateLive, | ||
23 | waitJobs | ||
24 | } from '../../../../shared/extra-utils' | ||
25 | |||
26 | const expect = chai.expect | ||
27 | |||
28 | describe('Test live', function () { | ||
29 | let servers: ServerInfo[] = [] | ||
30 | let liveVideoUUID: string | ||
31 | |||
32 | before(async function () { | ||
33 | this.timeout(120000) | ||
34 | |||
35 | servers = await flushAndRunMultipleServers(2) | ||
36 | |||
37 | // Get the access tokens | ||
38 | await setAccessTokensToServers(servers) | ||
39 | await setDefaultVideoChannel(servers) | ||
40 | |||
41 | await updateCustomSubConfig(servers[0].url, servers[0].accessToken, { | ||
42 | live: { | ||
43 | enabled: true, | ||
44 | allowReplay: true | ||
45 | } | ||
46 | }) | ||
47 | |||
48 | // Server 1 and server 2 follow each other | ||
49 | await doubleFollow(servers[0], servers[1]) | ||
50 | }) | ||
51 | |||
52 | describe('Live creation, update and delete', function () { | ||
53 | |||
54 | it('Should create a live with the appropriate parameters', async function () { | ||
55 | this.timeout(20000) | ||
56 | |||
57 | const attributes: LiveVideoCreate = { | ||
58 | category: 1, | ||
59 | licence: 2, | ||
60 | language: 'fr', | ||
61 | description: 'super live description', | ||
62 | support: 'support field', | ||
63 | channelId: servers[0].videoChannel.id, | ||
64 | nsfw: false, | ||
65 | waitTranscoding: false, | ||
66 | name: 'my super live', | ||
67 | tags: [ 'tag1', 'tag2' ], | ||
68 | commentsEnabled: false, | ||
69 | downloadEnabled: false, | ||
70 | saveReplay: true, | ||
71 | privacy: VideoPrivacy.PUBLIC, | ||
72 | previewfile: 'video_short1-preview.webm.jpg', | ||
73 | thumbnailfile: 'video_short1.webm.jpg' | ||
74 | } | ||
75 | |||
76 | const res = await createLive(servers[0].url, servers[0].accessToken, attributes) | ||
77 | liveVideoUUID = res.body.video.uuid | ||
78 | |||
79 | await waitJobs(servers) | ||
80 | |||
81 | for (const server of servers) { | ||
82 | const resVideo = await getVideo(server.url, liveVideoUUID) | ||
83 | const video: VideoDetails = resVideo.body | ||
84 | |||
85 | expect(video.category.id).to.equal(1) | ||
86 | expect(video.licence.id).to.equal(2) | ||
87 | expect(video.language.id).to.equal('fr') | ||
88 | expect(video.description).to.equal('super live description') | ||
89 | expect(video.support).to.equal('support field') | ||
90 | |||
91 | expect(video.channel.name).to.equal(servers[0].videoChannel.name) | ||
92 | expect(video.channel.host).to.equal(servers[0].videoChannel.host) | ||
93 | |||
94 | expect(video.nsfw).to.be.false | ||
95 | expect(video.waitTranscoding).to.be.false | ||
96 | expect(video.name).to.equal('my super live') | ||
97 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2' ]) | ||
98 | expect(video.commentsEnabled).to.be.false | ||
99 | expect(video.downloadEnabled).to.be.false | ||
100 | expect(video.privacy.id).to.equal(VideoPrivacy.PUBLIC) | ||
101 | |||
102 | await testImage(server.url, 'video_short1-preview.webm', video.previewPath) | ||
103 | await testImage(server.url, 'video_short1.webm', video.thumbnailPath) | ||
104 | |||
105 | const resLive = await getLive(server.url, server.accessToken, liveVideoUUID) | ||
106 | const live: LiveVideo = resLive.body | ||
107 | |||
108 | if (server.url === servers[0].url) { | ||
109 | expect(live.rtmpUrl).to.equal('rtmp://' + server.hostname + ':1936/live') | ||
110 | expect(live.streamKey).to.not.be.empty | ||
111 | } else { | ||
112 | expect(live.rtmpUrl).to.be.null | ||
113 | expect(live.streamKey).to.be.null | ||
114 | } | ||
115 | |||
116 | expect(live.saveReplay).to.be.true | ||
117 | } | ||
118 | }) | ||
119 | |||
120 | it('Should have a default preview and thumbnail', async function () { | ||
121 | this.timeout(20000) | ||
122 | |||
123 | const attributes: LiveVideoCreate = { | ||
124 | name: 'default live thumbnail', | ||
125 | channelId: servers[0].videoChannel.id, | ||
126 | privacy: VideoPrivacy.UNLISTED, | ||
127 | nsfw: true | ||
128 | } | ||
129 | |||
130 | const res = await createLive(servers[0].url, servers[0].accessToken, attributes) | ||
131 | const videoId = res.body.video.uuid | ||
132 | |||
133 | await waitJobs(servers) | ||
134 | |||
135 | for (const server of servers) { | ||
136 | const resVideo = await getVideo(server.url, videoId) | ||
137 | const video: VideoDetails = resVideo.body | ||
138 | |||
139 | expect(video.privacy.id).to.equal(VideoPrivacy.UNLISTED) | ||
140 | expect(video.nsfw).to.be.true | ||
141 | |||
142 | await makeRawRequest(server.url + video.thumbnailPath, 200) | ||
143 | await makeRawRequest(server.url + video.previewPath, 200) | ||
144 | } | ||
145 | }) | ||
146 | |||
147 | it('Should not have the live listed since nobody streams into', async function () { | ||
148 | for (const server of servers) { | ||
149 | const res = await getVideosList(server.url) | ||
150 | |||
151 | expect(res.body.total).to.equal(0) | ||
152 | expect(res.body.data).to.have.lengthOf(0) | ||
153 | } | ||
154 | }) | ||
155 | |||
156 | it('Should not be able to update a live of another server', async function () { | ||
157 | await updateLive(servers[1].url, servers[1].accessToken, liveVideoUUID, { saveReplay: false }, 403) | ||
158 | }) | ||
159 | |||
160 | it('Should update the live', async function () { | ||
161 | this.timeout(10000) | ||
162 | |||
163 | await updateLive(servers[0].url, servers[0].accessToken, liveVideoUUID, { saveReplay: false }) | ||
164 | await waitJobs(servers) | ||
165 | }) | ||
166 | |||
167 | it('Have the live updated', async function () { | ||
168 | for (const server of servers) { | ||
169 | const res = await getLive(server.url, server.accessToken, liveVideoUUID) | ||
170 | const live: LiveVideo = res.body | ||
171 | |||
172 | if (server.url === servers[0].url) { | ||
173 | expect(live.rtmpUrl).to.equal('rtmp://' + server.hostname + ':1936/live') | ||
174 | expect(live.streamKey).to.not.be.empty | ||
175 | } else { | ||
176 | expect(live.rtmpUrl).to.be.null | ||
177 | expect(live.streamKey).to.be.null | ||
178 | } | ||
179 | |||
180 | expect(live.saveReplay).to.be.false | ||
181 | } | ||
182 | }) | ||
183 | |||
184 | it('Delete the live', async function () { | ||
185 | this.timeout(10000) | ||
186 | |||
187 | await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) | ||
188 | await waitJobs(servers) | ||
189 | }) | ||
190 | |||
191 | it('Should have the live deleted', async function () { | ||
192 | for (const server of servers) { | ||
193 | await getVideo(server.url, liveVideoUUID, 404) | ||
194 | await getLive(server.url, server.accessToken, liveVideoUUID, 404) | ||
195 | } | ||
196 | }) | ||
197 | }) | ||
198 | |||
199 | describe('Test live constraints', function () { | ||
200 | |||
201 | it('Should not have size limit if save replay is disabled', async function () { | ||
202 | |||
203 | }) | ||
204 | |||
205 | it('Should have size limit if save replay is enabled', async function () { | ||
206 | // daily quota + total quota | ||
207 | |||
208 | }) | ||
209 | |||
210 | it('Should have max duration limit', async function () { | ||
211 | |||
212 | }) | ||
213 | }) | ||
214 | |||
215 | describe('With save replay disabled', function () { | ||
216 | |||
217 | it('Should correctly create and federate the "waiting for stream" live', async function () { | ||
218 | |||
219 | }) | ||
220 | |||
221 | it('Should correctly have updated the live and federated it when streaming in the live', async function () { | ||
222 | |||
223 | }) | ||
224 | |||
225 | it('Should correctly delete the video and the live after the stream ended', async function () { | ||
226 | // Wait 10 seconds | ||
227 | // get video 404 | ||
228 | // get video federation 404 | ||
229 | |||
230 | // check cleanup | ||
231 | }) | ||
232 | |||
233 | it('Should correctly terminate the stream on blacklist and delete the live', async function () { | ||
234 | // Wait 10 seconds | ||
235 | // get video 404 | ||
236 | // get video federation 404 | ||
237 | |||
238 | // check cleanup | ||
239 | }) | ||
240 | |||
241 | it('Should correctly terminate the stream on delete and delete the video', async function () { | ||
242 | // Wait 10 seconds | ||
243 | // get video 404 | ||
244 | // get video federation 404 | ||
245 | |||
246 | // check cleanup | ||
247 | }) | ||
248 | }) | ||
249 | |||
250 | describe('With save replay enabled', function () { | ||
251 | |||
252 | it('Should correctly create and federate the "waiting for stream" live', async function () { | ||
253 | |||
254 | }) | ||
255 | |||
256 | it('Should correctly have updated the live and federated it when streaming in the live', async function () { | ||
257 | |||
258 | }) | ||
259 | |||
260 | it('Should correctly have saved the live and federated it after the streaming', async function () { | ||
261 | |||
262 | }) | ||
263 | |||
264 | it('Should update the saved live and correctly federate the updated attributes', async function () { | ||
265 | |||
266 | }) | ||
267 | |||
268 | it('Should have cleaned up the live files', async function () { | ||
269 | |||
270 | }) | ||
271 | |||
272 | it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () { | ||
273 | // Wait 10 seconds | ||
274 | // get video -> blacklisted | ||
275 | // get video federation -> blacklisted | ||
276 | |||
277 | // check cleanup live files quand meme | ||
278 | }) | ||
279 | |||
280 | it('Should correctly terminate the stream on delete and delete the video', async function () { | ||
281 | // Wait 10 seconds | ||
282 | // get video 404 | ||
283 | // get video federation 404 | ||
284 | |||
285 | // check cleanup | ||
286 | }) | ||
287 | }) | ||
288 | |||
289 | describe('Stream checks', function () { | ||
290 | |||
291 | it('Should not allow a stream without the appropriate path', async function () { | ||
292 | |||
293 | }) | ||
294 | |||
295 | it('Should not allow a stream without the appropriate stream key', async function () { | ||
296 | |||
297 | }) | ||
298 | |||
299 | it('Should not allow a stream on a live that was blacklisted', async function () { | ||
300 | |||
301 | }) | ||
302 | |||
303 | it('Should not allow a stream on a live that was deleted', async function () { | ||
304 | |||
305 | }) | ||
306 | }) | ||
307 | |||
308 | describe('Live transcoding', function () { | ||
309 | |||
310 | it('Should enable transcoding without additional resolutions', async function () { | ||
311 | // enable | ||
312 | // stream | ||
313 | // wait federation + test | ||
314 | |||
315 | }) | ||
316 | |||
317 | it('Should enable transcoding with some resolutions', async function () { | ||
318 | // enable | ||
319 | // stream | ||
320 | // wait federation + test | ||
321 | }) | ||
322 | |||
323 | it('Should enable transcoding with some resolutions and correctly save them', async function () { | ||
324 | // enable | ||
325 | // stream | ||
326 | // end stream | ||
327 | // wait federation + test | ||
328 | }) | ||
329 | |||
330 | it('Should correctly have cleaned up the live files', async function () { | ||
331 | // check files | ||
332 | }) | ||
333 | }) | ||
334 | |||
335 | describe('Live socket messages', function () { | ||
336 | |||
337 | it('Should correctly send a message when the live starts', async function () { | ||
338 | // local | ||
339 | // federation | ||
340 | }) | ||
341 | |||
342 | it('Should correctly send a message when the live ends', async function () { | ||
343 | // local | ||
344 | // federation | ||
345 | }) | ||
346 | }) | ||
347 | |||
348 | after(async function () { | ||
349 | await cleanupTests(servers) | ||
350 | }) | ||
351 | }) | ||