]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/videos/single-server.ts
emit more specific status codes on video upload (#3423)
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / single-server.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import * as chai from 'chai'
4 import { keyBy } from 'lodash'
5 import 'mocha'
6 import { VideoPrivacy } from '../../../../shared/models/videos'
7 import {
8 checkVideoFilesWereRemoved,
9 cleanupTests,
10 completeVideoCheck,
11 flushAndRunServer,
12 getVideo,
13 getVideoCategories,
14 getVideoLanguages,
15 getVideoLicences,
16 getVideoPrivacies,
17 getVideosList,
18 getVideosListPagination,
19 getVideosListSort,
20 getVideosWithFilters,
21 rateVideo,
22 removeVideo,
23 ServerInfo,
24 setAccessTokensToServers,
25 testImage,
26 updateVideo,
27 uploadVideo,
28 viewVideo,
29 wait
30 } from '../../../../shared/extra-utils'
31
32 const expect = chai.expect
33
34 describe('Test a single server', function () {
35 let server: ServerInfo = null
36 let videoId = -1
37 let videoId2 = -1
38 let videoUUID = ''
39 let videosListBase: any[] = null
40
41 const getCheckAttributes = () => ({
42 name: 'my super name',
43 category: 2,
44 licence: 6,
45 language: 'zh',
46 nsfw: true,
47 description: 'my super description',
48 support: 'my super support text',
49 account: {
50 name: 'root',
51 host: 'localhost:' + server.port
52 },
53 isLocal: true,
54 duration: 5,
55 tags: [ 'tag1', 'tag2', 'tag3' ],
56 privacy: VideoPrivacy.PUBLIC,
57 commentsEnabled: true,
58 downloadEnabled: true,
59 channel: {
60 displayName: 'Main root channel',
61 name: 'root_channel',
62 description: '',
63 isLocal: true
64 },
65 fixture: 'video_short.webm',
66 files: [
67 {
68 resolution: 720,
69 size: 218910
70 }
71 ]
72 })
73
74 const updateCheckAttributes = () => ({
75 name: 'my super video updated',
76 category: 4,
77 licence: 2,
78 language: 'ar',
79 nsfw: false,
80 description: 'my super description updated',
81 support: 'my super support text updated',
82 account: {
83 name: 'root',
84 host: 'localhost:' + server.port
85 },
86 isLocal: true,
87 tags: [ 'tagup1', 'tagup2' ],
88 privacy: VideoPrivacy.PUBLIC,
89 duration: 5,
90 commentsEnabled: false,
91 downloadEnabled: false,
92 channel: {
93 name: 'root_channel',
94 displayName: 'Main root channel',
95 description: '',
96 isLocal: true
97 },
98 fixture: 'video_short3.webm',
99 files: [
100 {
101 resolution: 720,
102 size: 292677
103 }
104 ]
105 })
106
107 before(async function () {
108 this.timeout(30000)
109
110 server = await flushAndRunServer(1)
111
112 await setAccessTokensToServers([ server ])
113 })
114
115 it('Should list video categories', async function () {
116 const res = await getVideoCategories(server.url)
117
118 const categories = res.body
119 expect(Object.keys(categories)).to.have.length.above(10)
120
121 expect(categories[11]).to.equal('News & Politics')
122 })
123
124 it('Should list video licences', async function () {
125 const res = await getVideoLicences(server.url)
126
127 const licences = res.body
128 expect(Object.keys(licences)).to.have.length.above(5)
129
130 expect(licences[3]).to.equal('Attribution - No Derivatives')
131 })
132
133 it('Should list video languages', async function () {
134 const res = await getVideoLanguages(server.url)
135
136 const languages = res.body
137 expect(Object.keys(languages)).to.have.length.above(5)
138
139 expect(languages['ru']).to.equal('Russian')
140 })
141
142 it('Should list video privacies', async function () {
143 const res = await getVideoPrivacies(server.url)
144
145 const privacies = res.body
146 expect(Object.keys(privacies)).to.have.length.at.least(3)
147
148 expect(privacies[3]).to.equal('Private')
149 })
150
151 it('Should not have videos', async function () {
152 const res = await getVideosList(server.url)
153
154 expect(res.body.total).to.equal(0)
155 expect(res.body.data).to.be.an('array')
156 expect(res.body.data.length).to.equal(0)
157 })
158
159 it('Should upload the video', async function () {
160 this.timeout(10000)
161
162 const videoAttributes = {
163 name: 'my super name',
164 category: 2,
165 nsfw: true,
166 licence: 6,
167 tags: [ 'tag1', 'tag2', 'tag3' ]
168 }
169 const res = await uploadVideo(server.url, server.accessToken, videoAttributes)
170 expect(res.body.video).to.not.be.undefined
171 expect(res.body.video.id).to.equal(1)
172 expect(res.body.video.uuid).to.have.length.above(5)
173
174 videoId = res.body.video.id
175 videoUUID = res.body.video.uuid
176 })
177
178 it('Should get and seed the uploaded video', async function () {
179 this.timeout(5000)
180
181 const res = await getVideosList(server.url)
182
183 expect(res.body.total).to.equal(1)
184 expect(res.body.data).to.be.an('array')
185 expect(res.body.data.length).to.equal(1)
186
187 const video = res.body.data[0]
188 await completeVideoCheck(server.url, video, getCheckAttributes())
189 })
190
191 it('Should get the video by UUID', async function () {
192 this.timeout(5000)
193
194 const res = await getVideo(server.url, videoUUID)
195
196 const video = res.body
197 await completeVideoCheck(server.url, video, getCheckAttributes())
198 })
199
200 it('Should have the views updated', async function () {
201 this.timeout(20000)
202
203 await viewVideo(server.url, videoId)
204 await viewVideo(server.url, videoId)
205 await viewVideo(server.url, videoId)
206
207 await wait(1500)
208
209 await viewVideo(server.url, videoId)
210 await viewVideo(server.url, videoId)
211
212 await wait(1500)
213
214 await viewVideo(server.url, videoId)
215 await viewVideo(server.url, videoId)
216
217 // Wait the repeatable job
218 await wait(8000)
219
220 const res = await getVideo(server.url, videoId)
221
222 const video = res.body
223 expect(video.views).to.equal(3)
224 })
225
226 it('Should remove the video', async function () {
227 await removeVideo(server.url, server.accessToken, videoId)
228
229 await checkVideoFilesWereRemoved(videoUUID, 1)
230 })
231
232 it('Should not have videos', async function () {
233 const res = await getVideosList(server.url)
234
235 expect(res.body.total).to.equal(0)
236 expect(res.body.data).to.be.an('array')
237 expect(res.body.data).to.have.lengthOf(0)
238 })
239
240 it('Should upload 6 videos', async function () {
241 this.timeout(25000)
242
243 const videos = new Set([
244 'video_short.mp4', 'video_short.ogv', 'video_short.webm',
245 'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
246 ])
247
248 for (const video of videos) {
249 const videoAttributes = {
250 name: video + ' name',
251 description: video + ' description',
252 category: 2,
253 licence: 1,
254 language: 'en',
255 nsfw: true,
256 tags: [ 'tag1', 'tag2', 'tag3' ],
257 fixture: video
258 }
259
260 await uploadVideo(server.url, server.accessToken, videoAttributes)
261 }
262 })
263
264 it('Should have the correct durations', async function () {
265 const res = await getVideosList(server.url)
266
267 expect(res.body.total).to.equal(6)
268 const videos = res.body.data
269 expect(videos).to.be.an('array')
270 expect(videos).to.have.lengthOf(6)
271
272 const videosByName = keyBy<{ duration: number }>(videos, 'name')
273 expect(videosByName['video_short.mp4 name'].duration).to.equal(5)
274 expect(videosByName['video_short.ogv name'].duration).to.equal(5)
275 expect(videosByName['video_short.webm name'].duration).to.equal(5)
276 expect(videosByName['video_short1.webm name'].duration).to.equal(10)
277 expect(videosByName['video_short2.webm name'].duration).to.equal(5)
278 expect(videosByName['video_short3.webm name'].duration).to.equal(5)
279 })
280
281 it('Should have the correct thumbnails', async function () {
282 const res = await getVideosList(server.url)
283
284 const videos = res.body.data
285 // For the next test
286 videosListBase = videos
287
288 for (const video of videos) {
289 const videoName = video.name.replace(' name', '')
290 await testImage(server.url, videoName, video.thumbnailPath)
291 }
292 })
293
294 it('Should list only the two first videos', async function () {
295 const res = await getVideosListPagination(server.url, 0, 2, 'name')
296
297 const videos = res.body.data
298 expect(res.body.total).to.equal(6)
299 expect(videos.length).to.equal(2)
300 expect(videos[0].name).to.equal(videosListBase[0].name)
301 expect(videos[1].name).to.equal(videosListBase[1].name)
302 })
303
304 it('Should list only the next three videos', async function () {
305 const res = await getVideosListPagination(server.url, 2, 3, 'name')
306
307 const videos = res.body.data
308 expect(res.body.total).to.equal(6)
309 expect(videos.length).to.equal(3)
310 expect(videos[0].name).to.equal(videosListBase[2].name)
311 expect(videos[1].name).to.equal(videosListBase[3].name)
312 expect(videos[2].name).to.equal(videosListBase[4].name)
313 })
314
315 it('Should list the last video', async function () {
316 const res = await getVideosListPagination(server.url, 5, 6, 'name')
317
318 const videos = res.body.data
319 expect(res.body.total).to.equal(6)
320 expect(videos.length).to.equal(1)
321 expect(videos[0].name).to.equal(videosListBase[5].name)
322 })
323
324 it('Should not have the total field', async function () {
325 const res = await getVideosListPagination(server.url, 5, 6, 'name', true)
326
327 const videos = res.body.data
328 expect(res.body.total).to.not.exist
329 expect(videos.length).to.equal(1)
330 expect(videos[0].name).to.equal(videosListBase[5].name)
331 })
332
333 it('Should list and sort by name in descending order', async function () {
334 const res = await getVideosListSort(server.url, '-name')
335
336 const videos = res.body.data
337 expect(res.body.total).to.equal(6)
338 expect(videos.length).to.equal(6)
339 expect(videos[0].name).to.equal('video_short.webm name')
340 expect(videos[1].name).to.equal('video_short.ogv name')
341 expect(videos[2].name).to.equal('video_short.mp4 name')
342 expect(videos[3].name).to.equal('video_short3.webm name')
343 expect(videos[4].name).to.equal('video_short2.webm name')
344 expect(videos[5].name).to.equal('video_short1.webm name')
345
346 videoId = videos[3].uuid
347 videoId2 = videos[5].uuid
348 })
349
350 it('Should list and sort by trending in descending order', async function () {
351 const res = await getVideosListPagination(server.url, 0, 2, '-trending')
352
353 const videos = res.body.data
354 expect(res.body.total).to.equal(6)
355 expect(videos.length).to.equal(2)
356 })
357
358 it('Should update a video', async function () {
359 const attributes = {
360 name: 'my super video updated',
361 category: 4,
362 licence: 2,
363 language: 'ar',
364 nsfw: false,
365 description: 'my super description updated',
366 commentsEnabled: false,
367 downloadEnabled: false,
368 tags: [ 'tagup1', 'tagup2' ]
369 }
370 await updateVideo(server.url, server.accessToken, videoId, attributes)
371 })
372
373 it('Should filter by tags and category', async function () {
374 const res1 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: 4 })
375 expect(res1.body.total).to.equal(1)
376 expect(res1.body.data[0].name).to.equal('my super video updated')
377
378 const res2 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: 3 })
379 expect(res2.body.total).to.equal(0)
380 })
381
382 it('Should have the video updated', async function () {
383 this.timeout(60000)
384
385 const res = await getVideo(server.url, videoId)
386 const video = res.body
387
388 await completeVideoCheck(server.url, video, updateCheckAttributes())
389 })
390
391 it('Should update only the tags of a video', async function () {
392 const attributes = {
393 tags: [ 'supertag', 'tag1', 'tag2' ]
394 }
395 await updateVideo(server.url, server.accessToken, videoId, attributes)
396
397 const res = await getVideo(server.url, videoId)
398 const video = res.body
399
400 await completeVideoCheck(server.url, video, Object.assign(updateCheckAttributes(), attributes))
401 })
402
403 it('Should update only the description of a video', async function () {
404 const attributes = {
405 description: 'hello everybody'
406 }
407 await updateVideo(server.url, server.accessToken, videoId, attributes)
408
409 const res = await getVideo(server.url, videoId)
410 const video = res.body
411
412 const expectedAttributes = Object.assign(updateCheckAttributes(), { tags: [ 'supertag', 'tag1', 'tag2' ] }, attributes)
413 await completeVideoCheck(server.url, video, expectedAttributes)
414 })
415
416 it('Should like a video', async function () {
417 await rateVideo(server.url, server.accessToken, videoId, 'like')
418
419 const res = await getVideo(server.url, videoId)
420 const video = res.body
421
422 expect(video.likes).to.equal(1)
423 expect(video.dislikes).to.equal(0)
424 })
425
426 it('Should dislike the same video', async function () {
427 await rateVideo(server.url, server.accessToken, videoId, 'dislike')
428
429 const res = await getVideo(server.url, videoId)
430 const video = res.body
431
432 expect(video.likes).to.equal(0)
433 expect(video.dislikes).to.equal(1)
434 })
435
436 it('Should sort by originallyPublishedAt', async function () {
437 {
438
439 {
440 const now = new Date()
441 const attributes = { originallyPublishedAt: now.toISOString() }
442 await updateVideo(server.url, server.accessToken, videoId, attributes)
443
444 const res = await getVideosListSort(server.url, '-originallyPublishedAt')
445 const names = res.body.data.map(v => v.name)
446
447 expect(names[0]).to.equal('my super video updated')
448 expect(names[1]).to.equal('video_short2.webm name')
449 expect(names[2]).to.equal('video_short1.webm name')
450 expect(names[3]).to.equal('video_short.webm name')
451 expect(names[4]).to.equal('video_short.ogv name')
452 expect(names[5]).to.equal('video_short.mp4 name')
453 }
454
455 {
456 const now = new Date()
457 const attributes = { originallyPublishedAt: now.toISOString() }
458 await updateVideo(server.url, server.accessToken, videoId2, attributes)
459
460 const res = await getVideosListSort(server.url, '-originallyPublishedAt')
461 const names = res.body.data.map(v => v.name)
462
463 expect(names[0]).to.equal('video_short1.webm name')
464 expect(names[1]).to.equal('my super video updated')
465 expect(names[2]).to.equal('video_short2.webm name')
466 expect(names[3]).to.equal('video_short.webm name')
467 expect(names[4]).to.equal('video_short.ogv name')
468 expect(names[5]).to.equal('video_short.mp4 name')
469 }
470 }
471 })
472
473 after(async function () {
474 await cleanupTests([ server ])
475 })
476 })