]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/check-params/live.ts
Introduce config command
[github/Chocobozzz/PeerTube.git] / server / tests / api / check-params / live.ts
CommitLineData
77e9f859
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import 'mocha'
77e9f859 4import { omit } from 'lodash'
d4a8e7a6 5import { LiveVideo, VideoCreateResult, VideoPrivacy } from '@shared/models'
3d470a53 6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
77e9f859 7import {
3d470a53 8 buildAbsoluteFixturePath,
77e9f859
C
9 cleanupTests,
10 createUser,
11 flushAndRunServer,
12 getLive,
13 getMyUserInformation,
14 immutableAssign,
15 makePostBodyRequest,
16 makeUploadRequest,
68e70a74 17 runAndTestFfmpegStreamError,
77e9f859
C
18 sendRTMPStream,
19 ServerInfo,
20 setAccessTokensToServers,
21 stopFfmpeg,
77e9f859
C
22 updateLive,
23 uploadVideoAndGetId,
24 userLogin,
0d8de275 25 waitUntilLivePublished
77e9f859
C
26} from '../../../../shared/extra-utils'
27
28describe('Test video lives API validator', function () {
29 const path = '/api/v1/videos/live'
30 let server: ServerInfo
31 let userAccessToken = ''
77e9f859 32 let channelId: number
d4a8e7a6 33 let video: VideoCreateResult
77e9f859
C
34 let videoIdNotLive: number
35
36 // ---------------------------------------------------------------
37
38 before(async function () {
39 this.timeout(30000)
40
41 server = await flushAndRunServer(1)
42
43 await setAccessTokensToServers([ server ])
44
65e6e260
C
45 await server.configCommand.updateCustomSubConfig({
46 newConfig: {
47 live: {
48 enabled: true,
49 maxInstanceLives: 20,
50 maxUserLives: 20,
51 allowReplay: true
52 }
77e9f859
C
53 }
54 })
55
56 const username = 'user1'
57 const password = 'my super password'
58 await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password })
59 userAccessToken = await userLogin(server, { username, password })
60
61 {
62 const res = await getMyUserInformation(server.url, server.accessToken)
63 channelId = res.body.videoChannels[0].id
64 }
65
66 {
67 videoIdNotLive = (await uploadVideoAndGetId({ server, videoName: 'not live' })).id
68 }
69 })
70
71 describe('When creating a live', function () {
72 let baseCorrectParams
73
74 before(function () {
75 baseCorrectParams = {
76 name: 'my super name',
77 category: 5,
78 licence: 1,
79 language: 'pt',
80 nsfw: false,
81 commentsEnabled: true,
82 downloadEnabled: true,
83 waitTranscoding: true,
84 description: 'my super description',
85 support: 'my super support text',
86 tags: [ 'tag1', 'tag2' ],
87 privacy: VideoPrivacy.PUBLIC,
88 channelId,
bb4ba6d9
C
89 saveReplay: false,
90 permanentLive: false
77e9f859
C
91 }
92 })
93
94 it('Should fail with nothing', async function () {
95 const fields = {}
96 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
97 })
98
99 it('Should fail with a long name', async function () {
100 const fields = immutableAssign(baseCorrectParams, { name: 'super'.repeat(65) })
101
102 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
103 })
104
105 it('Should fail with a bad category', async function () {
106 const fields = immutableAssign(baseCorrectParams, { category: 125 })
107
108 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
109 })
110
111 it('Should fail with a bad licence', async function () {
112 const fields = immutableAssign(baseCorrectParams, { licence: 125 })
113
114 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
115 })
116
117 it('Should fail with a bad language', async function () {
118 const fields = immutableAssign(baseCorrectParams, { language: 'a'.repeat(15) })
119
120 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
121 })
122
123 it('Should fail with a long description', async function () {
124 const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) })
125
126 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
127 })
128
129 it('Should fail with a long support text', async function () {
130 const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(201) })
131
132 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
133 })
134
135 it('Should fail without a channel', async function () {
136 const fields = omit(baseCorrectParams, 'channelId')
137
138 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
139 })
140
141 it('Should fail with a bad channel', async function () {
142 const fields = immutableAssign(baseCorrectParams, { channelId: 545454 })
143
144 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
145 })
146
147 it('Should fail with another user channel', async function () {
148 const user = {
149 username: 'fake',
150 password: 'fake_password'
151 }
152 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
153
154 const accessTokenUser = await userLogin(server, user)
155 const res = await getMyUserInformation(server.url, accessTokenUser)
156 const customChannelId = res.body.videoChannels[0].id
157
158 const fields = immutableAssign(baseCorrectParams, { channelId: customChannelId })
159
160 await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields })
161 })
162
163 it('Should fail with too many tags', async function () {
164 const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ] })
165
166 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
167 })
168
169 it('Should fail with a tag length too low', async function () {
170 const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 't' ] })
171
172 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
173 })
174
175 it('Should fail with a tag length too big', async function () {
176 const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'my_super_tag_too_long_long_long_long_long_long' ] })
177
178 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
179 })
180
181 it('Should fail with an incorrect thumbnail file', async function () {
182 const fields = baseCorrectParams
183 const attaches = {
3d470a53 184 thumbnailfile: buildAbsoluteFixturePath('video_short.mp4')
77e9f859
C
185 }
186
187 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
188 })
189
190 it('Should fail with a big thumbnail file', async function () {
191 const fields = baseCorrectParams
192 const attaches = {
3d470a53 193 thumbnailfile: buildAbsoluteFixturePath('preview-big.png')
77e9f859
C
194 }
195
196 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
197 })
198
199 it('Should fail with an incorrect preview file', async function () {
200 const fields = baseCorrectParams
201 const attaches = {
3d470a53 202 previewfile: buildAbsoluteFixturePath('video_short.mp4')
77e9f859
C
203 }
204
205 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
206 })
207
208 it('Should fail with a big preview file', async function () {
209 const fields = baseCorrectParams
210 const attaches = {
3d470a53 211 previewfile: buildAbsoluteFixturePath('preview-big.png')
77e9f859
C
212 }
213
214 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
215 })
216
bb4ba6d9
C
217 it('Should fail with save replay and permanent live set to true', async function () {
218 const fields = immutableAssign(baseCorrectParams, { saveReplay: true, permanentLive: true })
219
220 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
221 })
222
77e9f859
C
223 it('Should succeed with the correct parameters', async function () {
224 this.timeout(30000)
225
226 const res = await makePostBodyRequest({
227 url: server.url,
228 path,
229 token: server.accessToken,
230 fields: baseCorrectParams,
2d53be02 231 statusCodeExpected: HttpStatusCode.OK_200
77e9f859
C
232 })
233
d4a8e7a6 234 video = res.body.video
77e9f859
C
235 })
236
237 it('Should forbid if live is disabled', async function () {
65e6e260
C
238 await server.configCommand.updateCustomSubConfig({
239 newConfig: {
240 live: {
241 enabled: false
242 }
77e9f859
C
243 }
244 })
245
246 await makePostBodyRequest({
247 url: server.url,
248 path,
249 token: server.accessToken,
250 fields: baseCorrectParams,
2d53be02 251 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
77e9f859
C
252 })
253 })
254
255 it('Should forbid to save replay if not enabled by the admin', async function () {
256 const fields = immutableAssign(baseCorrectParams, { saveReplay: true })
257
65e6e260
C
258 await server.configCommand.updateCustomSubConfig({
259 newConfig: {
260 live: {
261 enabled: true,
262 allowReplay: false
263 }
77e9f859
C
264 }
265 })
266
267 await makePostBodyRequest({
268 url: server.url,
269 path,
270 token: server.accessToken,
271 fields,
2d53be02 272 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
77e9f859
C
273 })
274 })
275
276 it('Should allow to save replay if enabled by the admin', async function () {
277 const fields = immutableAssign(baseCorrectParams, { saveReplay: true })
278
65e6e260
C
279 await server.configCommand.updateCustomSubConfig({
280 newConfig: {
281 live: {
282 enabled: true,
283 allowReplay: true
284 }
77e9f859
C
285 }
286 })
287
288 await makePostBodyRequest({
289 url: server.url,
290 path,
291 token: server.accessToken,
292 fields,
2d53be02 293 statusCodeExpected: HttpStatusCode.OK_200
77e9f859
C
294 })
295 })
296
297 it('Should not allow live if max instance lives is reached', async function () {
65e6e260
C
298 await server.configCommand.updateCustomSubConfig({
299 newConfig: {
300 live: {
301 enabled: true,
302 maxInstanceLives: 1
303 }
77e9f859
C
304 }
305 })
306
307 await makePostBodyRequest({
308 url: server.url,
309 path,
310 token: server.accessToken,
311 fields: baseCorrectParams,
2d53be02 312 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
77e9f859
C
313 })
314 })
315
316 it('Should not allow live if max user lives is reached', async function () {
65e6e260
C
317 await server.configCommand.updateCustomSubConfig({
318 newConfig: {
319 live: {
320 enabled: true,
321 maxInstanceLives: 20,
322 maxUserLives: 1
323 }
77e9f859
C
324 }
325 })
326
327 await makePostBodyRequest({
328 url: server.url,
329 path,
330 token: server.accessToken,
331 fields: baseCorrectParams,
2d53be02 332 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
77e9f859
C
333 })
334 })
335 })
336
337 describe('When getting live information', function () {
338
339 it('Should fail without access token', async function () {
d4a8e7a6 340 await getLive(server.url, '', video.id, HttpStatusCode.UNAUTHORIZED_401)
77e9f859
C
341 })
342
343 it('Should fail with a bad access token', async function () {
d4a8e7a6 344 await getLive(server.url, 'toto', video.id, HttpStatusCode.UNAUTHORIZED_401)
77e9f859
C
345 })
346
347 it('Should fail with access token of another user', async function () {
d4a8e7a6 348 await getLive(server.url, userAccessToken, video.id, HttpStatusCode.FORBIDDEN_403)
77e9f859
C
349 })
350
351 it('Should fail with a bad video id', async function () {
2d53be02 352 await getLive(server.url, server.accessToken, 'toto', HttpStatusCode.BAD_REQUEST_400)
77e9f859
C
353 })
354
355 it('Should fail with an unknown video id', async function () {
2d53be02 356 await getLive(server.url, server.accessToken, 454555, HttpStatusCode.NOT_FOUND_404)
77e9f859
C
357 })
358
359 it('Should fail with a non live video', async function () {
2d53be02 360 await getLive(server.url, server.accessToken, videoIdNotLive, HttpStatusCode.NOT_FOUND_404)
77e9f859
C
361 })
362
363 it('Should succeed with the correct params', async function () {
d4a8e7a6
C
364 await getLive(server.url, server.accessToken, video.id)
365 await getLive(server.url, server.accessToken, video.shortUUID)
77e9f859
C
366 })
367 })
368
369 describe('When updating live information', async function () {
370
371 it('Should fail without access token', async function () {
d4a8e7a6 372 await updateLive(server.url, '', video.id, {}, HttpStatusCode.UNAUTHORIZED_401)
77e9f859
C
373 })
374
375 it('Should fail with a bad access token', async function () {
d4a8e7a6 376 await updateLive(server.url, 'toto', video.id, {}, HttpStatusCode.UNAUTHORIZED_401)
77e9f859
C
377 })
378
379 it('Should fail with access token of another user', async function () {
d4a8e7a6 380 await updateLive(server.url, userAccessToken, video.id, {}, HttpStatusCode.FORBIDDEN_403)
77e9f859
C
381 })
382
383 it('Should fail with a bad video id', async function () {
2d53be02 384 await updateLive(server.url, server.accessToken, 'toto', {}, HttpStatusCode.BAD_REQUEST_400)
77e9f859
C
385 })
386
387 it('Should fail with an unknown video id', async function () {
2d53be02 388 await updateLive(server.url, server.accessToken, 454555, {}, HttpStatusCode.NOT_FOUND_404)
77e9f859
C
389 })
390
391 it('Should fail with a non live video', async function () {
2d53be02 392 await updateLive(server.url, server.accessToken, videoIdNotLive, {}, HttpStatusCode.NOT_FOUND_404)
77e9f859
C
393 })
394
bb4ba6d9
C
395 it('Should fail with save replay and permanent live set to true', async function () {
396 const fields = { saveReplay: true, permanentLive: true }
397
d4a8e7a6 398 await updateLive(server.url, server.accessToken, video.id, fields, HttpStatusCode.BAD_REQUEST_400)
bb4ba6d9
C
399 })
400
77e9f859 401 it('Should succeed with the correct params', async function () {
d4a8e7a6
C
402 await updateLive(server.url, server.accessToken, video.id, { saveReplay: false })
403 await updateLive(server.url, server.accessToken, video.shortUUID, { saveReplay: false })
77e9f859
C
404 })
405
406 it('Should fail to update replay status if replay is not allowed on the instance', async function () {
65e6e260
C
407 await server.configCommand.updateCustomSubConfig({
408 newConfig: {
409 live: {
410 enabled: true,
411 allowReplay: false
412 }
77e9f859
C
413 }
414 })
415
d4a8e7a6 416 await updateLive(server.url, server.accessToken, video.id, { saveReplay: true }, HttpStatusCode.FORBIDDEN_403)
77e9f859
C
417 })
418
419 it('Should fail to update a live if it has already started', async function () {
59fd824c 420 this.timeout(40000)
77e9f859 421
d4a8e7a6 422 const resLive = await getLive(server.url, server.accessToken, video.id)
77e9f859
C
423 const live: LiveVideo = resLive.body
424
425 const command = sendRTMPStream(live.rtmpUrl, live.streamKey)
426
d4a8e7a6
C
427 await waitUntilLivePublished(server.url, server.accessToken, video.id)
428 await updateLive(server.url, server.accessToken, video.id, {}, HttpStatusCode.BAD_REQUEST_400)
77e9f859
C
429
430 await stopFfmpeg(command)
431 })
97969c4e
C
432
433 it('Should fail to stream twice in the save live', async function () {
59fd824c 434 this.timeout(40000)
97969c4e 435
d4a8e7a6 436 const resLive = await getLive(server.url, server.accessToken, video.id)
97969c4e
C
437 const live: LiveVideo = resLive.body
438
439 const command = sendRTMPStream(live.rtmpUrl, live.streamKey)
440
d4a8e7a6 441 await waitUntilLivePublished(server.url, server.accessToken, video.id)
97969c4e 442
d4a8e7a6 443 await runAndTestFfmpegStreamError(server.url, server.accessToken, video.id, true)
97969c4e
C
444
445 await stopFfmpeg(command)
446 })
77e9f859
C
447 })
448
449 after(async function () {
450 await cleanupTests([ server ])
451 })
452})