diff options
author | Chocobozzz <me@florianbigard.com> | 2023-08-17 08:59:21 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2023-08-17 08:59:21 +0200 |
commit | c380e3928517eb5311b38cf257816642617d7a33 (patch) | |
tree | 2ea9b70ebca16b5d109bcce98fe7f944dad89319 /packages/tests/src/api/check-params/live.ts | |
parent | a8ca6190fb462bf6eb5685cfc1d8ae444164a487 (diff) | |
parent | 3a4992633ee62d5edfbb484d9c6bcb3cf158489d (diff) | |
download | PeerTube-c380e3928517eb5311b38cf257816642617d7a33.tar.gz PeerTube-c380e3928517eb5311b38cf257816642617d7a33.tar.zst PeerTube-c380e3928517eb5311b38cf257816642617d7a33.zip |
Merge branch 'feature/esm-and-nx' into develop
Diffstat (limited to 'packages/tests/src/api/check-params/live.ts')
-rw-r--r-- | packages/tests/src/api/check-params/live.ts | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/packages/tests/src/api/check-params/live.ts b/packages/tests/src/api/check-params/live.ts new file mode 100644 index 000000000..5900823ea --- /dev/null +++ b/packages/tests/src/api/check-params/live.ts | |||
@@ -0,0 +1,590 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { expect } from 'chai' | ||
4 | import { omit } from '@peertube/peertube-core-utils' | ||
5 | import { HttpStatusCode, LiveVideoLatencyMode, VideoCreateResult, VideoPrivacy } from '@peertube/peertube-models' | ||
6 | import { buildAbsoluteFixturePath } from '@peertube/peertube-node-utils' | ||
7 | import { | ||
8 | cleanupTests, | ||
9 | createSingleServer, | ||
10 | LiveCommand, | ||
11 | makePostBodyRequest, | ||
12 | makeUploadRequest, | ||
13 | PeerTubeServer, | ||
14 | sendRTMPStream, | ||
15 | setAccessTokensToServers, | ||
16 | stopFfmpeg | ||
17 | } from '@peertube/peertube-server-commands' | ||
18 | |||
19 | describe('Test video lives API validator', function () { | ||
20 | const path = '/api/v1/videos/live' | ||
21 | let server: PeerTubeServer | ||
22 | let userAccessToken = '' | ||
23 | let channelId: number | ||
24 | let video: VideoCreateResult | ||
25 | let videoIdNotLive: number | ||
26 | let command: LiveCommand | ||
27 | |||
28 | // --------------------------------------------------------------- | ||
29 | |||
30 | before(async function () { | ||
31 | this.timeout(30000) | ||
32 | |||
33 | server = await createSingleServer(1) | ||
34 | |||
35 | await setAccessTokensToServers([ server ]) | ||
36 | |||
37 | await server.config.updateCustomSubConfig({ | ||
38 | newConfig: { | ||
39 | live: { | ||
40 | enabled: true, | ||
41 | latencySetting: { | ||
42 | enabled: false | ||
43 | }, | ||
44 | maxInstanceLives: 20, | ||
45 | maxUserLives: 20, | ||
46 | allowReplay: true | ||
47 | } | ||
48 | } | ||
49 | }) | ||
50 | |||
51 | const username = 'user1' | ||
52 | const password = 'my super password' | ||
53 | await server.users.create({ username, password }) | ||
54 | userAccessToken = await server.login.getAccessToken({ username, password }) | ||
55 | |||
56 | { | ||
57 | const { videoChannels } = await server.users.getMyInfo() | ||
58 | channelId = videoChannels[0].id | ||
59 | } | ||
60 | |||
61 | { | ||
62 | videoIdNotLive = (await server.videos.quickUpload({ name: 'not live' })).id | ||
63 | } | ||
64 | |||
65 | command = server.live | ||
66 | }) | ||
67 | |||
68 | describe('When creating a live', function () { | ||
69 | let baseCorrectParams | ||
70 | |||
71 | before(function () { | ||
72 | baseCorrectParams = { | ||
73 | name: 'my super name', | ||
74 | category: 5, | ||
75 | licence: 1, | ||
76 | language: 'pt', | ||
77 | nsfw: false, | ||
78 | commentsEnabled: true, | ||
79 | downloadEnabled: true, | ||
80 | waitTranscoding: true, | ||
81 | description: 'my super description', | ||
82 | support: 'my super support text', | ||
83 | tags: [ 'tag1', 'tag2' ], | ||
84 | privacy: VideoPrivacy.PUBLIC, | ||
85 | channelId, | ||
86 | saveReplay: false, | ||
87 | replaySettings: undefined, | ||
88 | permanentLive: false, | ||
89 | latencyMode: LiveVideoLatencyMode.DEFAULT | ||
90 | } | ||
91 | }) | ||
92 | |||
93 | it('Should fail with nothing', async function () { | ||
94 | const fields = {} | ||
95 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
96 | }) | ||
97 | |||
98 | it('Should fail with a long name', async function () { | ||
99 | const fields = { ...baseCorrectParams, name: 'super'.repeat(65) } | ||
100 | |||
101 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
102 | }) | ||
103 | |||
104 | it('Should fail with a bad category', async function () { | ||
105 | const fields = { ...baseCorrectParams, category: 125 } | ||
106 | |||
107 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
108 | }) | ||
109 | |||
110 | it('Should fail with a bad licence', async function () { | ||
111 | const fields = { ...baseCorrectParams, licence: 125 } | ||
112 | |||
113 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
114 | }) | ||
115 | |||
116 | it('Should fail with a bad language', async function () { | ||
117 | const fields = { ...baseCorrectParams, language: 'a'.repeat(15) } | ||
118 | |||
119 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
120 | }) | ||
121 | |||
122 | it('Should fail with a long description', async function () { | ||
123 | const fields = { ...baseCorrectParams, description: 'super'.repeat(2500) } | ||
124 | |||
125 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
126 | }) | ||
127 | |||
128 | it('Should fail with a long support text', async function () { | ||
129 | const fields = { ...baseCorrectParams, support: 'super'.repeat(201) } | ||
130 | |||
131 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
132 | }) | ||
133 | |||
134 | it('Should fail without a channel', async function () { | ||
135 | const fields = omit(baseCorrectParams, [ 'channelId' ]) | ||
136 | |||
137 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
138 | }) | ||
139 | |||
140 | it('Should fail with a bad channel', async function () { | ||
141 | const fields = { ...baseCorrectParams, channelId: 545454 } | ||
142 | |||
143 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
144 | }) | ||
145 | |||
146 | it('Should fail with a bad privacy for replay settings', async function () { | ||
147 | const fields = { ...baseCorrectParams, saveReplay: true, replaySettings: { privacy: 999 } } | ||
148 | |||
149 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
150 | }) | ||
151 | |||
152 | it('Should fail with another user channel', async function () { | ||
153 | const user = { | ||
154 | username: 'fake', | ||
155 | password: 'fake_password' | ||
156 | } | ||
157 | await server.users.create({ username: user.username, password: user.password }) | ||
158 | |||
159 | const accessTokenUser = await server.login.getAccessToken(user) | ||
160 | const { videoChannels } = await server.users.getMyInfo({ token: accessTokenUser }) | ||
161 | const customChannelId = videoChannels[0].id | ||
162 | |||
163 | const fields = { ...baseCorrectParams, channelId: customChannelId } | ||
164 | |||
165 | await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields }) | ||
166 | }) | ||
167 | |||
168 | it('Should fail with too many tags', async function () { | ||
169 | const fields = { ...baseCorrectParams, tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ] } | ||
170 | |||
171 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
172 | }) | ||
173 | |||
174 | it('Should fail with a tag length too low', async function () { | ||
175 | const fields = { ...baseCorrectParams, tags: [ 'tag1', 't' ] } | ||
176 | |||
177 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
178 | }) | ||
179 | |||
180 | it('Should fail with a tag length too big', async function () { | ||
181 | const fields = { ...baseCorrectParams, tags: [ 'tag1', 'my_super_tag_too_long_long_long_long_long_long' ] } | ||
182 | |||
183 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
184 | }) | ||
185 | |||
186 | it('Should fail with an incorrect thumbnail file', async function () { | ||
187 | const fields = baseCorrectParams | ||
188 | const attaches = { | ||
189 | thumbnailfile: buildAbsoluteFixturePath('video_short.mp4') | ||
190 | } | ||
191 | |||
192 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | ||
193 | }) | ||
194 | |||
195 | it('Should fail with a big thumbnail file', async function () { | ||
196 | const fields = baseCorrectParams | ||
197 | const attaches = { | ||
198 | thumbnailfile: buildAbsoluteFixturePath('custom-preview-big.png') | ||
199 | } | ||
200 | |||
201 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | ||
202 | }) | ||
203 | |||
204 | it('Should fail with an incorrect preview file', async function () { | ||
205 | const fields = baseCorrectParams | ||
206 | const attaches = { | ||
207 | previewfile: buildAbsoluteFixturePath('video_short.mp4') | ||
208 | } | ||
209 | |||
210 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | ||
211 | }) | ||
212 | |||
213 | it('Should fail with a big preview file', async function () { | ||
214 | const fields = baseCorrectParams | ||
215 | const attaches = { | ||
216 | previewfile: buildAbsoluteFixturePath('custom-preview-big.png') | ||
217 | } | ||
218 | |||
219 | await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches }) | ||
220 | }) | ||
221 | |||
222 | it('Should fail with bad latency setting', async function () { | ||
223 | const fields = { ...baseCorrectParams, latencyMode: 42 } | ||
224 | |||
225 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) | ||
226 | }) | ||
227 | |||
228 | it('Should fail to set latency if the server does not allow it', async function () { | ||
229 | const fields = { ...baseCorrectParams, latencyMode: LiveVideoLatencyMode.HIGH_LATENCY } | ||
230 | |||
231 | await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
232 | }) | ||
233 | |||
234 | it('Should succeed with the correct parameters', async function () { | ||
235 | this.timeout(30000) | ||
236 | |||
237 | const res = await makePostBodyRequest({ | ||
238 | url: server.url, | ||
239 | path, | ||
240 | token: server.accessToken, | ||
241 | fields: baseCorrectParams, | ||
242 | expectedStatus: HttpStatusCode.OK_200 | ||
243 | }) | ||
244 | |||
245 | video = res.body.video | ||
246 | }) | ||
247 | |||
248 | it('Should forbid if live is disabled', async function () { | ||
249 | await server.config.updateCustomSubConfig({ | ||
250 | newConfig: { | ||
251 | live: { | ||
252 | enabled: false | ||
253 | } | ||
254 | } | ||
255 | }) | ||
256 | |||
257 | await makePostBodyRequest({ | ||
258 | url: server.url, | ||
259 | path, | ||
260 | token: server.accessToken, | ||
261 | fields: baseCorrectParams, | ||
262 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
263 | }) | ||
264 | }) | ||
265 | |||
266 | it('Should forbid to save replay if not enabled by the admin', async function () { | ||
267 | const fields = { ...baseCorrectParams, saveReplay: true, replaySettings: { privacy: VideoPrivacy.PUBLIC } } | ||
268 | |||
269 | await server.config.updateCustomSubConfig({ | ||
270 | newConfig: { | ||
271 | live: { | ||
272 | enabled: true, | ||
273 | allowReplay: false | ||
274 | } | ||
275 | } | ||
276 | }) | ||
277 | |||
278 | await makePostBodyRequest({ | ||
279 | url: server.url, | ||
280 | path, | ||
281 | token: server.accessToken, | ||
282 | fields, | ||
283 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
284 | }) | ||
285 | }) | ||
286 | |||
287 | it('Should allow to save replay if enabled by the admin', async function () { | ||
288 | const fields = { ...baseCorrectParams, saveReplay: true, replaySettings: { privacy: VideoPrivacy.PUBLIC } } | ||
289 | |||
290 | await server.config.updateCustomSubConfig({ | ||
291 | newConfig: { | ||
292 | live: { | ||
293 | enabled: true, | ||
294 | allowReplay: true | ||
295 | } | ||
296 | } | ||
297 | }) | ||
298 | |||
299 | await makePostBodyRequest({ | ||
300 | url: server.url, | ||
301 | path, | ||
302 | token: server.accessToken, | ||
303 | fields, | ||
304 | expectedStatus: HttpStatusCode.OK_200 | ||
305 | }) | ||
306 | }) | ||
307 | |||
308 | it('Should not allow live if max instance lives is reached', async function () { | ||
309 | await server.config.updateCustomSubConfig({ | ||
310 | newConfig: { | ||
311 | live: { | ||
312 | enabled: true, | ||
313 | maxInstanceLives: 1 | ||
314 | } | ||
315 | } | ||
316 | }) | ||
317 | |||
318 | await makePostBodyRequest({ | ||
319 | url: server.url, | ||
320 | path, | ||
321 | token: server.accessToken, | ||
322 | fields: baseCorrectParams, | ||
323 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
324 | }) | ||
325 | }) | ||
326 | |||
327 | it('Should not allow live if max user lives is reached', async function () { | ||
328 | await server.config.updateCustomSubConfig({ | ||
329 | newConfig: { | ||
330 | live: { | ||
331 | enabled: true, | ||
332 | maxInstanceLives: 20, | ||
333 | maxUserLives: 1 | ||
334 | } | ||
335 | } | ||
336 | }) | ||
337 | |||
338 | await makePostBodyRequest({ | ||
339 | url: server.url, | ||
340 | path, | ||
341 | token: server.accessToken, | ||
342 | fields: baseCorrectParams, | ||
343 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
344 | }) | ||
345 | }) | ||
346 | }) | ||
347 | |||
348 | describe('When getting live information', function () { | ||
349 | |||
350 | it('Should fail with a bad access token', async function () { | ||
351 | await command.get({ token: 'toto', videoId: video.id, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
352 | }) | ||
353 | |||
354 | it('Should not display private information without access token', async function () { | ||
355 | const live = await command.get({ token: '', videoId: video.id }) | ||
356 | |||
357 | expect(live.rtmpUrl).to.not.exist | ||
358 | expect(live.streamKey).to.not.exist | ||
359 | expect(live.latencyMode).to.exist | ||
360 | }) | ||
361 | |||
362 | it('Should not display private information with token of another user', async function () { | ||
363 | const live = await command.get({ token: userAccessToken, videoId: video.id }) | ||
364 | |||
365 | expect(live.rtmpUrl).to.not.exist | ||
366 | expect(live.streamKey).to.not.exist | ||
367 | expect(live.latencyMode).to.exist | ||
368 | }) | ||
369 | |||
370 | it('Should display private information with appropriate token', async function () { | ||
371 | const live = await command.get({ videoId: video.id }) | ||
372 | |||
373 | expect(live.rtmpUrl).to.exist | ||
374 | expect(live.streamKey).to.exist | ||
375 | expect(live.latencyMode).to.exist | ||
376 | }) | ||
377 | |||
378 | it('Should fail with a bad video id', async function () { | ||
379 | await command.get({ videoId: 'toto', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
380 | }) | ||
381 | |||
382 | it('Should fail with an unknown video id', async function () { | ||
383 | await command.get({ videoId: 454555, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
384 | }) | ||
385 | |||
386 | it('Should fail with a non live video', async function () { | ||
387 | await command.get({ videoId: videoIdNotLive, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
388 | }) | ||
389 | |||
390 | it('Should succeed with the correct params', async function () { | ||
391 | await command.get({ videoId: video.id }) | ||
392 | await command.get({ videoId: video.uuid }) | ||
393 | await command.get({ videoId: video.shortUUID }) | ||
394 | }) | ||
395 | }) | ||
396 | |||
397 | describe('When getting live sessions', function () { | ||
398 | |||
399 | it('Should fail with a bad access token', async function () { | ||
400 | await command.listSessions({ token: 'toto', videoId: video.id, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
401 | }) | ||
402 | |||
403 | it('Should fail without token', async function () { | ||
404 | await command.listSessions({ token: null, videoId: video.id, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
405 | }) | ||
406 | |||
407 | it('Should fail with the token of another user', async function () { | ||
408 | await command.listSessions({ token: userAccessToken, videoId: video.id, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
409 | }) | ||
410 | |||
411 | it('Should fail with a bad video id', async function () { | ||
412 | await command.listSessions({ videoId: 'toto', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
413 | }) | ||
414 | |||
415 | it('Should fail with an unknown video id', async function () { | ||
416 | await command.listSessions({ videoId: 454555, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
417 | }) | ||
418 | |||
419 | it('Should fail with a non live video', async function () { | ||
420 | await command.listSessions({ videoId: videoIdNotLive, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
421 | }) | ||
422 | |||
423 | it('Should succeed with the correct params', async function () { | ||
424 | await command.listSessions({ videoId: video.id }) | ||
425 | }) | ||
426 | }) | ||
427 | |||
428 | describe('When getting live session of a replay', function () { | ||
429 | |||
430 | it('Should fail with a bad video id', async function () { | ||
431 | await command.getReplaySession({ videoId: 'toto', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
432 | }) | ||
433 | |||
434 | it('Should fail with an unknown video id', async function () { | ||
435 | await command.getReplaySession({ videoId: 454555, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
436 | }) | ||
437 | |||
438 | it('Should fail with a non replay video', async function () { | ||
439 | await command.getReplaySession({ videoId: videoIdNotLive, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
440 | }) | ||
441 | }) | ||
442 | |||
443 | describe('When updating live information', async function () { | ||
444 | |||
445 | it('Should fail without access token', async function () { | ||
446 | await command.update({ token: '', videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
447 | }) | ||
448 | |||
449 | it('Should fail with a bad access token', async function () { | ||
450 | await command.update({ token: 'toto', videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
451 | }) | ||
452 | |||
453 | it('Should fail with access token of another user', async function () { | ||
454 | await command.update({ token: userAccessToken, videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
455 | }) | ||
456 | |||
457 | it('Should fail with a bad video id', async function () { | ||
458 | await command.update({ videoId: 'toto', fields: {}, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
459 | }) | ||
460 | |||
461 | it('Should fail with an unknown video id', async function () { | ||
462 | await command.update({ videoId: 454555, fields: {}, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
463 | }) | ||
464 | |||
465 | it('Should fail with a non live video', async function () { | ||
466 | await command.update({ videoId: videoIdNotLive, fields: {}, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
467 | }) | ||
468 | |||
469 | it('Should fail with bad latency setting', async function () { | ||
470 | const fields = { latencyMode: 42 as any } | ||
471 | |||
472 | await command.update({ videoId: video.id, fields, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
473 | }) | ||
474 | |||
475 | it('Should fail with a bad privacy for replay settings', async function () { | ||
476 | const fields = { saveReplay: true, replaySettings: { privacy: 999 as any } } | ||
477 | |||
478 | await command.update({ videoId: video.id, fields, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
479 | }) | ||
480 | |||
481 | it('Should fail with save replay enabled but without replay settings', async function () { | ||
482 | await server.config.updateCustomSubConfig({ | ||
483 | newConfig: { | ||
484 | live: { | ||
485 | enabled: true, | ||
486 | allowReplay: true | ||
487 | } | ||
488 | } | ||
489 | }) | ||
490 | |||
491 | const fields = { saveReplay: true } | ||
492 | |||
493 | await command.update({ videoId: video.id, fields, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
494 | }) | ||
495 | |||
496 | it('Should fail with save replay disabled and replay settings', async function () { | ||
497 | const fields = { saveReplay: false, replaySettings: { privacy: VideoPrivacy.INTERNAL } } | ||
498 | |||
499 | await command.update({ videoId: video.id, fields, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
500 | }) | ||
501 | |||
502 | it('Should fail with only replay settings when save replay is disabled', async function () { | ||
503 | const fields = { replaySettings: { privacy: VideoPrivacy.INTERNAL } } | ||
504 | |||
505 | await command.update({ videoId: video.id, fields, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
506 | }) | ||
507 | |||
508 | it('Should fail to set latency if the server does not allow it', async function () { | ||
509 | const fields = { latencyMode: LiveVideoLatencyMode.HIGH_LATENCY } | ||
510 | |||
511 | await command.update({ videoId: video.id, fields, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
512 | }) | ||
513 | |||
514 | it('Should succeed with the correct params', async function () { | ||
515 | await command.update({ videoId: video.id, fields: { saveReplay: false } }) | ||
516 | await command.update({ videoId: video.uuid, fields: { saveReplay: false } }) | ||
517 | await command.update({ videoId: video.shortUUID, fields: { saveReplay: false } }) | ||
518 | |||
519 | await command.update({ videoId: video.id, fields: { saveReplay: true, replaySettings: { privacy: VideoPrivacy.PUBLIC } } }) | ||
520 | |||
521 | }) | ||
522 | |||
523 | it('Should fail to update replay status if replay is not allowed on the instance', async function () { | ||
524 | await server.config.updateCustomSubConfig({ | ||
525 | newConfig: { | ||
526 | live: { | ||
527 | enabled: true, | ||
528 | allowReplay: false | ||
529 | } | ||
530 | } | ||
531 | }) | ||
532 | |||
533 | await command.update({ videoId: video.id, fields: { saveReplay: true }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
534 | }) | ||
535 | |||
536 | it('Should fail to update a live if it has already started', async function () { | ||
537 | this.timeout(40000) | ||
538 | |||
539 | const live = await command.get({ videoId: video.id }) | ||
540 | |||
541 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: live.rtmpUrl, streamKey: live.streamKey }) | ||
542 | |||
543 | await command.waitUntilPublished({ videoId: video.id }) | ||
544 | await command.update({ videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
545 | |||
546 | await stopFfmpeg(ffmpegCommand) | ||
547 | }) | ||
548 | |||
549 | it('Should fail to change live privacy if it has already started', async function () { | ||
550 | this.timeout(40000) | ||
551 | |||
552 | const live = await command.get({ videoId: video.id }) | ||
553 | |||
554 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: live.rtmpUrl, streamKey: live.streamKey }) | ||
555 | |||
556 | await command.waitUntilPublished({ videoId: video.id }) | ||
557 | |||
558 | await server.videos.update({ | ||
559 | id: video.id, | ||
560 | attributes: { privacy: VideoPrivacy.PUBLIC } // Same privacy, it's fine | ||
561 | }) | ||
562 | |||
563 | await server.videos.update({ | ||
564 | id: video.id, | ||
565 | attributes: { privacy: VideoPrivacy.UNLISTED }, | ||
566 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
567 | }) | ||
568 | |||
569 | await stopFfmpeg(ffmpegCommand) | ||
570 | }) | ||
571 | |||
572 | it('Should fail to stream twice in the save live', async function () { | ||
573 | this.timeout(40000) | ||
574 | |||
575 | const live = await command.get({ videoId: video.id }) | ||
576 | |||
577 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: live.rtmpUrl, streamKey: live.streamKey }) | ||
578 | |||
579 | await command.waitUntilPublished({ videoId: video.id }) | ||
580 | |||
581 | await command.runAndTestStreamError({ videoId: video.id, shouldHaveError: true }) | ||
582 | |||
583 | await stopFfmpeg(ffmpegCommand) | ||
584 | }) | ||
585 | }) | ||
586 | |||
587 | after(async function () { | ||
588 | await cleanupTests([ server ]) | ||
589 | }) | ||
590 | }) | ||