aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/tests/src/api/videos/single-server.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-07-31 14:34:36 +0200
committerChocobozzz <me@florianbigard.com>2023-08-11 15:02:33 +0200
commit3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch)
treee4510b39bdac9c318fdb4b47018d08f15368b8f0 /packages/tests/src/api/videos/single-server.ts
parent04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff)
downloadPeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip
Migrate server to ESM
Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports)
Diffstat (limited to 'packages/tests/src/api/videos/single-server.ts')
-rw-r--r--packages/tests/src/api/videos/single-server.ts461
1 files changed, 461 insertions, 0 deletions
diff --git a/packages/tests/src/api/videos/single-server.ts b/packages/tests/src/api/videos/single-server.ts
new file mode 100644
index 000000000..b87192a57
--- /dev/null
+++ b/packages/tests/src/api/videos/single-server.ts
@@ -0,0 +1,461 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { wait } from '@peertube/peertube-core-utils'
5import { Video, VideoPrivacy } from '@peertube/peertube-models'
6import { checkVideoFilesWereRemoved, completeVideoCheck } from '@tests/shared/videos.js'
7import { testImageGeneratedByFFmpeg } from '@tests/shared/checks.js'
8import {
9 cleanupTests,
10 createSingleServer,
11 PeerTubeServer,
12 setAccessTokensToServers,
13 setDefaultAccountAvatar,
14 setDefaultChannelAvatar,
15 waitJobs
16} from '@peertube/peertube-server-commands'
17
18describe('Test a single server', function () {
19
20 function runSuite (mode: 'legacy' | 'resumable') {
21 let server: PeerTubeServer = null
22 let videoId: number | string
23 let videoId2: string
24 let videoUUID = ''
25 let videosListBase: any[] = null
26
27 const getCheckAttributes = () => ({
28 name: 'my super name',
29 category: 2,
30 licence: 6,
31 language: 'zh',
32 nsfw: true,
33 description: 'my super description',
34 support: 'my super support text',
35 account: {
36 name: 'root',
37 host: server.host
38 },
39 isLocal: true,
40 duration: 5,
41 tags: [ 'tag1', 'tag2', 'tag3' ],
42 privacy: VideoPrivacy.PUBLIC,
43 commentsEnabled: true,
44 downloadEnabled: true,
45 channel: {
46 displayName: 'Main root channel',
47 name: 'root_channel',
48 description: '',
49 isLocal: true
50 },
51 fixture: 'video_short.webm',
52 files: [
53 {
54 resolution: 720,
55 size: 218910
56 }
57 ]
58 })
59
60 const updateCheckAttributes = () => ({
61 name: 'my super video updated',
62 category: 4,
63 licence: 2,
64 language: 'ar',
65 nsfw: false,
66 description: 'my super description updated',
67 support: 'my super support text updated',
68 account: {
69 name: 'root',
70 host: server.host
71 },
72 isLocal: true,
73 tags: [ 'tagup1', 'tagup2' ],
74 privacy: VideoPrivacy.PUBLIC,
75 duration: 5,
76 commentsEnabled: false,
77 downloadEnabled: false,
78 channel: {
79 name: 'root_channel',
80 displayName: 'Main root channel',
81 description: '',
82 isLocal: true
83 },
84 fixture: 'video_short3.webm',
85 files: [
86 {
87 resolution: 720,
88 size: 292677
89 }
90 ]
91 })
92
93 before(async function () {
94 this.timeout(30000)
95
96 server = await createSingleServer(1, {})
97
98 await setAccessTokensToServers([ server ])
99 await setDefaultChannelAvatar(server)
100 await setDefaultAccountAvatar(server)
101 })
102
103 it('Should list video categories', async function () {
104 const categories = await server.videos.getCategories()
105 expect(Object.keys(categories)).to.have.length.above(10)
106
107 expect(categories[11]).to.equal('News & Politics')
108 })
109
110 it('Should list video licences', async function () {
111 const licences = await server.videos.getLicences()
112 expect(Object.keys(licences)).to.have.length.above(5)
113
114 expect(licences[3]).to.equal('Attribution - No Derivatives')
115 })
116
117 it('Should list video languages', async function () {
118 const languages = await server.videos.getLanguages()
119 expect(Object.keys(languages)).to.have.length.above(5)
120
121 expect(languages['ru']).to.equal('Russian')
122 })
123
124 it('Should list video privacies', async function () {
125 const privacies = await server.videos.getPrivacies()
126 expect(Object.keys(privacies)).to.have.length.at.least(3)
127
128 expect(privacies[3]).to.equal('Private')
129 })
130
131 it('Should not have videos', async function () {
132 const { data, total } = await server.videos.list()
133
134 expect(total).to.equal(0)
135 expect(data).to.be.an('array')
136 expect(data.length).to.equal(0)
137 })
138
139 it('Should upload the video', async function () {
140 const attributes = {
141 name: 'my super name',
142 category: 2,
143 nsfw: true,
144 licence: 6,
145 tags: [ 'tag1', 'tag2', 'tag3' ]
146 }
147 const video = await server.videos.upload({ attributes, mode })
148 expect(video).to.not.be.undefined
149 expect(video.id).to.equal(1)
150 expect(video.uuid).to.have.length.above(5)
151
152 videoId = video.id
153 videoUUID = video.uuid
154 })
155
156 it('Should get and seed the uploaded video', async function () {
157 this.timeout(5000)
158
159 const { data, total } = await server.videos.list()
160
161 expect(total).to.equal(1)
162 expect(data).to.be.an('array')
163 expect(data.length).to.equal(1)
164
165 const video = data[0]
166 await completeVideoCheck({ server, originServer: server, videoUUID: video.uuid, attributes: getCheckAttributes() })
167 })
168
169 it('Should get the video by UUID', async function () {
170 this.timeout(5000)
171
172 const video = await server.videos.get({ id: videoUUID })
173 await completeVideoCheck({ server, originServer: server, videoUUID: video.uuid, attributes: getCheckAttributes() })
174 })
175
176 it('Should have the views updated', async function () {
177 this.timeout(20000)
178
179 await server.views.simulateView({ id: videoId })
180 await server.views.simulateView({ id: videoId })
181 await server.views.simulateView({ id: videoId })
182
183 await wait(1500)
184
185 await server.views.simulateView({ id: videoId })
186 await server.views.simulateView({ id: videoId })
187
188 await wait(1500)
189
190 await server.views.simulateView({ id: videoId })
191 await server.views.simulateView({ id: videoId })
192
193 await server.debug.sendCommand({ body: { command: 'process-video-views-buffer' } })
194
195 const video = await server.videos.get({ id: videoId })
196 expect(video.views).to.equal(3)
197 })
198
199 it('Should remove the video', async function () {
200 const video = await server.videos.get({ id: videoId })
201 await server.videos.remove({ id: videoId })
202
203 await checkVideoFilesWereRemoved({ video, server })
204 })
205
206 it('Should not have videos', async function () {
207 const { total, data } = await server.videos.list()
208
209 expect(total).to.equal(0)
210 expect(data).to.be.an('array')
211 expect(data).to.have.lengthOf(0)
212 })
213
214 it('Should upload 6 videos', async function () {
215 this.timeout(120000)
216
217 const videos = new Set([
218 'video_short.mp4', 'video_short.ogv', 'video_short.webm',
219 'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
220 ])
221
222 for (const video of videos) {
223 const attributes = {
224 name: video + ' name',
225 description: video + ' description',
226 category: 2,
227 licence: 1,
228 language: 'en',
229 nsfw: true,
230 tags: [ 'tag1', 'tag2', 'tag3' ],
231 fixture: video
232 }
233
234 await server.videos.upload({ attributes, mode })
235 }
236 })
237
238 it('Should have the correct durations', async function () {
239 const { total, data } = await server.videos.list()
240
241 expect(total).to.equal(6)
242 expect(data).to.be.an('array')
243 expect(data).to.have.lengthOf(6)
244
245 const videosByName: { [ name: string ]: Video } = {}
246 data.forEach(v => { videosByName[v.name] = v })
247
248 expect(videosByName['video_short.mp4 name'].duration).to.equal(5)
249 expect(videosByName['video_short.ogv name'].duration).to.equal(5)
250 expect(videosByName['video_short.webm name'].duration).to.equal(5)
251 expect(videosByName['video_short1.webm name'].duration).to.equal(10)
252 expect(videosByName['video_short2.webm name'].duration).to.equal(5)
253 expect(videosByName['video_short3.webm name'].duration).to.equal(5)
254 })
255
256 it('Should have the correct thumbnails', async function () {
257 const { data } = await server.videos.list()
258
259 // For the next test
260 videosListBase = data
261
262 for (const video of data) {
263 const videoName = video.name.replace(' name', '')
264 await testImageGeneratedByFFmpeg(server.url, videoName, video.thumbnailPath)
265 }
266 })
267
268 it('Should list only the two first videos', async function () {
269 const { total, data } = await server.videos.list({ start: 0, count: 2, sort: 'name' })
270
271 expect(total).to.equal(6)
272 expect(data.length).to.equal(2)
273 expect(data[0].name).to.equal(videosListBase[0].name)
274 expect(data[1].name).to.equal(videosListBase[1].name)
275 })
276
277 it('Should list only the next three videos', async function () {
278 const { total, data } = await server.videos.list({ start: 2, count: 3, sort: 'name' })
279
280 expect(total).to.equal(6)
281 expect(data.length).to.equal(3)
282 expect(data[0].name).to.equal(videosListBase[2].name)
283 expect(data[1].name).to.equal(videosListBase[3].name)
284 expect(data[2].name).to.equal(videosListBase[4].name)
285 })
286
287 it('Should list the last video', async function () {
288 const { total, data } = await server.videos.list({ start: 5, count: 6, sort: 'name' })
289
290 expect(total).to.equal(6)
291 expect(data.length).to.equal(1)
292 expect(data[0].name).to.equal(videosListBase[5].name)
293 })
294
295 it('Should not have the total field', async function () {
296 const { total, data } = await server.videos.list({ start: 5, count: 6, sort: 'name', skipCount: true })
297
298 expect(total).to.not.exist
299 expect(data.length).to.equal(1)
300 expect(data[0].name).to.equal(videosListBase[5].name)
301 })
302
303 it('Should list and sort by name in descending order', async function () {
304 const { total, data } = await server.videos.list({ sort: '-name' })
305
306 expect(total).to.equal(6)
307 expect(data.length).to.equal(6)
308 expect(data[0].name).to.equal('video_short.webm name')
309 expect(data[1].name).to.equal('video_short.ogv name')
310 expect(data[2].name).to.equal('video_short.mp4 name')
311 expect(data[3].name).to.equal('video_short3.webm name')
312 expect(data[4].name).to.equal('video_short2.webm name')
313 expect(data[5].name).to.equal('video_short1.webm name')
314
315 videoId = data[3].uuid
316 videoId2 = data[5].uuid
317 })
318
319 it('Should list and sort by trending in descending order', async function () {
320 const { total, data } = await server.videos.list({ start: 0, count: 2, sort: '-trending' })
321
322 expect(total).to.equal(6)
323 expect(data.length).to.equal(2)
324 })
325
326 it('Should list and sort by hotness in descending order', async function () {
327 const { total, data } = await server.videos.list({ start: 0, count: 2, sort: '-hot' })
328
329 expect(total).to.equal(6)
330 expect(data.length).to.equal(2)
331 })
332
333 it('Should list and sort by best in descending order', async function () {
334 const { total, data } = await server.videos.list({ start: 0, count: 2, sort: '-best' })
335
336 expect(total).to.equal(6)
337 expect(data.length).to.equal(2)
338 })
339
340 it('Should update a video', async function () {
341 const attributes = {
342 name: 'my super video updated',
343 category: 4,
344 licence: 2,
345 language: 'ar',
346 nsfw: false,
347 description: 'my super description updated',
348 commentsEnabled: false,
349 downloadEnabled: false,
350 tags: [ 'tagup1', 'tagup2' ]
351 }
352 await server.videos.update({ id: videoId, attributes })
353 })
354
355 it('Should have the video updated', async function () {
356 this.timeout(60000)
357
358 await waitJobs([ server ])
359
360 const video = await server.videos.get({ id: videoId })
361
362 await completeVideoCheck({ server, originServer: server, videoUUID: video.uuid, attributes: updateCheckAttributes() })
363 })
364
365 it('Should update only the tags of a video', async function () {
366 const attributes = {
367 tags: [ 'supertag', 'tag1', 'tag2' ]
368 }
369 await server.videos.update({ id: videoId, attributes })
370
371 const video = await server.videos.get({ id: videoId })
372
373 await completeVideoCheck({
374 server,
375 originServer: server,
376 videoUUID: video.uuid,
377 attributes: Object.assign(updateCheckAttributes(), attributes)
378 })
379 })
380
381 it('Should update only the description of a video', async function () {
382 const attributes = {
383 description: 'hello everybody'
384 }
385 await server.videos.update({ id: videoId, attributes })
386
387 const video = await server.videos.get({ id: videoId })
388
389 await completeVideoCheck({
390 server,
391 originServer: server,
392 videoUUID: video.uuid,
393 attributes: Object.assign(updateCheckAttributes(), { tags: [ 'supertag', 'tag1', 'tag2' ] }, attributes)
394 })
395 })
396
397 it('Should like a video', async function () {
398 await server.videos.rate({ id: videoId, rating: 'like' })
399
400 const video = await server.videos.get({ id: videoId })
401
402 expect(video.likes).to.equal(1)
403 expect(video.dislikes).to.equal(0)
404 })
405
406 it('Should dislike the same video', async function () {
407 await server.videos.rate({ id: videoId, rating: 'dislike' })
408
409 const video = await server.videos.get({ id: videoId })
410
411 expect(video.likes).to.equal(0)
412 expect(video.dislikes).to.equal(1)
413 })
414
415 it('Should sort by originallyPublishedAt', async function () {
416 {
417 const now = new Date()
418 const attributes = { originallyPublishedAt: now.toISOString() }
419 await server.videos.update({ id: videoId, attributes })
420
421 const { data } = await server.videos.list({ sort: '-originallyPublishedAt' })
422 const names = data.map(v => v.name)
423
424 expect(names[0]).to.equal('my super video updated')
425 expect(names[1]).to.equal('video_short2.webm name')
426 expect(names[2]).to.equal('video_short1.webm name')
427 expect(names[3]).to.equal('video_short.webm name')
428 expect(names[4]).to.equal('video_short.ogv name')
429 expect(names[5]).to.equal('video_short.mp4 name')
430 }
431
432 {
433 const now = new Date()
434 const attributes = { originallyPublishedAt: now.toISOString() }
435 await server.videos.update({ id: videoId2, attributes })
436
437 const { data } = await server.videos.list({ sort: '-originallyPublishedAt' })
438 const names = data.map(v => v.name)
439
440 expect(names[0]).to.equal('video_short1.webm name')
441 expect(names[1]).to.equal('my super video updated')
442 expect(names[2]).to.equal('video_short2.webm name')
443 expect(names[3]).to.equal('video_short.webm name')
444 expect(names[4]).to.equal('video_short.ogv name')
445 expect(names[5]).to.equal('video_short.mp4 name')
446 }
447 })
448
449 after(async function () {
450 await cleanupTests([ server ])
451 })
452 }
453
454 describe('Legacy upload', function () {
455 runSuite('legacy')
456 })
457
458 describe('Resumable upload', function () {
459 runSuite('resumable')
460 })
461})