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