From b31d72625dd32143a45277528b90bb67a881f249 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 5 May 2021 15:26:28 +0200 Subject: Plugin user.getAuthUser is now async So we can load the full user --- server/tests/fixtures/peertube-plugin-test-four/main.js | 5 +++-- server/tests/plugins/plugin-helpers.ts | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'server/tests') diff --git a/server/tests/fixtures/peertube-plugin-test-four/main.js b/server/tests/fixtures/peertube-plugin-test-four/main.js index 6ed0c20d2..b9b207b81 100644 --- a/server/tests/fixtures/peertube-plugin-test-four/main.js +++ b/server/tests/fixtures/peertube-plugin-test-four/main.js @@ -88,8 +88,8 @@ async function register ({ return res.json({ routerRoute }) }) - router.get('/user', (req, res) => { - const user = peertubeHelpers.user.getAuthUser(res) + router.get('/user', async (req, res) => { + const user = await peertubeHelpers.user.getAuthUser(res) if (!user) return res.sendStatus(404) const isAdmin = user.role === 0 @@ -98,6 +98,7 @@ async function register ({ return res.json({ username: user.username, + displayName: user.Account.name, isAdmin, isModerator, isUser diff --git a/server/tests/plugins/plugin-helpers.ts b/server/tests/plugins/plugin-helpers.ts index 20020ec41..f72de8229 100644 --- a/server/tests/plugins/plugin-helpers.ts +++ b/server/tests/plugins/plugin-helpers.ts @@ -133,6 +133,7 @@ describe('Test plugin helpers', function () { }) expect(res.body.username).to.equal('root') + expect(res.body.displayName).to.equal('root') expect(res.body.isAdmin).to.be.true expect(res.body.isModerator).to.be.false expect(res.body.isUser).to.be.false -- cgit v1.2.3 From a66c2e3252d6cca8958959966f42494ded564023 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 7 May 2021 08:59:59 +0200 Subject: Fix remote actor creation date --- server/tests/api/users/users-multiple-servers.ts | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'server/tests') diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts index dcd03879b..f60c66e4b 100644 --- a/server/tests/api/users/users-multiple-servers.ts +++ b/server/tests/api/users/users-multiple-servers.ts @@ -130,26 +130,32 @@ describe('Test users with multiple servers', function () { }) it('Should have updated my profile on other servers too', async function () { + let createdAt: string | Date + for (const server of servers) { const resAccounts = await getAccountsList(server.url, '-createdAt') - const rootServer1List = resAccounts.body.data.find(a => a.name === 'root' && a.host === 'localhost:' + servers[0].port) as Account - expect(rootServer1List).not.to.be.undefined + const resList = resAccounts.body.data.find(a => a.name === 'root' && a.host === 'localhost:' + servers[0].port) as Account + expect(resList).not.to.be.undefined + + const resAccount = await getAccount(server.url, resList.name + '@' + resList.host) + const account = resAccount.body as Account + + if (!createdAt) createdAt = account.createdAt - const resAccount = await getAccount(server.url, rootServer1List.name + '@' + rootServer1List.host) - const rootServer1Get = resAccount.body as Account - expect(rootServer1Get.name).to.equal('root') - expect(rootServer1Get.host).to.equal('localhost:' + servers[0].port) - expect(rootServer1Get.displayName).to.equal('my super display name') - expect(rootServer1Get.description).to.equal('my super description updated') + expect(account.name).to.equal('root') + expect(account.host).to.equal('localhost:' + servers[0].port) + expect(account.displayName).to.equal('my super display name') + expect(account.description).to.equal('my super description updated') + expect(createdAt).to.equal(account.createdAt) if (server.serverNumber === 1) { - expect(rootServer1Get.userId).to.be.a('number') + expect(account.userId).to.be.a('number') } else { - expect(rootServer1Get.userId).to.be.undefined + expect(account.userId).to.be.undefined } - await testImage(server.url, 'avatar2-resized', rootServer1Get.avatar.path, '.png') + await testImage(server.url, 'avatar2-resized', account.avatar.path, '.png') } }) -- cgit v1.2.3 From a1bb73f9b591686b2ddfeb3291f305dae9f7fc6c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 7 May 2021 11:53:46 +0200 Subject: Refactor a little bit live tests --- server/tests/api/live/live-constraints.ts | 70 ++++++++++--------------------- server/tests/api/live/live-permanent.ts | 21 ++-------- server/tests/api/live/live-save-replay.ts | 11 +---- 3 files changed, 27 insertions(+), 75 deletions(-) (limited to 'server/tests') diff --git a/server/tests/api/live/live-constraints.ts b/server/tests/api/live/live-constraints.ts index 5569e6066..cc635de33 100644 --- a/server/tests/api/live/live-constraints.ts +++ b/server/tests/api/live/live-constraints.ts @@ -2,15 +2,15 @@ import 'mocha' import * as chai from 'chai' -import { User, VideoDetails, VideoPrivacy } from '@shared/models' +import { VideoDetails, VideoPrivacy } from '@shared/models' import { checkLiveCleanup, cleanupTests, createLive, - createUser, doubleFollow, flushAndRunMultipleServers, - getMyUserInformation, + generateUser, + getCustomConfigResolutions, getVideo, runAndTestFfmpegStreamError, ServerInfo, @@ -18,7 +18,6 @@ import { setDefaultVideoChannel, updateCustomSubConfig, updateUser, - userLogin, wait, waitJobs, waitUntilLivePublished @@ -62,6 +61,16 @@ describe('Test live constraints', function () { } } + function updateQuota (options: { total: number, daily: number }) { + return updateUser({ + url: servers[0].url, + accessToken: servers[0].accessToken, + userId, + videoQuota: options.total, + videoQuotaDaily: options.daily + }) + } + before(async function () { this.timeout(120000) @@ -82,27 +91,12 @@ describe('Test live constraints', function () { }) { - const user = { username: 'user1', password: 'superpassword' } - const res = await createUser({ - url: servers[0].url, - accessToken: servers[0].accessToken, - username: user.username, - password: user.password - }) - userId = res.body.user.id - - userAccessToken = await userLogin(servers[0], user) - - const resMe = await getMyUserInformation(servers[0].url, userAccessToken) - userChannelId = (resMe.body as User).videoChannels[0].id - - await updateUser({ - url: servers[0].url, - userId, - accessToken: servers[0].accessToken, - videoQuota: 1, - videoQuotaDaily: -1 - }) + const res = await generateUser(servers[0], 'user1') + userId = res.userId + userChannelId = res.userChannelId + userAccessToken = res.token + + await updateQuota({ total: 1, daily: -1 }) } // Server 1 and server 2 follow each other @@ -137,13 +131,7 @@ describe('Test live constraints', function () { // Wait for user quota memoize cache invalidation await wait(5000) - await updateUser({ - url: servers[0].url, - userId, - accessToken: servers[0].accessToken, - videoQuota: -1, - videoQuotaDaily: 1 - }) + await updateQuota({ total: -1, daily: 1 }) const userVideoLiveoId = await createLiveWrapper(true) await runAndTestFfmpegStreamError(servers[0].url, userAccessToken, userVideoLiveoId, true) @@ -160,13 +148,7 @@ describe('Test live constraints', function () { // Wait for user quota memoize cache invalidation await wait(5000) - await updateUser({ - url: servers[0].url, - userId, - accessToken: servers[0].accessToken, - videoQuota: 10 * 1000 * 1000, - videoQuotaDaily: -1 - }) + await updateQuota({ total: 10 * 1000 * 1000, daily: -1 }) const userVideoLiveoId = await createLiveWrapper(true) await runAndTestFfmpegStreamError(servers[0].url, userAccessToken, userVideoLiveoId, false) @@ -182,15 +164,7 @@ describe('Test live constraints', function () { maxDuration: 1, transcoding: { enabled: true, - resolutions: { - '240p': true, - '360p': true, - '480p': true, - '720p': true, - '1080p': true, - '1440p': true, - '2160p': true - } + resolutions: getCustomConfigResolutions(true) } } }) diff --git a/server/tests/api/live/live-permanent.ts b/server/tests/api/live/live-permanent.ts index a5bda009f..d52e8c7e4 100644 --- a/server/tests/api/live/live-permanent.ts +++ b/server/tests/api/live/live-permanent.ts @@ -8,6 +8,7 @@ import { createLive, doubleFollow, flushAndRunMultipleServers, + getCustomConfigResolutions, getLive, getPlaylistsCount, getVideo, @@ -69,15 +70,7 @@ describe('Permenant live', function () { maxDuration: -1, transcoding: { enabled: true, - resolutions: { - '240p': true, - '360p': true, - '480p': true, - '720p': true, - '1080p': true, - '1440p': true, - '2160p': true - } + resolutions: getCustomConfigResolutions(true) } } }) @@ -159,15 +152,7 @@ describe('Permenant live', function () { maxDuration: -1, transcoding: { enabled: true, - resolutions: { - '240p': false, - '360p': false, - '480p': false, - '720p': false, - '1080p': false, - '1440p': false, - '2160p': false - } + resolutions: getCustomConfigResolutions(false) } } }) diff --git a/server/tests/api/live/live-save-replay.ts b/server/tests/api/live/live-save-replay.ts index 61c8e74dd..3d4736c8f 100644 --- a/server/tests/api/live/live-save-replay.ts +++ b/server/tests/api/live/live-save-replay.ts @@ -12,6 +12,7 @@ import { createLive, doubleFollow, flushAndRunMultipleServers, + getCustomConfigResolutions, getVideo, getVideosList, removeVideo, @@ -108,15 +109,7 @@ describe('Save replay setting', function () { maxDuration: -1, transcoding: { enabled: false, - resolutions: { - '240p': true, - '360p': true, - '480p': true, - '720p': true, - '1080p': true, - '1440p': true, - '2160p': true - } + resolutions: getCustomConfigResolutions(true) } } }) -- cgit v1.2.3 From 4076e2ef6b5337cc56caabb8d6cc5f94e60e9347 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 7 May 2021 15:17:43 +0200 Subject: Increase test timeout --- server/tests/plugins/filter-hooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/tests') diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index ac958c5f5..cf1dd0854 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts @@ -55,7 +55,7 @@ describe('Test plugin filter hooks', function () { let threadId: number before(async function () { - this.timeout(30000) + this.timeout(60000) servers = await flushAndRunMultipleServers(2) await setAccessTokensToServers(servers) -- cgit v1.2.3 From e024fd6a7494b37251da1d59470324305cdb4129 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 7 May 2021 17:14:39 +0200 Subject: Update channel updatedAt when uploading a video --- server/tests/api/videos/video-channels.ts | 82 +++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 25 deletions(-) (limited to 'server/tests') diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts index d12d58e75..7e7ad028c 100644 --- a/server/tests/api/videos/video-channels.ts +++ b/server/tests/api/videos/video-channels.ts @@ -3,6 +3,7 @@ import 'mocha' import * as chai from 'chai' import { basename } from 'path' +import { ACTOR_IMAGES_SIZE } from '@server/initializers/constants' import { cleanupTests, createUser, @@ -13,6 +14,7 @@ import { getVideo, getVideoChannel, getVideoChannelVideos, + setDefaultVideoChannel, testImage, updateVideo, updateVideoChannelImage, @@ -33,7 +35,6 @@ import { } from '../../../../shared/extra-utils/index' import { waitJobs } from '../../../../shared/extra-utils/server/jobs' import { User, Video, VideoChannel, VideoDetails } from '../../../../shared/index' -import { ACTOR_IMAGES_SIZE } from '@server/initializers/constants' const expect = chai.expect @@ -47,9 +48,10 @@ async function findChannel (server: ServerInfo, channelId: number) { describe('Test video channels', function () { let servers: ServerInfo[] let userInfo: User - let firstVideoChannelId: number let secondVideoChannelId: number + let totoChannel: number let videoUUID: string + let accountName: string before(async function () { this.timeout(60000) @@ -57,16 +59,9 @@ describe('Test video channels', function () { servers = await flushAndRunMultipleServers(2) await setAccessTokensToServers(servers) - await doubleFollow(servers[0], servers[1]) - - { - const res = await getMyUserInformation(servers[0].url, servers[0].accessToken) - const user: User = res.body - - firstVideoChannelId = user.videoChannels[0].id - } + await setDefaultVideoChannel(servers) - await waitJobs(servers) + await doubleFollow(servers[0], servers[1]) }) it('Should have one video channel (created with root)', async () => { @@ -116,12 +111,14 @@ describe('Test video channels', function () { expect(videoChannels[1].displayName).to.equal('second video channel') expect(videoChannels[1].description).to.equal('super video channel description') expect(videoChannels[1].support).to.equal('super video channel support text') + + accountName = userInfo.account.name + '@' + userInfo.account.host }) it('Should have two video channels when getting account channels on server 1', async function () { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host + accountName }) expect(res.body.total).to.equal(2) @@ -142,7 +139,7 @@ describe('Test video channels', function () { { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, start: 0, count: 1, sort: 'createdAt' @@ -158,7 +155,7 @@ describe('Test video channels', function () { { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, start: 0, count: 1, sort: '-createdAt' @@ -174,7 +171,7 @@ describe('Test video channels', function () { { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, start: 1, count: 1, sort: '-createdAt' @@ -191,7 +188,7 @@ describe('Test video channels', function () { it('Should have one video channel when getting account channels on server 2', async function () { const res = await getAccountVideoChannelsList({ url: servers[1].url, - accountName: userInfo.account.name + '@' + userInfo.account.host + accountName }) expect(res.body.total).to.equal(1) @@ -379,7 +376,7 @@ describe('Test video channels', function () { it('Should change the video channel of a video', async function () { this.timeout(10000) - await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { channelId: firstVideoChannelId }) + await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { channelId: servers[0].videoChannel.id }) await waitJobs(servers) }) @@ -419,7 +416,8 @@ describe('Test video channels', function () { it('Should create the main channel with an uuid if there is a conflict', async function () { { const videoChannel = { name: 'toto_channel', displayName: 'My toto channel' } - await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel) + const res = await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel) + totoChannel = res.body.videoChannel.id } { @@ -438,7 +436,7 @@ describe('Test video channels', function () { { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, withStats: true }) @@ -456,7 +454,7 @@ describe('Test video channels', function () { } { - // video has been posted on channel firstVideoChannelId since last update + // video has been posted on channel servers[0].videoChannel.id since last update await viewVideo(servers[0].url, videoUUID, 204, '0.0.0.1,127.0.0.1') await viewVideo(servers[0].url, videoUUID, 204, '0.0.0.2,127.0.0.1') @@ -465,10 +463,10 @@ describe('Test video channels', function () { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, withStats: true }) - const channelWithView = res.body.data.find((channel: VideoChannel) => channel.id === firstVideoChannelId) + const channelWithView = res.body.data.find((channel: VideoChannel) => channel.id === servers[0].videoChannel.id) expect(channelWithView.viewsPerDay.slice(-1)[0].views).to.equal(2) } }) @@ -476,7 +474,7 @@ describe('Test video channels', function () { it('Should report correct videos count', async function () { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, withStats: true }) const channels: VideoChannel[] = res.body.data @@ -492,7 +490,7 @@ describe('Test video channels', function () { { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, search: 'root' }) expect(res.body.total).to.equal(1) @@ -504,7 +502,7 @@ describe('Test video channels', function () { { const res = await getAccountVideoChannelsList({ url: servers[0].url, - accountName: userInfo.account.name + '@' + userInfo.account.host, + accountName, search: 'does not exist' }) expect(res.body.total).to.equal(0) @@ -514,6 +512,40 @@ describe('Test video channels', function () { } }) + it('Should list channels by updatedAt desc if a video has been uploaded', async function () { + this.timeout(30000) + + await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: totoChannel }) + await waitJobs(servers) + + for (const server of servers) { + const res = await getAccountVideoChannelsList({ + url: server.url, + accountName, + sort: '-updatedAt' + }) + + const channels: VideoChannel[] = res.body.data + expect(channels[0].name).to.equal('toto_channel') + expect(channels[1].name).to.equal('root_channel') + } + + await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: servers[0].videoChannel.id }) + await waitJobs(servers) + + for (const server of servers) { + const res = await getAccountVideoChannelsList({ + url: server.url, + accountName, + sort: '-updatedAt' + }) + + const channels: VideoChannel[] = res.body.data + expect(channels[0].name).to.equal('root_channel') + expect(channels[1].name).to.equal('toto_channel') + } + }) + after(async function () { await cleanupTests(servers) }) -- cgit v1.2.3 From f6d6e7f861189a4446f406efb775a29688764b48 Mon Sep 17 00:00:00 2001 From: kontrollanten <6680299+kontrollanten@users.noreply.github.com> Date: Mon, 10 May 2021 11:13:41 +0200 Subject: Resumable video uploads (#3933) * WIP: resumable video uploads relates to #324 * fix review comments * video upload: error handling * fix audio upload * fixes after self review * Update server/controllers/api/videos/index.ts Co-authored-by: Rigel Kent * Update server/middlewares/validators/videos/videos.ts Co-authored-by: Rigel Kent * Update server/controllers/api/videos/index.ts Co-authored-by: Rigel Kent * update after code review * refactor upload route - restore multipart upload route - move resumable to dedicated upload-resumable route - move checks to middleware - do not leak internal fs structure in response * fix yarn.lock upon rebase * factorize addVideo for reuse in both endpoints * add resumable upload API to openapi spec * add initial test and test helper for resumable upload * typings for videoAddResumable middleware * avoid including aws and google packages via node-uploadx, by only including uploadx/core * rename ex-isAudioBg to more explicit name mentioning it is a preview file for audio * add video-upload-tmp-folder-cleaner job * stronger typing of video upload middleware * reduce dependency to @uploadx/core * add audio upload test * refactor resumable uploads cleanup from job to scheduler * refactor resumable uploads scheduler to compare to last execution time * make resumable upload validator to always cleanup on failure * move legacy upload request building outside of uploadVideo test helper * filter upload-resumable middlewares down to POST, PUT, DELETE also begin to type metadata * merge add duration functions * stronger typings and documentation for uploadx behaviour, move init validator up * refactor(client/video-edit): options > uploadxOptions * refactor(client/video-edit): remove obsolete else * scheduler/remove-dangling-resum: rename tag * refactor(server/video): add UploadVideoFiles type * refactor(mw/validators): restructure eslint disable * refactor(mw/validators/videos): rename import * refactor(client/vid-upload): rename html elem id * refactor(sched/remove-dangl): move fn to method * refactor(mw/async): add method typing * refactor(mw/vali/video): double quote > single * refactor(server/upload-resum): express use > all * proper http methud enum server/middlewares/async.ts * properly type http methods * factorize common video upload validation steps * add check for maximum partially uploaded file size * fix audioBg use * fix extname(filename) in addVideo * document parameters for uploadx's resumable protocol * clear META files in scheduler * last audio refactor before cramming preview in the initial POST form data * refactor as mulitpart/form-data initial post request this allows preview/thumbnail uploads alongside the initial request, and cleans up the upload form * Add more tests for resumable uploads * Refactor remove dangling resumable uploads * Prepare changelog * Add more resumable upload tests * Remove user quota check for resumable uploads * Fix upload error handler * Update nginx template for upload-resumable * Cleanup comment * Remove unused express methods * Prefer to use got instead of raw http * Don't retry on error 500 Co-authored-by: Rigel Kent Co-authored-by: Rigel Kent Co-authored-by: Chocobozzz --- server/tests/api/check-params/index.ts | 1 + server/tests/api/check-params/upload-quota.ts | 152 ++++++ server/tests/api/check-params/users.ts | 105 +--- server/tests/api/check-params/videos.ts | 393 +++++++------- server/tests/api/videos/index.ts | 1 + server/tests/api/videos/multiple-servers.ts | 2 +- server/tests/api/videos/resumable-upload.ts | 187 +++++++ server/tests/api/videos/single-server.ts | 724 +++++++++++++------------- server/tests/api/videos/video-transcoder.ts | 159 +++--- 9 files changed, 987 insertions(+), 737 deletions(-) create mode 100644 server/tests/api/check-params/upload-quota.ts create mode 100644 server/tests/api/videos/resumable-upload.ts (limited to 'server/tests') diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts index d0b0b9c21..143515838 100644 --- a/server/tests/api/check-params/index.ts +++ b/server/tests/api/check-params/index.ts @@ -13,6 +13,7 @@ import './plugins' import './redundancy' import './search' import './services' +import './upload-quota' import './user-notifications' import './user-subscriptions' import './users' diff --git a/server/tests/api/check-params/upload-quota.ts b/server/tests/api/check-params/upload-quota.ts new file mode 100644 index 000000000..d0fbec415 --- /dev/null +++ b/server/tests/api/check-params/upload-quota.ts @@ -0,0 +1,152 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ + +import 'mocha' +import { expect } from 'chai' +import { HttpStatusCode, randomInt } from '@shared/core-utils' +import { getGoodVideoUrl, getMagnetURI, getMyVideoImports, importVideo } from '@shared/extra-utils/videos/video-imports' +import { MyUser, VideoImport, VideoImportState, VideoPrivacy } from '@shared/models' +import { + cleanupTests, + flushAndRunServer, + getMyUserInformation, + immutableAssign, + registerUser, + ServerInfo, + setAccessTokensToServers, + setDefaultVideoChannel, + updateUser, + uploadVideo, + userLogin, + waitJobs +} from '../../../../shared/extra-utils' + +describe('Test upload quota', function () { + let server: ServerInfo + let rootId: number + + // --------------------------------------------------------------- + + before(async function () { + this.timeout(30000) + + server = await flushAndRunServer(1) + await setAccessTokensToServers([ server ]) + await setDefaultVideoChannel([ server ]) + + const res = await getMyUserInformation(server.url, server.accessToken) + rootId = (res.body as MyUser).id + + await updateUser({ + url: server.url, + userId: rootId, + accessToken: server.accessToken, + videoQuota: 42 + }) + }) + + describe('When having a video quota', function () { + + it('Should fail with a registered user having too many videos with legacy upload', async function () { + this.timeout(30000) + + const user = { username: 'registered' + randomInt(1, 1500), password: 'password' } + await registerUser(server.url, user.username, user.password) + const userAccessToken = await userLogin(server, user) + + const videoAttributes = { fixture: 'video_short2.webm' } + for (let i = 0; i < 5; i++) { + await uploadVideo(server.url, userAccessToken, videoAttributes) + } + + await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'legacy') + }) + + it('Should fail with a registered user having too many videos with resumable upload', async function () { + this.timeout(30000) + + const user = { username: 'registered' + randomInt(1, 1500), password: 'password' } + await registerUser(server.url, user.username, user.password) + const userAccessToken = await userLogin(server, user) + + const videoAttributes = { fixture: 'video_short2.webm' } + for (let i = 0; i < 5; i++) { + await uploadVideo(server.url, userAccessToken, videoAttributes) + } + + await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'resumable') + }) + + it('Should fail to import with HTTP/Torrent/magnet', async function () { + this.timeout(120000) + + const baseAttributes = { + channelId: server.videoChannel.id, + privacy: VideoPrivacy.PUBLIC + } + await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getGoodVideoUrl() })) + await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() })) + await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' as any })) + + await waitJobs([ server ]) + + const res = await getMyVideoImports(server.url, server.accessToken) + + expect(res.body.total).to.equal(3) + const videoImports: VideoImport[] = res.body.data + expect(videoImports).to.have.lengthOf(3) + + for (const videoImport of videoImports) { + expect(videoImport.state.id).to.equal(VideoImportState.FAILED) + expect(videoImport.error).not.to.be.undefined + expect(videoImport.error).to.contain('user video quota is exceeded') + } + }) + }) + + describe('When having a daily video quota', function () { + + it('Should fail with a user having too many videos daily', async function () { + await updateUser({ + url: server.url, + userId: rootId, + accessToken: server.accessToken, + videoQuotaDaily: 42 + }) + + await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'legacy') + await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'resumable') + }) + }) + + describe('When having an absolute and daily video quota', function () { + it('Should fail if exceeding total quota', async function () { + await updateUser({ + url: server.url, + userId: rootId, + accessToken: server.accessToken, + videoQuota: 42, + videoQuotaDaily: 1024 * 1024 * 1024 + }) + + await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'legacy') + await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'resumable') + }) + + it('Should fail if exceeding daily quota', async function () { + await updateUser({ + url: server.url, + userId: rootId, + accessToken: server.accessToken, + videoQuota: 1024 * 1024 * 1024, + videoQuotaDaily: 42 + }) + + await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'legacy') + await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413, 'resumable') + }) + }) + + after(async function () { + await cleanupTests([ server ]) + }) +}) diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 2b03fde2d..dcff0d52b 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ import 'mocha' -import { expect } from 'chai' import { omit } from 'lodash' import { join } from 'path' -import { User, UserRole, VideoImport, VideoImportState } from '../../../../shared' +import { User, UserRole } from '../../../../shared' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { addVideoChannel, blockUser, @@ -29,7 +29,6 @@ import { ServerInfo, setAccessTokensToServers, unblockUser, - updateUser, uploadVideo, userLogin } from '../../../../shared/extra-utils' @@ -39,11 +38,7 @@ import { checkBadSortPagination, checkBadStartPagination } from '../../../../shared/extra-utils/requests/check-api-params' -import { waitJobs } from '../../../../shared/extra-utils/server/jobs' -import { getGoodVideoUrl, getMagnetURI, getMyVideoImports, importVideo } from '../../../../shared/extra-utils/videos/video-imports' import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' -import { VideoPrivacy } from '../../../../shared/models/videos' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' describe('Test users API validators', function () { const path = '/api/v1/users/' @@ -1093,102 +1088,6 @@ describe('Test users API validators', function () { }) }) - describe('When having a video quota', function () { - it('Should fail with a user having too many videos', async function () { - await updateUser({ - url: server.url, - userId: rootId, - accessToken: server.accessToken, - videoQuota: 42 - }) - - await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) - }) - - it('Should fail with a registered user having too many videos', async function () { - this.timeout(30000) - - const user = { - username: 'user3', - password: 'my super password' - } - userAccessToken = await userLogin(server, user) - - const videoAttributes = { fixture: 'video_short2.webm' } - await uploadVideo(server.url, userAccessToken, videoAttributes) - await uploadVideo(server.url, userAccessToken, videoAttributes) - await uploadVideo(server.url, userAccessToken, videoAttributes) - await uploadVideo(server.url, userAccessToken, videoAttributes) - await uploadVideo(server.url, userAccessToken, videoAttributes) - await uploadVideo(server.url, userAccessToken, videoAttributes, HttpStatusCode.PAYLOAD_TOO_LARGE_413) - }) - - it('Should fail to import with HTTP/Torrent/magnet', async function () { - this.timeout(120000) - - const baseAttributes = { - channelId: 1, - privacy: VideoPrivacy.PUBLIC - } - await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getGoodVideoUrl() })) - await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() })) - await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' as any })) - - await waitJobs([ server ]) - - const res = await getMyVideoImports(server.url, server.accessToken) - - expect(res.body.total).to.equal(3) - const videoImports: VideoImport[] = res.body.data - expect(videoImports).to.have.lengthOf(3) - - for (const videoImport of videoImports) { - expect(videoImport.state.id).to.equal(VideoImportState.FAILED) - expect(videoImport.error).not.to.be.undefined - expect(videoImport.error).to.contain('user video quota is exceeded') - } - }) - }) - - describe('When having a daily video quota', function () { - it('Should fail with a user having too many videos daily', async function () { - await updateUser({ - url: server.url, - userId: rootId, - accessToken: server.accessToken, - videoQuotaDaily: 42 - }) - - await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) - }) - }) - - describe('When having an absolute and daily video quota', function () { - it('Should fail if exceeding total quota', async function () { - await updateUser({ - url: server.url, - userId: rootId, - accessToken: server.accessToken, - videoQuota: 42, - videoQuotaDaily: 1024 * 1024 * 1024 - }) - - await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) - }) - - it('Should fail if exceeding daily quota', async function () { - await updateUser({ - url: server.url, - userId: rootId, - accessToken: server.accessToken, - videoQuota: 1024 * 1024 * 1024, - videoQuotaDaily: 42 - }) - - await uploadVideo(server.url, server.accessToken, {}, HttpStatusCode.PAYLOAD_TOO_LARGE_413) - }) - }) - describe('When asking a password reset', function () { const path = '/api/v1/users/ask-reset-password' diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index 188d1835c..c970c4a15 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts @@ -1,11 +1,12 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ +import 'mocha' import * as chai from 'chai' import { omit } from 'lodash' -import 'mocha' import { join } from 'path' -import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { + checkUploadVideoParam, cleanupTests, createUser, flushAndRunServer, @@ -18,17 +19,18 @@ import { makePutBodyRequest, makeUploadRequest, removeVideo, + root, ServerInfo, setAccessTokensToServers, - userLogin, - root + userLogin } from '../../../../shared/extra-utils' import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../../../shared/extra-utils/requests/check-api-params' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' +import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum' +import { randomInt } from '@shared/core-utils' const expect = chai.expect @@ -183,7 +185,7 @@ describe('Test videos API validator', function () { describe('When adding a video', function () { let baseCorrectParams const baseCorrectAttaches = { - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.webm') + fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.webm') } before(function () { @@ -206,256 +208,243 @@ describe('Test videos API validator', function () { } }) - it('Should fail with nothing', async function () { - const fields = {} - const attaches = {} - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + function runSuite (mode: 'legacy' | 'resumable') { - it('Should fail without name', async function () { - const fields = omit(baseCorrectParams, 'name') - const attaches = baseCorrectAttaches + it('Should fail with nothing', async function () { + const fields = {} + const attaches = {} + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail without name', async function () { + const fields = omit(baseCorrectParams, 'name') + const attaches = baseCorrectAttaches - it('Should fail with a long name', async function () { - const fields = immutableAssign(baseCorrectParams, { name: 'super'.repeat(65) }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a long name', async function () { + const fields = immutableAssign(baseCorrectParams, { name: 'super'.repeat(65) }) + const attaches = baseCorrectAttaches - it('Should fail with a bad category', async function () { - const fields = immutableAssign(baseCorrectParams, { category: 125 }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a bad category', async function () { + const fields = immutableAssign(baseCorrectParams, { category: 125 }) + const attaches = baseCorrectAttaches - it('Should fail with a bad licence', async function () { - const fields = immutableAssign(baseCorrectParams, { licence: 125 }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a bad licence', async function () { + const fields = immutableAssign(baseCorrectParams, { licence: 125 }) + const attaches = baseCorrectAttaches - it('Should fail with a bad language', async function () { - const fields = immutableAssign(baseCorrectParams, { language: 'a'.repeat(15) }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a bad language', async function () { + const fields = immutableAssign(baseCorrectParams, { language: 'a'.repeat(15) }) + const attaches = baseCorrectAttaches - it('Should fail with a long description', async function () { - const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a long description', async function () { + const fields = immutableAssign(baseCorrectParams, { description: 'super'.repeat(2500) }) + const attaches = baseCorrectAttaches - it('Should fail with a long support text', async function () { - const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(201) }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a long support text', async function () { + const fields = immutableAssign(baseCorrectParams, { support: 'super'.repeat(201) }) + const attaches = baseCorrectAttaches - it('Should fail without a channel', async function () { - const fields = omit(baseCorrectParams, 'channelId') - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail without a channel', async function () { + const fields = omit(baseCorrectParams, 'channelId') + const attaches = baseCorrectAttaches - it('Should fail with a bad channel', async function () { - const fields = immutableAssign(baseCorrectParams, { channelId: 545454 }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a bad channel', async function () { + const fields = immutableAssign(baseCorrectParams, { channelId: 545454 }) + const attaches = baseCorrectAttaches - it('Should fail with another user channel', async function () { - const user = { - username: 'fake', - password: 'fake_password' - } - await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - const accessTokenUser = await userLogin(server, user) - const res = await getMyUserInformation(server.url, accessTokenUser) - const customChannelId = res.body.videoChannels[0].id + it('Should fail with another user channel', async function () { + const user = { + username: 'fake' + randomInt(0, 1500), + password: 'fake_password' + } + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) - const fields = immutableAssign(baseCorrectParams, { channelId: customChannelId }) - const attaches = baseCorrectAttaches + const accessTokenUser = await userLogin(server, user) + const res = await getMyUserInformation(server.url, accessTokenUser) + const customChannelId = res.body.videoChannels[0].id - await makeUploadRequest({ url: server.url, path: path + '/upload', token: userAccessToken, fields, attaches }) - }) + const fields = immutableAssign(baseCorrectParams, { channelId: customChannelId }) + const attaches = baseCorrectAttaches - it('Should fail with too many tags', async function () { - const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ] }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, userAccessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with too many tags', async function () { + const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ] }) + const attaches = baseCorrectAttaches - it('Should fail with a tag length too low', async function () { - const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 't' ] }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a tag length too low', async function () { + const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 't' ] }) + const attaches = baseCorrectAttaches - it('Should fail with a tag length too big', async function () { - const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'my_super_tag_too_long_long_long_long_long_long' ] }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a tag length too big', async function () { + const fields = immutableAssign(baseCorrectParams, { tags: [ 'tag1', 'my_super_tag_too_long_long_long_long_long_long' ] }) + const attaches = baseCorrectAttaches - it('Should fail with a bad schedule update (miss updateAt)', async function () { - const fields = immutableAssign(baseCorrectParams, { 'scheduleUpdate[privacy]': VideoPrivacy.PUBLIC }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a bad schedule update (miss updateAt)', async function () { + const fields = immutableAssign(baseCorrectParams, { scheduleUpdate: { privacy: VideoPrivacy.PUBLIC } }) + const attaches = baseCorrectAttaches - it('Should fail with a bad schedule update (wrong updateAt)', async function () { - const fields = immutableAssign(baseCorrectParams, { - 'scheduleUpdate[privacy]': VideoPrivacy.PUBLIC, - 'scheduleUpdate[updateAt]': 'toto' + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) }) - const attaches = baseCorrectAttaches - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a bad schedule update (wrong updateAt)', async function () { + const fields = immutableAssign(baseCorrectParams, { + scheduleUpdate: { + privacy: VideoPrivacy.PUBLIC, + updateAt: 'toto' + } + }) + const attaches = baseCorrectAttaches - it('Should fail with a bad originally published at attribute', async function () { - const fields = immutableAssign(baseCorrectParams, { originallyPublishedAt: 'toto' }) - const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + it('Should fail with a bad originally published at attribute', async function () { + const fields = immutableAssign(baseCorrectParams, { originallyPublishedAt: 'toto' }) + const attaches = baseCorrectAttaches - it('Should fail without an input file', async function () { - const fields = baseCorrectParams - const attaches = {} - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - it('Should fail with an incorrect input file', async function () { - const fields = baseCorrectParams - let attaches = { - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short_fake.webm') - } - await makeUploadRequest({ - url: server.url, - path: path + '/upload', - token: server.accessToken, - fields, - attaches, - statusCodeExpected: HttpStatusCode.UNPROCESSABLE_ENTITY_422 + it('Should fail without an input file', async function () { + const fields = baseCorrectParams + const attaches = {} + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) }) - attaches = { - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mkv') - } - await makeUploadRequest({ - url: server.url, - path: path + '/upload', - token: server.accessToken, - fields, - attaches, - statusCodeExpected: HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415 + it('Should fail with an incorrect input file', async function () { + const fields = baseCorrectParams + let attaches = { fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short_fake.webm') } + + await checkUploadVideoParam( + server.url, + server.accessToken, + { ...fields, ...attaches }, + HttpStatusCode.UNPROCESSABLE_ENTITY_422, + mode + ) + + attaches = { fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mkv') } + await checkUploadVideoParam( + server.url, + server.accessToken, + { ...fields, ...attaches }, + HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415, + mode + ) }) - }) - it('Should fail with an incorrect thumbnail file', async function () { - const fields = baseCorrectParams - const attaches = { - thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4'), - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') - } + it('Should fail with an incorrect thumbnail file', async function () { + const fields = baseCorrectParams + const attaches = { + thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4'), + fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') + } - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - it('Should fail with a big thumbnail file', async function () { - const fields = baseCorrectParams - const attaches = { - thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png'), - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') - } + it('Should fail with a big thumbnail file', async function () { + const fields = baseCorrectParams + const attaches = { + thumbnailfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png'), + fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') + } - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - it('Should fail with an incorrect preview file', async function () { - const fields = baseCorrectParams - const attaches = { - previewfile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4'), - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') - } + it('Should fail with an incorrect preview file', async function () { + const fields = baseCorrectParams + const attaches = { + previewfile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4'), + fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') + } - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - it('Should fail with a big preview file', async function () { - const fields = baseCorrectParams - const attaches = { - previewfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png'), - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') - } + it('Should fail with a big preview file', async function () { + const fields = baseCorrectParams + const attaches = { + previewfile: join(root(), 'server', 'tests', 'fixtures', 'preview-big.png'), + fixture: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') + } - await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) - }) + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) + }) - it('Should succeed with the correct parameters', async function () { - this.timeout(10000) + it('Should succeed with the correct parameters', async function () { + this.timeout(10000) - const fields = baseCorrectParams + const fields = baseCorrectParams - { - const attaches = baseCorrectAttaches - await makeUploadRequest({ - url: server.url, - path: path + '/upload', - token: server.accessToken, - fields, - attaches, - statusCodeExpected: HttpStatusCode.OK_200 - }) - } + { + const attaches = baseCorrectAttaches + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.OK_200, mode) + } - { - const attaches = immutableAssign(baseCorrectAttaches, { - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') - }) + { + const attaches = immutableAssign(baseCorrectAttaches, { + videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.mp4') + }) - await makeUploadRequest({ - url: server.url, - path: path + '/upload', - token: server.accessToken, - fields, - attaches, - statusCodeExpected: HttpStatusCode.OK_200 - }) - } + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.OK_200, mode) + } - { - const attaches = immutableAssign(baseCorrectAttaches, { - videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.ogv') - }) + { + const attaches = immutableAssign(baseCorrectAttaches, { + videofile: join(root(), 'server', 'tests', 'fixtures', 'video_short.ogv') + }) - await makeUploadRequest({ - url: server.url, - path: path + '/upload', - token: server.accessToken, - fields, - attaches, - statusCodeExpected: HttpStatusCode.OK_200 - }) - } + await checkUploadVideoParam(server.url, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.OK_200, mode) + } + }) + } + + describe('Resumable upload', function () { + runSuite('resumable') + }) + + describe('Legacy upload', function () { + runSuite('legacy') }) }) @@ -678,7 +667,7 @@ describe('Test videos API validator', function () { }) expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(3) + expect(res.body.data.length).to.equal(6) }) it('Should fail without a correct uuid', async function () { diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts index fc8b447b7..5c07f8926 100644 --- a/server/tests/api/videos/index.ts +++ b/server/tests/api/videos/index.ts @@ -1,5 +1,6 @@ import './audio-only' import './multiple-servers' +import './resumable-upload' import './single-server' import './video-captions' import './video-change-ownership' diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index 55e280e9f..41cd814e0 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts @@ -181,7 +181,7 @@ describe('Test multiple servers', function () { thumbnailfile: 'thumbnail.jpg', previewfile: 'preview.jpg' } - await uploadVideo(servers[1].url, userAccessToken, videoAttributes) + await uploadVideo(servers[1].url, userAccessToken, videoAttributes, HttpStatusCode.OK_200, 'resumable') // Transcoding await waitJobs(servers) diff --git a/server/tests/api/videos/resumable-upload.ts b/server/tests/api/videos/resumable-upload.ts new file mode 100644 index 000000000..af9221c43 --- /dev/null +++ b/server/tests/api/videos/resumable-upload.ts @@ -0,0 +1,187 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ + +import 'mocha' +import * as chai from 'chai' +import { pathExists, readdir, stat } from 'fs-extra' +import { join } from 'path' +import { HttpStatusCode } from '@shared/core-utils' +import { + buildAbsoluteFixturePath, + buildServerDirectory, + flushAndRunServer, + getMyUserInformation, + prepareResumableUpload, + sendDebugCommand, + sendResumableChunks, + ServerInfo, + setAccessTokensToServers, + setDefaultVideoChannel, + updateUser +} from '@shared/extra-utils' +import { MyUser, VideoPrivacy } from '@shared/models' + +const expect = chai.expect + +// Most classic resumable upload tests are done in other test suites + +describe('Test resumable upload', function () { + const defaultFixture = 'video_short.mp4' + let server: ServerInfo + let rootId: number + + async function buildSize (fixture: string, size?: number) { + if (size !== undefined) return size + + const baseFixture = buildAbsoluteFixturePath(fixture) + return (await stat(baseFixture)).size + } + + async function prepareUpload (sizeArg?: number) { + const size = await buildSize(defaultFixture, sizeArg) + + const attributes = { + name: 'video', + channelId: server.videoChannel.id, + privacy: VideoPrivacy.PUBLIC, + fixture: defaultFixture + } + + const mimetype = 'video/mp4' + + const res = await prepareResumableUpload({ url: server.url, token: server.accessToken, attributes, size, mimetype }) + + return res.header['location'].split('?')[1] + } + + async function sendChunks (options: { + pathUploadId: string + size?: number + expectedStatus?: HttpStatusCode + contentLength?: number + contentRange?: string + contentRangeBuilder?: (start: number, chunk: any) => string + }) { + const { pathUploadId, expectedStatus, contentLength, contentRangeBuilder } = options + + const size = await buildSize(defaultFixture, options.size) + const absoluteFilePath = buildAbsoluteFixturePath(defaultFixture) + + return sendResumableChunks({ + url: server.url, + token: server.accessToken, + pathUploadId, + videoFilePath: absoluteFilePath, + size, + contentLength, + contentRangeBuilder, + specialStatus: expectedStatus + }) + } + + async function checkFileSize (uploadIdArg: string, expectedSize: number | null) { + const uploadId = uploadIdArg.replace(/^upload_id=/, '') + + const subPath = join('tmp', 'resumable-uploads', uploadId) + const filePath = buildServerDirectory(server, subPath) + const exists = await pathExists(filePath) + + if (expectedSize === null) { + expect(exists).to.be.false + return + } + + expect(exists).to.be.true + + expect((await stat(filePath)).size).to.equal(expectedSize) + } + + async function countResumableUploads () { + const subPath = join('tmp', 'resumable-uploads') + const filePath = buildServerDirectory(server, subPath) + + const files = await readdir(filePath) + return files.length + } + + before(async function () { + this.timeout(30000) + + server = await flushAndRunServer(1) + await setAccessTokensToServers([ server ]) + await setDefaultVideoChannel([ server ]) + + const res = await getMyUserInformation(server.url, server.accessToken) + rootId = (res.body as MyUser).id + + await updateUser({ + url: server.url, + userId: rootId, + accessToken: server.accessToken, + videoQuota: 10_000_000 + }) + }) + + describe('Directory cleaning', function () { + + it('Should correctly delete files after an upload', async function () { + const uploadId = await prepareUpload() + await sendChunks({ pathUploadId: uploadId }) + + expect(await countResumableUploads()).to.equal(0) + }) + + it('Should not delete files after an unfinished upload', async function () { + await prepareUpload() + + expect(await countResumableUploads()).to.equal(2) + }) + + it('Should not delete recent uploads', async function () { + await sendDebugCommand(server.url, server.accessToken, { command: 'remove-dandling-resumable-uploads' }) + + expect(await countResumableUploads()).to.equal(2) + }) + + it('Should delete old uploads', async function () { + await sendDebugCommand(server.url, server.accessToken, { command: 'remove-dandling-resumable-uploads' }) + + expect(await countResumableUploads()).to.equal(0) + }) + }) + + describe('Resumable upload and chunks', function () { + + it('Should accept the same amount of chunks', async function () { + const uploadId = await prepareUpload() + await sendChunks({ pathUploadId: uploadId }) + + await checkFileSize(uploadId, null) + }) + + it('Should not accept more chunks than expected', async function () { + const size = 100 + const uploadId = await prepareUpload(size) + + await sendChunks({ pathUploadId: uploadId, expectedStatus: HttpStatusCode.CONFLICT_409 }) + await checkFileSize(uploadId, 0) + }) + + it('Should not accept more chunks than expected with an invalid content length/content range', async function () { + const uploadId = await prepareUpload(1500) + + await sendChunks({ pathUploadId: uploadId, expectedStatus: HttpStatusCode.BAD_REQUEST_400, contentLength: 1000 }) + await checkFileSize(uploadId, 0) + }) + + it('Should not accept more chunks than expected with an invalid content length', async function () { + const uploadId = await prepareUpload(500) + + const size = 1000 + + const contentRangeBuilder = start => `bytes ${start}-${start + size - 1}/${size}` + await sendChunks({ pathUploadId: uploadId, expectedStatus: HttpStatusCode.BAD_REQUEST_400, contentRangeBuilder, contentLength: size }) + await checkFileSize(uploadId, 0) + }) + }) + +}) diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts index a79648bf7..1058a1e9c 100644 --- a/server/tests/api/videos/single-server.ts +++ b/server/tests/api/videos/single-server.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ +import 'mocha' import * as chai from 'chai' import { keyBy } from 'lodash' -import 'mocha' -import { VideoPrivacy } from '../../../../shared/models/videos' + import { checkVideoFilesWereRemoved, cleanupTests, @@ -28,430 +28,432 @@ import { viewVideo, wait } from '../../../../shared/extra-utils' +import { VideoPrivacy } from '../../../../shared/models/videos' +import { HttpStatusCode } from '@shared/core-utils' const expect = chai.expect describe('Test a single server', function () { - let server: ServerInfo = null - let videoId = -1 - let videoId2 = -1 - let videoUUID = '' - let videosListBase: any[] = null - - const getCheckAttributes = () => ({ - name: 'my super name', - category: 2, - licence: 6, - language: 'zh', - nsfw: true, - description: 'my super description', - support: 'my super support text', - account: { - name: 'root', - host: 'localhost:' + server.port - }, - isLocal: true, - duration: 5, - tags: [ 'tag1', 'tag2', 'tag3' ], - privacy: VideoPrivacy.PUBLIC, - commentsEnabled: true, - downloadEnabled: true, - channel: { - displayName: 'Main root channel', - name: 'root_channel', - description: '', - isLocal: true - }, - fixture: 'video_short.webm', - files: [ - { - resolution: 720, - size: 218910 - } - ] - }) - - const updateCheckAttributes = () => ({ - name: 'my super video updated', - category: 4, - licence: 2, - language: 'ar', - nsfw: false, - description: 'my super description updated', - support: 'my super support text updated', - account: { - name: 'root', - host: 'localhost:' + server.port - }, - isLocal: true, - tags: [ 'tagup1', 'tagup2' ], - privacy: VideoPrivacy.PUBLIC, - duration: 5, - commentsEnabled: false, - downloadEnabled: false, - channel: { - name: 'root_channel', - displayName: 'Main root channel', - description: '', - isLocal: true - }, - fixture: 'video_short3.webm', - files: [ - { - resolution: 720, - size: 292677 - } - ] - }) - - before(async function () { - this.timeout(30000) - - server = await flushAndRunServer(1) - - await setAccessTokensToServers([ server ]) - }) - - it('Should list video categories', async function () { - const res = await getVideoCategories(server.url) - - const categories = res.body - expect(Object.keys(categories)).to.have.length.above(10) - - expect(categories[11]).to.equal('News & Politics') - }) - - it('Should list video licences', async function () { - const res = await getVideoLicences(server.url) - - const licences = res.body - expect(Object.keys(licences)).to.have.length.above(5) - - expect(licences[3]).to.equal('Attribution - No Derivatives') - }) - - it('Should list video languages', async function () { - const res = await getVideoLanguages(server.url) - - const languages = res.body - expect(Object.keys(languages)).to.have.length.above(5) - - expect(languages['ru']).to.equal('Russian') - }) - - it('Should list video privacies', async function () { - const res = await getVideoPrivacies(server.url) - - const privacies = res.body - expect(Object.keys(privacies)).to.have.length.at.least(3) - - expect(privacies[3]).to.equal('Private') - }) - - it('Should not have videos', async function () { - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - }) - it('Should upload the video', async function () { - this.timeout(10000) + function runSuite (mode: 'legacy' | 'resumable') { + let server: ServerInfo = null + let videoId = -1 + let videoId2 = -1 + let videoUUID = '' + let videosListBase: any[] = null - const videoAttributes = { + const getCheckAttributes = () => ({ name: 'my super name', category: 2, - nsfw: true, licence: 6, - tags: [ 'tag1', 'tag2', 'tag3' ] - } - const res = await uploadVideo(server.url, server.accessToken, videoAttributes) - expect(res.body.video).to.not.be.undefined - expect(res.body.video.id).to.equal(1) - expect(res.body.video.uuid).to.have.length.above(5) - - videoId = res.body.video.id - videoUUID = res.body.video.uuid - }) - - it('Should get and seed the uploaded video', async function () { - this.timeout(5000) - - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - - const video = res.body.data[0] - await completeVideoCheck(server.url, video, getCheckAttributes()) - }) + language: 'zh', + nsfw: true, + description: 'my super description', + support: 'my super support text', + account: { + name: 'root', + host: 'localhost:' + server.port + }, + isLocal: true, + duration: 5, + tags: [ 'tag1', 'tag2', 'tag3' ], + privacy: VideoPrivacy.PUBLIC, + commentsEnabled: true, + downloadEnabled: true, + channel: { + displayName: 'Main root channel', + name: 'root_channel', + description: '', + isLocal: true + }, + fixture: 'video_short.webm', + files: [ + { + resolution: 720, + size: 218910 + } + ] + }) + + const updateCheckAttributes = () => ({ + name: 'my super video updated', + category: 4, + licence: 2, + language: 'ar', + nsfw: false, + description: 'my super description updated', + support: 'my super support text updated', + account: { + name: 'root', + host: 'localhost:' + server.port + }, + isLocal: true, + tags: [ 'tagup1', 'tagup2' ], + privacy: VideoPrivacy.PUBLIC, + duration: 5, + commentsEnabled: false, + downloadEnabled: false, + channel: { + name: 'root_channel', + displayName: 'Main root channel', + description: '', + isLocal: true + }, + fixture: 'video_short3.webm', + files: [ + { + resolution: 720, + size: 292677 + } + ] + }) - it('Should get the video by UUID', async function () { - this.timeout(5000) + before(async function () { + this.timeout(30000) - const res = await getVideo(server.url, videoUUID) + server = await flushAndRunServer(1) - const video = res.body - await completeVideoCheck(server.url, video, getCheckAttributes()) - }) + await setAccessTokensToServers([ server ]) + }) - it('Should have the views updated', async function () { - this.timeout(20000) + it('Should list video categories', async function () { + const res = await getVideoCategories(server.url) - await viewVideo(server.url, videoId) - await viewVideo(server.url, videoId) - await viewVideo(server.url, videoId) + const categories = res.body + expect(Object.keys(categories)).to.have.length.above(10) - await wait(1500) + expect(categories[11]).to.equal('News & Politics') + }) - await viewVideo(server.url, videoId) - await viewVideo(server.url, videoId) + it('Should list video licences', async function () { + const res = await getVideoLicences(server.url) - await wait(1500) + const licences = res.body + expect(Object.keys(licences)).to.have.length.above(5) - await viewVideo(server.url, videoId) - await viewVideo(server.url, videoId) + expect(licences[3]).to.equal('Attribution - No Derivatives') + }) - // Wait the repeatable job - await wait(8000) + it('Should list video languages', async function () { + const res = await getVideoLanguages(server.url) - const res = await getVideo(server.url, videoId) + const languages = res.body + expect(Object.keys(languages)).to.have.length.above(5) - const video = res.body - expect(video.views).to.equal(3) - }) + expect(languages['ru']).to.equal('Russian') + }) - it('Should remove the video', async function () { - await removeVideo(server.url, server.accessToken, videoId) + it('Should list video privacies', async function () { + const res = await getVideoPrivacies(server.url) - await checkVideoFilesWereRemoved(videoUUID, 1) - }) + const privacies = res.body + expect(Object.keys(privacies)).to.have.length.at.least(3) - it('Should not have videos', async function () { - const res = await getVideosList(server.url) + expect(privacies[3]).to.equal('Private') + }) - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data).to.have.lengthOf(0) - }) + it('Should not have videos', async function () { + const res = await getVideosList(server.url) - it('Should upload 6 videos', async function () { - this.timeout(25000) + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + }) - const videos = new Set([ - 'video_short.mp4', 'video_short.ogv', 'video_short.webm', - 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' - ]) + it('Should upload the video', async function () { + this.timeout(10000) - for (const video of videos) { const videoAttributes = { - name: video + ' name', - description: video + ' description', + name: 'my super name', category: 2, - licence: 1, - language: 'en', nsfw: true, - tags: [ 'tag1', 'tag2', 'tag3' ], - fixture: video + licence: 6, + tags: [ 'tag1', 'tag2', 'tag3' ] } + const res = await uploadVideo(server.url, server.accessToken, videoAttributes, HttpStatusCode.OK_200, mode) + expect(res.body.video).to.not.be.undefined + expect(res.body.video.id).to.equal(1) + expect(res.body.video.uuid).to.have.length.above(5) - await uploadVideo(server.url, server.accessToken, videoAttributes) - } - }) + videoId = res.body.video.id + videoUUID = res.body.video.uuid + }) - it('Should have the correct durations', async function () { - const res = await getVideosList(server.url) - - expect(res.body.total).to.equal(6) - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos).to.have.lengthOf(6) - - const videosByName = keyBy<{ duration: number }>(videos, 'name') - expect(videosByName['video_short.mp4 name'].duration).to.equal(5) - expect(videosByName['video_short.ogv name'].duration).to.equal(5) - expect(videosByName['video_short.webm name'].duration).to.equal(5) - expect(videosByName['video_short1.webm name'].duration).to.equal(10) - expect(videosByName['video_short2.webm name'].duration).to.equal(5) - expect(videosByName['video_short3.webm name'].duration).to.equal(5) - }) + it('Should get and seed the uploaded video', async function () { + this.timeout(5000) - it('Should have the correct thumbnails', async function () { - const res = await getVideosList(server.url) + const res = await getVideosList(server.url) - const videos = res.body.data - // For the next test - videosListBase = videos + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) - for (const video of videos) { - const videoName = video.name.replace(' name', '') - await testImage(server.url, videoName, video.thumbnailPath) - } - }) + const video = res.body.data[0] + await completeVideoCheck(server.url, video, getCheckAttributes()) + }) - it('Should list only the two first videos', async function () { - const res = await getVideosListPagination(server.url, 0, 2, 'name') + it('Should get the video by UUID', async function () { + this.timeout(5000) - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(2) - expect(videos[0].name).to.equal(videosListBase[0].name) - expect(videos[1].name).to.equal(videosListBase[1].name) - }) + const res = await getVideo(server.url, videoUUID) - it('Should list only the next three videos', async function () { - const res = await getVideosListPagination(server.url, 2, 3, 'name') + const video = res.body + await completeVideoCheck(server.url, video, getCheckAttributes()) + }) - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(3) - expect(videos[0].name).to.equal(videosListBase[2].name) - expect(videos[1].name).to.equal(videosListBase[3].name) - expect(videos[2].name).to.equal(videosListBase[4].name) - }) + it('Should have the views updated', async function () { + this.timeout(20000) - it('Should list the last video', async function () { - const res = await getVideosListPagination(server.url, 5, 6, 'name') + await viewVideo(server.url, videoId) + await viewVideo(server.url, videoId) + await viewVideo(server.url, videoId) - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(1) - expect(videos[0].name).to.equal(videosListBase[5].name) - }) + await wait(1500) - it('Should not have the total field', async function () { - const res = await getVideosListPagination(server.url, 5, 6, 'name', true) + await viewVideo(server.url, videoId) + await viewVideo(server.url, videoId) - const videos = res.body.data - expect(res.body.total).to.not.exist - expect(videos.length).to.equal(1) - expect(videos[0].name).to.equal(videosListBase[5].name) - }) + await wait(1500) - it('Should list and sort by name in descending order', async function () { - const res = await getVideosListSort(server.url, '-name') - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(6) - expect(videos[0].name).to.equal('video_short.webm name') - expect(videos[1].name).to.equal('video_short.ogv name') - expect(videos[2].name).to.equal('video_short.mp4 name') - expect(videos[3].name).to.equal('video_short3.webm name') - expect(videos[4].name).to.equal('video_short2.webm name') - expect(videos[5].name).to.equal('video_short1.webm name') - - videoId = videos[3].uuid - videoId2 = videos[5].uuid - }) + await viewVideo(server.url, videoId) + await viewVideo(server.url, videoId) - it('Should list and sort by trending in descending order', async function () { - const res = await getVideosListPagination(server.url, 0, 2, '-trending') + // Wait the repeatable job + await wait(8000) - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(2) - }) + const res = await getVideo(server.url, videoId) - it('Should list and sort by hotness in descending order', async function () { - const res = await getVideosListPagination(server.url, 0, 2, '-hot') + const video = res.body + expect(video.views).to.equal(3) + }) - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(2) - }) + it('Should remove the video', async function () { + await removeVideo(server.url, server.accessToken, videoId) - it('Should list and sort by best in descending order', async function () { - const res = await getVideosListPagination(server.url, 0, 2, '-best') + await checkVideoFilesWereRemoved(videoUUID, 1) + }) - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(2) - }) + it('Should not have videos', async function () { + const res = await getVideosList(server.url) - it('Should update a video', async function () { - const attributes = { - name: 'my super video updated', - category: 4, - licence: 2, - language: 'ar', - nsfw: false, - description: 'my super description updated', - commentsEnabled: false, - downloadEnabled: false, - tags: [ 'tagup1', 'tagup2' ] - } - await updateVideo(server.url, server.accessToken, videoId, attributes) - }) + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data).to.have.lengthOf(0) + }) - it('Should filter by tags and category', async function () { - const res1 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: [ 4 ] }) - expect(res1.body.total).to.equal(1) - expect(res1.body.data[0].name).to.equal('my super video updated') + it('Should upload 6 videos', async function () { + this.timeout(25000) - const res2 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: [ 3 ] }) - expect(res2.body.total).to.equal(0) - }) + const videos = new Set([ + 'video_short.mp4', 'video_short.ogv', 'video_short.webm', + 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' + ]) - it('Should have the video updated', async function () { - this.timeout(60000) + for (const video of videos) { + const videoAttributes = { + name: video + ' name', + description: video + ' description', + category: 2, + licence: 1, + language: 'en', + nsfw: true, + tags: [ 'tag1', 'tag2', 'tag3' ], + fixture: video + } - const res = await getVideo(server.url, videoId) - const video = res.body + await uploadVideo(server.url, server.accessToken, videoAttributes, HttpStatusCode.OK_200, mode) + } + }) + + it('Should have the correct durations', async function () { + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(6) + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos).to.have.lengthOf(6) + + const videosByName = keyBy<{ duration: number }>(videos, 'name') + expect(videosByName['video_short.mp4 name'].duration).to.equal(5) + expect(videosByName['video_short.ogv name'].duration).to.equal(5) + expect(videosByName['video_short.webm name'].duration).to.equal(5) + expect(videosByName['video_short1.webm name'].duration).to.equal(10) + expect(videosByName['video_short2.webm name'].duration).to.equal(5) + expect(videosByName['video_short3.webm name'].duration).to.equal(5) + }) + + it('Should have the correct thumbnails', async function () { + const res = await getVideosList(server.url) + + const videos = res.body.data + // For the next test + videosListBase = videos + + for (const video of videos) { + const videoName = video.name.replace(' name', '') + await testImage(server.url, videoName, video.thumbnailPath) + } + }) + + it('Should list only the two first videos', async function () { + const res = await getVideosListPagination(server.url, 0, 2, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(2) + expect(videos[0].name).to.equal(videosListBase[0].name) + expect(videos[1].name).to.equal(videosListBase[1].name) + }) + + it('Should list only the next three videos', async function () { + const res = await getVideosListPagination(server.url, 2, 3, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(3) + expect(videos[0].name).to.equal(videosListBase[2].name) + expect(videos[1].name).to.equal(videosListBase[3].name) + expect(videos[2].name).to.equal(videosListBase[4].name) + }) + + it('Should list the last video', async function () { + const res = await getVideosListPagination(server.url, 5, 6, 'name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(1) + expect(videos[0].name).to.equal(videosListBase[5].name) + }) + + it('Should not have the total field', async function () { + const res = await getVideosListPagination(server.url, 5, 6, 'name', true) + + const videos = res.body.data + expect(res.body.total).to.not.exist + expect(videos.length).to.equal(1) + expect(videos[0].name).to.equal(videosListBase[5].name) + }) + + it('Should list and sort by name in descending order', async function () { + const res = await getVideosListSort(server.url, '-name') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(6) + expect(videos[0].name).to.equal('video_short.webm name') + expect(videos[1].name).to.equal('video_short.ogv name') + expect(videos[2].name).to.equal('video_short.mp4 name') + expect(videos[3].name).to.equal('video_short3.webm name') + expect(videos[4].name).to.equal('video_short2.webm name') + expect(videos[5].name).to.equal('video_short1.webm name') + + videoId = videos[3].uuid + videoId2 = videos[5].uuid + }) + + it('Should list and sort by trending in descending order', async function () { + const res = await getVideosListPagination(server.url, 0, 2, '-trending') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(2) + }) + + it('Should list and sort by hotness in descending order', async function () { + const res = await getVideosListPagination(server.url, 0, 2, '-hot') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(2) + }) + + it('Should list and sort by best in descending order', async function () { + const res = await getVideosListPagination(server.url, 0, 2, '-best') + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(2) + }) + + it('Should update a video', async function () { + const attributes = { + name: 'my super video updated', + category: 4, + licence: 2, + language: 'ar', + nsfw: false, + description: 'my super description updated', + commentsEnabled: false, + downloadEnabled: false, + tags: [ 'tagup1', 'tagup2' ] + } + await updateVideo(server.url, server.accessToken, videoId, attributes) + }) - await completeVideoCheck(server.url, video, updateCheckAttributes()) - }) + it('Should filter by tags and category', async function () { + const res1 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: [ 4 ] }) + expect(res1.body.total).to.equal(1) + expect(res1.body.data[0].name).to.equal('my super video updated') - it('Should update only the tags of a video', async function () { - const attributes = { - tags: [ 'supertag', 'tag1', 'tag2' ] - } - await updateVideo(server.url, server.accessToken, videoId, attributes) + const res2 = await getVideosWithFilters(server.url, { tagsAllOf: [ 'tagup1', 'tagup2' ], categoryOneOf: [ 3 ] }) + expect(res2.body.total).to.equal(0) + }) - const res = await getVideo(server.url, videoId) - const video = res.body + it('Should have the video updated', async function () { + this.timeout(60000) - await completeVideoCheck(server.url, video, Object.assign(updateCheckAttributes(), attributes)) - }) + const res = await getVideo(server.url, videoId) + const video = res.body - it('Should update only the description of a video', async function () { - const attributes = { - description: 'hello everybody' - } - await updateVideo(server.url, server.accessToken, videoId, attributes) + await completeVideoCheck(server.url, video, updateCheckAttributes()) + }) - const res = await getVideo(server.url, videoId) - const video = res.body + it('Should update only the tags of a video', async function () { + const attributes = { + tags: [ 'supertag', 'tag1', 'tag2' ] + } + await updateVideo(server.url, server.accessToken, videoId, attributes) - const expectedAttributes = Object.assign(updateCheckAttributes(), { tags: [ 'supertag', 'tag1', 'tag2' ] }, attributes) - await completeVideoCheck(server.url, video, expectedAttributes) - }) + const res = await getVideo(server.url, videoId) + const video = res.body - it('Should like a video', async function () { - await rateVideo(server.url, server.accessToken, videoId, 'like') + await completeVideoCheck(server.url, video, Object.assign(updateCheckAttributes(), attributes)) + }) - const res = await getVideo(server.url, videoId) - const video = res.body + it('Should update only the description of a video', async function () { + const attributes = { + description: 'hello everybody' + } + await updateVideo(server.url, server.accessToken, videoId, attributes) - expect(video.likes).to.equal(1) - expect(video.dislikes).to.equal(0) - }) + const res = await getVideo(server.url, videoId) + const video = res.body - it('Should dislike the same video', async function () { - await rateVideo(server.url, server.accessToken, videoId, 'dislike') + const expectedAttributes = Object.assign(updateCheckAttributes(), { tags: [ 'supertag', 'tag1', 'tag2' ] }, attributes) + await completeVideoCheck(server.url, video, expectedAttributes) + }) - const res = await getVideo(server.url, videoId) - const video = res.body + it('Should like a video', async function () { + await rateVideo(server.url, server.accessToken, videoId, 'like') - expect(video.likes).to.equal(0) - expect(video.dislikes).to.equal(1) - }) + const res = await getVideo(server.url, videoId) + const video = res.body - it('Should sort by originallyPublishedAt', async function () { - { + expect(video.likes).to.equal(1) + expect(video.dislikes).to.equal(0) + }) + it('Should dislike the same video', async function () { + await rateVideo(server.url, server.accessToken, videoId, 'dislike') + + const res = await getVideo(server.url, videoId) + const video = res.body + + expect(video.likes).to.equal(0) + expect(video.dislikes).to.equal(1) + }) + + it('Should sort by originallyPublishedAt', async function () { { const now = new Date() const attributes = { originallyPublishedAt: now.toISOString() } @@ -483,10 +485,18 @@ describe('Test a single server', function () { expect(names[4]).to.equal('video_short.ogv name') expect(names[5]).to.equal('video_short.mp4 name') } - } + }) + + after(async function () { + await cleanupTests([ server ]) + }) + } + + describe('Legacy upload', function () { + runSuite('legacy') }) - after(async function () { - await cleanupTests([ server ]) + describe('Resumable upload', function () { + runSuite('resumable') }) }) diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts index 1c99f26df..ea5ffd239 100644 --- a/server/tests/api/videos/video-transcoder.ts +++ b/server/tests/api/videos/video-transcoder.ts @@ -361,106 +361,117 @@ describe('Test video transcoding', function () { describe('Audio upload', function () { - before(async function () { - await updateCustomSubConfig(servers[1].url, servers[1].accessToken, { - transcoding: { - hls: { enabled: true }, - webtorrent: { enabled: true }, - resolutions: { - '0p': false, - '240p': false, - '360p': false, - '480p': false, - '720p': false, - '1080p': false, - '1440p': false, - '2160p': false + function runSuite (mode: 'legacy' | 'resumable') { + + before(async function () { + await updateCustomSubConfig(servers[1].url, servers[1].accessToken, { + transcoding: { + hls: { enabled: true }, + webtorrent: { enabled: true }, + resolutions: { + '0p': false, + '240p': false, + '360p': false, + '480p': false, + '720p': false, + '1080p': false, + '1440p': false, + '2160p': false + } } - } + }) }) - }) - - it('Should merge an audio file with the preview file', async function () { - this.timeout(60_000) - - const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } - await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg) - await waitJobs(servers) + it('Should merge an audio file with the preview file', async function () { + this.timeout(60_000) - for (const server of servers) { - const res = await getVideosList(server.url) + const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } + await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg, HttpStatusCode.OK_200, mode) - const video = res.body.data.find(v => v.name === 'audio_with_preview') - const res2 = await getVideo(server.url, video.id) - const videoDetails: VideoDetails = res2.body + await waitJobs(servers) - expect(videoDetails.files).to.have.lengthOf(1) + for (const server of servers) { + const res = await getVideosList(server.url) - await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: HttpStatusCode.OK_200 }) - await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: HttpStatusCode.OK_200 }) + const video = res.body.data.find(v => v.name === 'audio_with_preview') + const res2 = await getVideo(server.url, video.id) + const videoDetails: VideoDetails = res2.body - const magnetUri = videoDetails.files[0].magnetUri - expect(magnetUri).to.contain('.mp4') - } - }) + expect(videoDetails.files).to.have.lengthOf(1) - it('Should upload an audio file and choose a default background image', async function () { - this.timeout(60_000) + await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: HttpStatusCode.OK_200 }) + await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: HttpStatusCode.OK_200 }) - const videoAttributesArg = { name: 'audio_without_preview', fixture: 'sample.ogg' } - await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg) + const magnetUri = videoDetails.files[0].magnetUri + expect(magnetUri).to.contain('.mp4') + } + }) - await waitJobs(servers) + it('Should upload an audio file and choose a default background image', async function () { + this.timeout(60_000) - for (const server of servers) { - const res = await getVideosList(server.url) + const videoAttributesArg = { name: 'audio_without_preview', fixture: 'sample.ogg' } + await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg, HttpStatusCode.OK_200, mode) - const video = res.body.data.find(v => v.name === 'audio_without_preview') - const res2 = await getVideo(server.url, video.id) - const videoDetails = res2.body + await waitJobs(servers) - expect(videoDetails.files).to.have.lengthOf(1) + for (const server of servers) { + const res = await getVideosList(server.url) - await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: HttpStatusCode.OK_200 }) - await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: HttpStatusCode.OK_200 }) + const video = res.body.data.find(v => v.name === 'audio_without_preview') + const res2 = await getVideo(server.url, video.id) + const videoDetails = res2.body - const magnetUri = videoDetails.files[0].magnetUri - expect(magnetUri).to.contain('.mp4') - } - }) + expect(videoDetails.files).to.have.lengthOf(1) - it('Should upload an audio file and create an audio version only', async function () { - this.timeout(60_000) + await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: HttpStatusCode.OK_200 }) + await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: HttpStatusCode.OK_200 }) - await updateCustomSubConfig(servers[1].url, servers[1].accessToken, { - transcoding: { - hls: { enabled: true }, - webtorrent: { enabled: true }, - resolutions: { - '0p': true, - '240p': false, - '360p': false - } + const magnetUri = videoDetails.files[0].magnetUri + expect(magnetUri).to.contain('.mp4') } }) - const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } - const resVideo = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg) + it('Should upload an audio file and create an audio version only', async function () { + this.timeout(60_000) + + await updateCustomSubConfig(servers[1].url, servers[1].accessToken, { + transcoding: { + hls: { enabled: true }, + webtorrent: { enabled: true }, + resolutions: { + '0p': true, + '240p': false, + '360p': false + } + } + }) - await waitJobs(servers) + const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } + const resVideo = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg, HttpStatusCode.OK_200, mode) - for (const server of servers) { - const res2 = await getVideo(server.url, resVideo.body.video.id) - const videoDetails: VideoDetails = res2.body + await waitJobs(servers) + + for (const server of servers) { + const res2 = await getVideo(server.url, resVideo.body.video.id) + const videoDetails: VideoDetails = res2.body - for (const files of [ videoDetails.files, videoDetails.streamingPlaylists[0].files ]) { - expect(files).to.have.lengthOf(2) - expect(files.find(f => f.resolution.id === 0)).to.not.be.undefined + for (const files of [ videoDetails.files, videoDetails.streamingPlaylists[0].files ]) { + expect(files).to.have.lengthOf(2) + expect(files.find(f => f.resolution.id === 0)).to.not.be.undefined + } } - } - await updateConfigForTranscoding(servers[1]) + await updateConfigForTranscoding(servers[1]) + }) + } + + describe('Legacy upload', function () { + runSuite('legacy') + }) + + describe('Resumable upload', function () { + runSuite('resumable') }) }) -- cgit v1.2.3 From 3ec535f72be4fea5c6afa129d40b81b74431f1d2 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 10 May 2021 13:56:26 +0200 Subject: Fix E2E tests --- server/tests/api/server/follow-constraints.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/tests') diff --git a/server/tests/api/server/follow-constraints.ts b/server/tests/api/server/follow-constraints.ts index 0846b04f4..8a91fbba3 100644 --- a/server/tests/api/server/follow-constraints.ts +++ b/server/tests/api/server/follow-constraints.ts @@ -28,7 +28,7 @@ describe('Test follow constraints', function () { let userAccessToken: string before(async function () { - this.timeout(60000) + this.timeout(90000) servers = await flushAndRunMultipleServers(2) -- cgit v1.2.3 From f67d1dca1aa2b9015a5ec82add123ea12c1fc4ed Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 10 May 2021 16:28:26 +0200 Subject: Fix handle downs test --- server/tests/api/server/handle-down.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/tests') diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts index f3ba11950..817c79f6e 100644 --- a/server/tests/api/server/handle-down.ts +++ b/server/tests/api/server/handle-down.ts @@ -143,7 +143,7 @@ describe('Test handle downs', function () { await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) } - await waitJobs(servers[0]) + await waitJobs([ servers[0], servers[2] ]) // Kill server 3 killallServers([ servers[2] ]) -- cgit v1.2.3 From 38ce2aa7a8cc51a833b85a32222da2d2c2a43cb9 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 10 May 2021 17:06:53 +0200 Subject: Increase tests timeout --- server/tests/plugins/filter-hooks.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'server/tests') diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index cf1dd0854..7d4f7abb4 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts @@ -326,7 +326,7 @@ describe('Test plugin filter hooks', function () { }) it('Should blacklist on remote upload', async function () { - this.timeout(45000) + this.timeout(60000) const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'remote please blacklist me' }) await waitJobs(servers) @@ -335,7 +335,7 @@ describe('Test plugin filter hooks', function () { }) it('Should blacklist on remote update', async function () { - this.timeout(45000) + this.timeout(60000) const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video' }) await waitJobs(servers) -- cgit v1.2.3 From 2b02c520e66ea452687cab39401b371711caa9ed Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 11 May 2021 11:27:40 +0200 Subject: Cleanup shared models --- server/tests/api/moderation/blocklist.ts | 56 ++++++++++++---------- .../api/notifications/comments-notifications.ts | 25 ++++++---- server/tests/api/server/bulk.ts | 9 ++-- server/tests/api/server/follows.ts | 48 +++++++++---------- server/tests/api/server/handle-down.ts | 2 +- server/tests/api/videos/multiple-servers.ts | 13 +++-- server/tests/api/videos/video-comments.ts | 3 +- server/tests/plugins/filter-hooks.ts | 2 +- 8 files changed, 81 insertions(+), 77 deletions(-) (limited to 'server/tests') diff --git a/server/tests/api/moderation/blocklist.ts b/server/tests/api/moderation/blocklist.ts index e8202aff1..b767d38c7 100644 --- a/server/tests/api/moderation/blocklist.ts +++ b/server/tests/api/moderation/blocklist.ts @@ -1,46 +1,50 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import * as chai from 'chai' import 'mocha' -import { AccountBlock, ServerBlock, Video, UserNotification, UserNotificationType } from '../../../../shared/index' +import * as chai from 'chai' import { + addAccountToAccountBlocklist, + addAccountToServerBlocklist, + addServerToAccountBlocklist, + addServerToServerBlocklist, + addVideoCommentReply, + addVideoCommentThread, cleanupTests, createUser, deleteVideoComment, doubleFollow, + findCommentId, flushAndRunMultipleServers, - ServerInfo, - uploadVideo, - userLogin, follow, - unfollow -} from '../../../../shared/extra-utils/index' -import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login' -import { getVideosList, getVideosListWithToken } from '../../../../shared/extra-utils/videos/videos' -import { - addVideoCommentReply, - addVideoCommentThread, - getVideoCommentThreads, - getVideoThreadComments, - findCommentId -} from '../../../../shared/extra-utils/videos/video-comments' -import { waitJobs } from '../../../../shared/extra-utils/server/jobs' -import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' -import { - addAccountToAccountBlocklist, - addAccountToServerBlocklist, - addServerToAccountBlocklist, - addServerToServerBlocklist, getAccountBlocklistByAccount, getAccountBlocklistByServer, getServerBlocklistByAccount, getServerBlocklistByServer, + getUserNotifications, + getVideoCommentThreads, + getVideosList, + getVideosListWithToken, + getVideoThreadComments, removeAccountFromAccountBlocklist, removeAccountFromServerBlocklist, removeServerFromAccountBlocklist, - removeServerFromServerBlocklist -} from '../../../../shared/extra-utils/users/blocklist' -import { getUserNotifications } from '../../../../shared/extra-utils/users/user-notifications' + removeServerFromServerBlocklist, + ServerInfo, + setAccessTokensToServers, + unfollow, + uploadVideo, + userLogin, + waitJobs +} from '@shared/extra-utils' +import { + AccountBlock, + ServerBlock, + UserNotification, + UserNotificationType, + Video, + VideoComment, + VideoCommentThreadTree +} from '@shared/models' const expect = chai.expect diff --git a/server/tests/api/notifications/comments-notifications.ts b/server/tests/api/notifications/comments-notifications.ts index 5e4ab0d6c..d2badf237 100644 --- a/server/tests/api/notifications/comments-notifications.ts +++ b/server/tests/api/notifications/comments-notifications.ts @@ -2,20 +2,25 @@ import 'mocha' import * as chai from 'chai' -import { cleanupTests, getVideoCommentThreads, getVideoThreadComments, updateMyUser } from '../../../../shared/extra-utils' -import { ServerInfo, uploadVideo } from '../../../../shared/extra-utils/index' -import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email' -import { waitJobs } from '../../../../shared/extra-utils/server/jobs' -import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/extra-utils/users/blocklist' import { + addAccountToAccountBlocklist, + addVideoCommentReply, + addVideoCommentThread, checkCommentMention, CheckerBaseParams, checkNewCommentOnMyVideo, - prepareNotificationsTest -} from '../../../../shared/extra-utils/users/user-notifications' -import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments' -import { UserNotification } from '../../../../shared/models/users' -import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' + cleanupTests, + getVideoCommentThreads, + getVideoThreadComments, + MockSmtpServer, + prepareNotificationsTest, + removeAccountFromAccountBlocklist, + ServerInfo, + updateMyUser, + uploadVideo, + waitJobs +} from '@shared/extra-utils' +import { UserNotification, VideoCommentThreadTree } from '@shared/models' const expect = chai.expect diff --git a/server/tests/api/server/bulk.ts b/server/tests/api/server/bulk.ts index 51ba0e7af..80fa7fce6 100644 --- a/server/tests/api/server/bulk.ts +++ b/server/tests/api/server/bulk.ts @@ -2,12 +2,14 @@ import 'mocha' import * as chai from 'chai' -import { VideoComment } from '@shared/models/videos/video-comment.model' +import { Video, VideoComment } from '@shared/models' import { + addVideoCommentReply, addVideoCommentThread, bulkRemoveCommentsOf, cleanupTests, createUser, + doubleFollow, flushAndRunMultipleServers, getVideoCommentThreads, getVideosList, @@ -15,11 +17,8 @@ import { setAccessTokensToServers, uploadVideo, userLogin, - waitJobs, - addVideoCommentReply + waitJobs } from '../../../../shared/extra-utils/index' -import { doubleFollow } from '../../../../shared/extra-utils/server/follows' -import { Video } from '@shared/models' const expect = chai.expect diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts index eb9ab10eb..e1c062020 100644 --- a/server/tests/api/server/follows.ts +++ b/server/tests/api/server/follows.ts @@ -1,37 +1,35 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import * as chai from 'chai' import 'mocha' -import { Video, VideoPrivacy } from '../../../../shared/models/videos' -import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' -import { cleanupTests, completeVideoCheck, deleteVideoComment } from '../../../../shared/extra-utils' +import * as chai from 'chai' import { + addVideoCommentReply, + addVideoCommentThread, + cleanupTests, + completeVideoCheck, + createUser, + createVideoCaption, + dateIsValid, + deleteVideoComment, + expectAccountFollows, flushAndRunMultipleServers, - getVideosList, - ServerInfo, - setAccessTokensToServers, - uploadVideo -} from '../../../../shared/extra-utils/index' -import { dateIsValid } from '../../../../shared/extra-utils/miscs/miscs' -import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, - unfollow -} from '../../../../shared/extra-utils/server/follows' -import { expectAccountFollows } from '../../../../shared/extra-utils/users/accounts' -import { userLogin } from '../../../../shared/extra-utils/users/login' -import { createUser } from '../../../../shared/extra-utils/users/users' -import { - addVideoCommentReply, - addVideoCommentThread, getVideoCommentThreads, - getVideoThreadComments -} from '../../../../shared/extra-utils/videos/video-comments' -import { rateVideo } from '../../../../shared/extra-utils/videos/videos' -import { waitJobs } from '../../../../shared/extra-utils/server/jobs' -import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/extra-utils/videos/video-captions' -import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' + getVideosList, + getVideoThreadComments, + listVideoCaptions, + rateVideo, + ServerInfo, + setAccessTokensToServers, + testCaptionFile, + unfollow, + uploadVideo, + userLogin, + waitJobs +} from '@shared/extra-utils' +import { Video, VideoCaption, VideoComment, VideoCommentThreadTree, VideoPrivacy } from '@shared/models' const expect = chai.expect diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts index 817c79f6e..fa1a3c444 100644 --- a/server/tests/api/server/handle-down.ts +++ b/server/tests/api/server/handle-down.ts @@ -4,7 +4,7 @@ import * as chai from 'chai' import 'mocha' import { JobState, Video } from '../../../../shared/models' import { VideoPrivacy } from '../../../../shared/models/videos' -import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' +import { VideoCommentThreadTree } from '../../../../shared/models/videos/comment/video-comment.model' import { cleanupTests, diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index 41cd814e0..6aa996038 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts @@ -1,11 +1,10 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import * as chai from 'chai' import 'mocha' +import * as chai from 'chai' import { join } from 'path' import * as request from 'supertest' -import { VideoPrivacy } from '../../../../shared/models/videos' -import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { addVideoChannel, checkTmpIsEmpty, @@ -32,16 +31,16 @@ import { wait, webtorrentAdd } from '../../../../shared/extra-utils' +import { waitJobs } from '../../../../shared/extra-utils/server/jobs' import { addVideoCommentReply, addVideoCommentThread, deleteVideoComment, + findCommentId, getVideoCommentThreads, - getVideoThreadComments, - findCommentId + getVideoThreadComments } from '../../../../shared/extra-utils/videos/video-comments' -import { waitJobs } from '../../../../shared/extra-utils/server/jobs' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' +import { VideoComment, VideoCommentThreadTree, VideoPrivacy } from '../../../../shared/models/videos' const expect = chai.expect diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts index 615e0ea45..a5ff3a39d 100644 --- a/server/tests/api/videos/video-comments.ts +++ b/server/tests/api/videos/video-comments.ts @@ -2,7 +2,7 @@ import 'mocha' import * as chai from 'chai' - +import { VideoComment, VideoCommentAdmin, VideoCommentThreadTree } from '@shared/models' import { cleanupTests, testImage } from '../../../../shared/extra-utils' import { createUser, @@ -22,7 +22,6 @@ import { getVideoCommentThreads, getVideoThreadComments } from '../../../../shared/extra-utils/videos/video-comments' -import { VideoComment, VideoCommentAdmin, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' const expect = chai.expect diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index 7d4f7abb4..1d6bb6cf4 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts @@ -38,6 +38,7 @@ import { import { cleanupTests, flushAndRunMultipleServers, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers' import { getGoodVideoUrl, getMyVideoImports, importVideo } from '../../../shared/extra-utils/videos/video-imports' import { + VideoCommentThreadTree, VideoDetails, VideoImport, VideoImportState, @@ -45,7 +46,6 @@ import { VideoPlaylistPrivacy, VideoPrivacy } from '../../../shared/models/videos' -import { VideoCommentThreadTree } from '../../../shared/models/videos/video-comment.model' const expect = chai.expect -- cgit v1.2.3 From 428ccb8b7a44ce60cabb7401a5464cf5fcbd4dba Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 11 May 2021 12:04:47 +0200 Subject: Reorganize plugin models --- server/tests/api/check-params/plugins.ts | 12 ++++++------ server/tests/api/server/plugins.ts | 10 ++-------- 2 files changed, 8 insertions(+), 14 deletions(-) (limited to 'server/tests') diff --git a/server/tests/api/check-params/plugins.ts b/server/tests/api/check-params/plugins.ts index 6e540bcbb..a833fe6ff 100644 --- a/server/tests/api/check-params/plugins.ts +++ b/server/tests/api/check-params/plugins.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ import 'mocha' - +import { HttpStatusCode } from '@shared/core-utils' import { checkBadCountPagination, checkBadSortPagination, @@ -11,14 +11,14 @@ import { flushAndRunServer, immutableAssign, installPlugin, - makeGetRequest, makePostBodyRequest, makePutBodyRequest, + makeGetRequest, + makePostBodyRequest, + makePutBodyRequest, ServerInfo, setAccessTokensToServers, userLogin -} from '../../../../shared/extra-utils' -import { PluginType } from '../../../../shared/models/plugins/plugin.type' -import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugin.model' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' +} from '@shared/extra-utils' +import { PeerTubePlugin, PluginType } from '@shared/models' describe('Test server plugins API validators', function () { let server: ServerInfo diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts index 1c6eabe6d..3c09acc9a 100644 --- a/server/tests/api/server/plugins.ts +++ b/server/tests/api/server/plugins.ts @@ -28,14 +28,8 @@ import { updatePluginSettings, wait, waitUntilLog -} from '../../../../shared/extra-utils' -import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' -import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugin.model' -import { PluginPackageJson } from '../../../../shared/models/plugins/plugin-package-json.model' -import { PluginType } from '../../../../shared/models/plugins/plugin.type' -import { PublicServerSetting } from '../../../../shared/models/plugins/public-server.setting' -import { ServerConfig } from '../../../../shared/models/server' -import { User } from '../../../../shared/models/users' +} from '@shared/extra-utils' +import { PeerTubePlugin, PeerTubePluginIndex, PluginPackageJson, PluginType, PublicServerSetting, ServerConfig, User } from '@shared/models' const expect = chai.expect -- cgit v1.2.3 From a3c997b34cad79fce92c67951a3c8140a9888973 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 11 May 2021 14:23:49 +0200 Subject: Update README --- server/tests/api/server/handle-down.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'server/tests') diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts index fa1a3c444..fe4a0e100 100644 --- a/server/tests/api/server/handle-down.ts +++ b/server/tests/api/server/handle-down.ts @@ -346,10 +346,12 @@ describe('Test handle downs', function () { // Wait video expiration await wait(11000) - for (let i = 0; i < 3; i++) { - await getVideo(servers[1].url, videoIdsServer1[i]) - await waitJobs([ servers[1] ]) - await wait(1500) + for (let i = 0; i < 5; i++) { + try { + await getVideo(servers[1].url, videoIdsServer1[i]) + await waitJobs([ servers[1] ]) + await wait(1500) + } catch {} } for (const id of videoIdsServer1) { -- cgit v1.2.3 From aea0b0e7cde7495e60fe07b4444067f53d35ce3f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 14 May 2021 12:04:44 +0200 Subject: Inject server config in HTML --- server/tests/client.ts | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'server/tests') diff --git a/server/tests/client.ts b/server/tests/client.ts index 3c99bcd1f..a385edd26 100644 --- a/server/tests/client.ts +++ b/server/tests/client.ts @@ -3,7 +3,7 @@ import 'mocha' import * as chai from 'chai' import * as request from 'supertest' -import { Account, VideoPlaylistPrivacy } from '@shared/models' +import { Account, HTMLServerConfig, ServerConfig, VideoPlaylistPrivacy } from '@shared/models' import { addVideoInPlaylist, cleanupTests, @@ -11,6 +11,7 @@ import { doubleFollow, flushAndRunMultipleServers, getAccount, + getConfig, getCustomConfig, getVideosList, makeHTMLRequest, @@ -25,13 +26,17 @@ import { waitJobs } from '../../shared/extra-utils' import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' +import { omit } from 'lodash' const expect = chai.expect -function checkIndexTags (html: string, title: string, description: string, css: string) { +function checkIndexTags (html: string, title: string, description: string, css: string, config: ServerConfig) { expect(html).to.contain('' + title + '') expect(html).to.contain('') expect(html).to.contain('') + + const htmlConfig: HTMLServerConfig = omit(config, 'signup') + expect(html).to.contain(``) } describe('Test a client controllers', function () { @@ -296,10 +301,11 @@ describe('Test a client controllers', function () { describe('Index HTML', function () { it('Should have valid index html tags (title, description...)', async function () { + const resConfig = await getConfig(servers[0].url) const res = await makeHTMLRequest(servers[0].url, '/videos/trending') const description = 'PeerTube, an ActivityPub-federated video streaming platform using P2P directly in your web browser.' - checkIndexTags(res.text, 'PeerTube', description, '') + checkIndexTags(res.text, 'PeerTube', description, '', resConfig.body) }) it('Should update the customized configuration and have the correct index html tags', async function () { @@ -318,15 +324,17 @@ describe('Test a client controllers', function () { } }) + const resConfig = await getConfig(servers[0].url) const res = await makeHTMLRequest(servers[0].url, '/videos/trending') - checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }') + checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', resConfig.body) }) it('Should have valid index html updated tags (title, description...)', async function () { + const resConfig = await getConfig(servers[0].url) const res = await makeHTMLRequest(servers[0].url, '/videos/trending') - checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }') + checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', resConfig.body) }) it('Should use the original video URL for the canonical tag', async function () { @@ -350,6 +358,16 @@ describe('Test a client controllers', function () { }) }) + describe('Embed HTML', function () { + + it('Should have the correct embed html tags', async function () { + const resConfig = await getConfig(servers[0].url) + const res = await makeHTMLRequest(servers[0].url, servers[0].video.embedPath) + + checkIndexTags(res.text, 'PeerTube updated', 'my short description', 'body { background-color: red; }', resConfig.body) + }) + }) + after(async function () { await cleanupTests(servers) }) -- cgit v1.2.3 From 008af5c9bb26b6a28db604d10356b4272d9c0432 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 25 May 2021 10:08:29 +0200 Subject: Fix broadcast message log level --- server/tests/api/server/plugins.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/tests') diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts index 1c6eabe6d..f4190c352 100644 --- a/server/tests/api/server/plugins.ts +++ b/server/tests/api/server/plugins.ts @@ -290,7 +290,7 @@ describe('Test plugins', function () { }) it('Should update the plugin and the theme', async function () { - this.timeout(30000) + this.timeout(90000) // Wait the scheduler that get the latest plugins versions await wait(6000) -- cgit v1.2.3 From 31a911190b27d93f6324da3d826f96c7fbc5deb6 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 25 May 2021 10:08:29 +0200 Subject: Fix broadcast message log level --- server/tests/api/server/plugins.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/tests') diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts index 3c09acc9a..6046ab97e 100644 --- a/server/tests/api/server/plugins.ts +++ b/server/tests/api/server/plugins.ts @@ -284,7 +284,7 @@ describe('Test plugins', function () { }) it('Should update the plugin and the theme', async function () { - this.timeout(30000) + this.timeout(90000) // Wait the scheduler that get the latest plugins versions await wait(6000) -- cgit v1.2.3 From fc8f15d202e715667c5b726b4f3e7d252381c6d0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 25 May 2021 13:14:05 +0200 Subject: Increase plugin transcoding tests timeout --- server/tests/plugins/plugin-transcoding.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'server/tests') diff --git a/server/tests/plugins/plugin-transcoding.ts b/server/tests/plugins/plugin-transcoding.ts index c834b6985..eefb2294d 100644 --- a/server/tests/plugins/plugin-transcoding.ts +++ b/server/tests/plugins/plugin-transcoding.ts @@ -125,7 +125,7 @@ describe('Test transcoding plugins', function () { }) it('Should not use the plugin profile if not chosen by the admin', async function () { - this.timeout(120000) + this.timeout(240000) const videoUUID = (await uploadVideoAndGetId({ server, videoName: 'video' })).uuid await waitJobs([ server ]) @@ -134,7 +134,7 @@ describe('Test transcoding plugins', function () { }) it('Should use the vod profile', async function () { - this.timeout(120000) + this.timeout(240000) await updateConf(server, 'low-vod', 'default') @@ -145,7 +145,7 @@ describe('Test transcoding plugins', function () { }) it('Should apply input options in vod profile', async function () { - this.timeout(120000) + this.timeout(240000) await updateConf(server, 'input-options-vod', 'default') @@ -156,7 +156,7 @@ describe('Test transcoding plugins', function () { }) it('Should apply the scale filter in vod profile', async function () { - this.timeout(120000) + this.timeout(240000) await updateConf(server, 'bad-scale-vod', 'default') @@ -172,7 +172,7 @@ describe('Test transcoding plugins', function () { }) it('Should not use the plugin profile if not chosen by the admin', async function () { - this.timeout(120000) + this.timeout(240000) const liveVideoId = await createLiveWrapper(server) @@ -184,7 +184,7 @@ describe('Test transcoding plugins', function () { }) it('Should use the live profile', async function () { - this.timeout(120000) + this.timeout(240000) await updateConf(server, 'low-vod', 'low-live') @@ -198,7 +198,7 @@ describe('Test transcoding plugins', function () { }) it('Should apply the input options on live profile', async function () { - this.timeout(120000) + this.timeout(240000) await updateConf(server, 'low-vod', 'input-options-live') @@ -212,7 +212,7 @@ describe('Test transcoding plugins', function () { }) it('Should apply the scale filter name on live profile', async function () { - this.timeout(120000) + this.timeout(240000) await updateConf(server, 'low-vod', 'bad-scale-live') @@ -223,7 +223,7 @@ describe('Test transcoding plugins', function () { }) it('Should default to the default profile if the specified profile does not exist', async function () { - this.timeout(120000) + this.timeout(240000) await uninstallPlugin({ url: server.url, accessToken: server.accessToken, npmName: 'peertube-plugin-test-transcoding-one' }) @@ -268,7 +268,7 @@ describe('Test transcoding plugins', function () { }) it('Should use the new live encoders', async function () { - this.timeout(120000) + this.timeout(240000) const liveVideoId = await createLiveWrapper(server) -- cgit v1.2.3 From 2539932e16129992a2c0889b4ff527c265a8e2c7 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 27 May 2021 15:59:55 +0200 Subject: Instance homepage support (#4007) * Prepare homepage parsers * Add ability to update instance hompage * Add ability to set homepage as landing page * Add homepage preview in admin * Dynamically update left menu for homepage * Inject home content in homepage * Add videos list and channel miniature custom markup * Remove unused elements in markup service --- server/tests/api/check-params/custom-pages.ts | 81 +++++++++++++++++++++++++ server/tests/api/check-params/index.ts | 1 + server/tests/api/server/homepage.ts | 85 +++++++++++++++++++++++++++ server/tests/api/server/index.ts | 1 + 4 files changed, 168 insertions(+) create mode 100644 server/tests/api/check-params/custom-pages.ts create mode 100644 server/tests/api/server/homepage.ts (limited to 'server/tests') diff --git a/server/tests/api/check-params/custom-pages.ts b/server/tests/api/check-params/custom-pages.ts new file mode 100644 index 000000000..74ca3384c --- /dev/null +++ b/server/tests/api/check-params/custom-pages.ts @@ -0,0 +1,81 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ + +import 'mocha' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' +import { + cleanupTests, + createUser, + flushAndRunServer, + ServerInfo, + setAccessTokensToServers, + userLogin +} from '../../../../shared/extra-utils' +import { makeGetRequest, makePutBodyRequest } from '../../../../shared/extra-utils/requests/requests' + +describe('Test custom pages validators', function () { + const path = '/api/v1/custom-pages/homepage/instance' + + let server: ServerInfo + let userAccessToken: string + + // --------------------------------------------------------------- + + before(async function () { + this.timeout(120000) + + server = await flushAndRunServer(1) + await setAccessTokensToServers([ server ]) + + const user = { username: 'user1', password: 'password' } + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) + + userAccessToken = await userLogin(server, user) + }) + + describe('When updating instance homepage', function () { + + it('Should fail with an unauthenticated user', async function () { + await makePutBodyRequest({ + url: server.url, + path, + fields: { content: 'super content' }, + statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401 + }) + }) + + it('Should fail with a non admin user', async function () { + await makePutBodyRequest({ + url: server.url, + path, + token: userAccessToken, + fields: { content: 'super content' }, + statusCodeExpected: HttpStatusCode.FORBIDDEN_403 + }) + }) + + it('Should succeed with the correct params', async function () { + await makePutBodyRequest({ + url: server.url, + path, + token: server.accessToken, + fields: { content: 'super content' }, + statusCodeExpected: HttpStatusCode.NO_CONTENT_204 + }) + }) + }) + + describe('When getting instance homapage', function () { + + it('Should succeed with the correct params', async function () { + await makeGetRequest({ + url: server.url, + path, + statusCodeExpected: HttpStatusCode.OK_200 + }) + }) + }) + + after(async function () { + await cleanupTests([ server ]) + }) +}) diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts index 143515838..ce2335e42 100644 --- a/server/tests/api/check-params/index.ts +++ b/server/tests/api/check-params/index.ts @@ -3,6 +3,7 @@ import './accounts' import './blocklist' import './bulk' import './config' +import './custom-pages' import './contact-form' import './debug' import './follows' diff --git a/server/tests/api/server/homepage.ts b/server/tests/api/server/homepage.ts new file mode 100644 index 000000000..e8ba89ca6 --- /dev/null +++ b/server/tests/api/server/homepage.ts @@ -0,0 +1,85 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ + +import 'mocha' +import * as chai from 'chai' +import { HttpStatusCode } from '@shared/core-utils' +import { CustomPage, ServerConfig } from '@shared/models' +import { + cleanupTests, + flushAndRunServer, + getConfig, + getInstanceHomepage, + killallServers, + reRunServer, + ServerInfo, + setAccessTokensToServers, + updateInstanceHomepage +} from '../../../../shared/extra-utils/index' + +const expect = chai.expect + +async function getHomepageState (server: ServerInfo) { + const res = await getConfig(server.url) + + const config = res.body as ServerConfig + return config.homepage.enabled +} + +describe('Test instance homepage actions', function () { + let server: ServerInfo + + before(async function () { + this.timeout(30000) + + server = await flushAndRunServer(1) + await setAccessTokensToServers([ server ]) + }) + + it('Should not have a homepage', async function () { + const state = await getHomepageState(server) + expect(state).to.be.false + + await getInstanceHomepage(server.url, HttpStatusCode.NOT_FOUND_404) + }) + + it('Should set a homepage', async function () { + await updateInstanceHomepage(server.url, server.accessToken, '') + + const res = await getInstanceHomepage(server.url) + const page: CustomPage = res.body + expect(page.content).to.equal('') + + const state = await getHomepageState(server) + expect(state).to.be.true + }) + + it('Should have the same homepage after a restart', async function () { + this.timeout(30000) + + killallServers([ server ]) + + await reRunServer(server) + + const res = await getInstanceHomepage(server.url) + const page: CustomPage = res.body + expect(page.content).to.equal('') + + const state = await getHomepageState(server) + expect(state).to.be.true + }) + + it('Should empty the homepage', async function () { + await updateInstanceHomepage(server.url, server.accessToken, '') + + const res = await getInstanceHomepage(server.url) + const page: CustomPage = res.body + expect(page.content).to.be.empty + + const state = await getHomepageState(server) + expect(state).to.be.false + }) + + after(async function () { + await cleanupTests([ server ]) + }) +}) diff --git a/server/tests/api/server/index.ts b/server/tests/api/server/index.ts index be743973a..56e6eb5da 100644 --- a/server/tests/api/server/index.ts +++ b/server/tests/api/server/index.ts @@ -5,6 +5,7 @@ import './email' import './follow-constraints' import './follows' import './follows-moderation' +import './homepage' import './handle-down' import './jobs' import './logs' -- cgit v1.2.3