From 3a4992633ee62d5edfbb484d9c6bcb3cf158489d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 31 Jul 2023 14:34:36 +0200 Subject: Migrate server to ESM Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports) --- server/tests/plugins/action-hooks.ts | 298 ---------- server/tests/plugins/external-auth.ts | 436 -------------- server/tests/plugins/filter-hooks.ts | 909 ----------------------------- server/tests/plugins/html-injection.ts | 73 --- server/tests/plugins/id-and-pass-auth.ts | 242 -------- server/tests/plugins/index.ts | 13 - server/tests/plugins/plugin-helpers.ts | 383 ------------ server/tests/plugins/plugin-router.ts | 105 ---- server/tests/plugins/plugin-storage.ts | 94 --- server/tests/plugins/plugin-transcoding.ts | 279 --------- server/tests/plugins/plugin-unloading.ts | 75 --- server/tests/plugins/plugin-websocket.ts | 70 --- server/tests/plugins/translations.ts | 74 --- server/tests/plugins/video-constants.ts | 180 ------ 14 files changed, 3231 deletions(-) delete mode 100644 server/tests/plugins/action-hooks.ts delete mode 100644 server/tests/plugins/external-auth.ts delete mode 100644 server/tests/plugins/filter-hooks.ts delete mode 100644 server/tests/plugins/html-injection.ts delete mode 100644 server/tests/plugins/id-and-pass-auth.ts delete mode 100644 server/tests/plugins/index.ts delete mode 100644 server/tests/plugins/plugin-helpers.ts delete mode 100644 server/tests/plugins/plugin-router.ts delete mode 100644 server/tests/plugins/plugin-storage.ts delete mode 100644 server/tests/plugins/plugin-transcoding.ts delete mode 100644 server/tests/plugins/plugin-unloading.ts delete mode 100644 server/tests/plugins/plugin-websocket.ts delete mode 100644 server/tests/plugins/translations.ts delete mode 100644 server/tests/plugins/video-constants.ts (limited to 'server/tests/plugins') diff --git a/server/tests/plugins/action-hooks.ts b/server/tests/plugins/action-hooks.ts deleted file mode 100644 index 773be0d76..000000000 --- a/server/tests/plugins/action-hooks.ts +++ /dev/null @@ -1,298 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { ServerHookName, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' -import { - cleanupTests, - createMultipleServers, - doubleFollow, - killallServers, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers, - setDefaultVideoChannel, - stopFfmpeg, - waitJobs -} from '@shared/server-commands' - -describe('Test plugin action hooks', function () { - let servers: PeerTubeServer[] - let videoUUID: string - let threadId: number - - function checkHook (hook: ServerHookName, strictCount = true, count = 1) { - return servers[0].servers.waitUntilLog('Run hook ' + hook, count, strictCount) - } - - before(async function () { - this.timeout(120000) - - servers = await createMultipleServers(2) - await setAccessTokensToServers(servers) - await setDefaultVideoChannel(servers) - - await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath() }) - - await killallServers([ servers[0] ]) - - await servers[0].run({ - live: { - enabled: true - } - }) - - await servers[0].config.enableFileUpdate() - - await doubleFollow(servers[0], servers[1]) - }) - - describe('Application hooks', function () { - it('Should run action:application.listening', async function () { - await checkHook('action:application.listening') - }) - }) - - describe('Videos hooks', function () { - - it('Should run action:api.video.uploaded', async function () { - const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video' } }) - videoUUID = uuid - - await checkHook('action:api.video.uploaded') - }) - - it('Should run action:api.video.updated', async function () { - await servers[0].videos.update({ id: videoUUID, attributes: { name: 'video updated' } }) - - await checkHook('action:api.video.updated') - }) - - it('Should run action:api.video.viewed', async function () { - await servers[0].views.simulateView({ id: videoUUID }) - - await checkHook('action:api.video.viewed') - }) - - it('Should run action:api.video.file-updated', async function () { - await servers[0].videos.replaceSourceFile({ videoId: videoUUID, fixture: 'video_short.mp4' }) - - await checkHook('action:api.video.file-updated') - }) - - it('Should run action:api.video.deleted', async function () { - await servers[0].videos.remove({ id: videoUUID }) - - await checkHook('action:api.video.deleted') - }) - - after(async function () { - const { uuid } = await servers[0].videos.quickUpload({ name: 'video' }) - videoUUID = uuid - }) - }) - - describe('Video channel hooks', function () { - const channelName = 'my_super_channel' - - it('Should run action:api.video-channel.created', async function () { - await servers[0].channels.create({ attributes: { name: channelName } }) - - await checkHook('action:api.video-channel.created') - }) - - it('Should run action:api.video-channel.updated', async function () { - await servers[0].channels.update({ channelName, attributes: { displayName: 'my display name' } }) - - await checkHook('action:api.video-channel.updated') - }) - - it('Should run action:api.video-channel.deleted', async function () { - await servers[0].channels.delete({ channelName }) - - await checkHook('action:api.video-channel.deleted') - }) - }) - - describe('Live hooks', function () { - - it('Should run action:api.live-video.created', async function () { - const attributes = { - name: 'live', - privacy: VideoPrivacy.PUBLIC, - channelId: servers[0].store.channel.id - } - - await servers[0].live.create({ fields: attributes }) - - await checkHook('action:api.live-video.created') - }) - - it('Should run action:live.video.state.updated', async function () { - this.timeout(60000) - - const attributes = { - name: 'live', - privacy: VideoPrivacy.PUBLIC, - channelId: servers[0].store.channel.id - } - - const { uuid: liveVideoId } = await servers[0].live.create({ fields: attributes }) - const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoId }) - await servers[0].live.waitUntilPublished({ videoId: liveVideoId }) - await waitJobs(servers) - - await checkHook('action:live.video.state.updated', true, 1) - - await stopFfmpeg(ffmpegCommand) - await servers[0].live.waitUntilEnded({ videoId: liveVideoId }) - await waitJobs(servers) - - await checkHook('action:live.video.state.updated', true, 2) - }) - }) - - describe('Comments hooks', function () { - it('Should run action:api.video-thread.created', async function () { - const created = await servers[0].comments.createThread({ videoId: videoUUID, text: 'thread' }) - threadId = created.id - - await checkHook('action:api.video-thread.created') - }) - - it('Should run action:api.video-comment-reply.created', async function () { - await servers[0].comments.addReply({ videoId: videoUUID, toCommentId: threadId, text: 'reply' }) - - await checkHook('action:api.video-comment-reply.created') - }) - - it('Should run action:api.video-comment.deleted', async function () { - await servers[0].comments.delete({ videoId: videoUUID, commentId: threadId }) - - await checkHook('action:api.video-comment.deleted') - }) - }) - - describe('Captions hooks', function () { - it('Should run action:api.video-caption.created', async function () { - await servers[0].captions.add({ videoId: videoUUID, language: 'en', fixture: 'subtitle-good.srt' }) - - await checkHook('action:api.video-caption.created') - }) - - it('Should run action:api.video-caption.deleted', async function () { - await servers[0].captions.delete({ videoId: videoUUID, language: 'en' }) - - await checkHook('action:api.video-caption.deleted') - }) - }) - - describe('Users hooks', function () { - let userId: number - - it('Should run action:api.user.registered', async function () { - await servers[0].registrations.register({ username: 'registered_user' }) - - await checkHook('action:api.user.registered') - }) - - it('Should run action:api.user.created', async function () { - const user = await servers[0].users.create({ username: 'created_user' }) - userId = user.id - - await checkHook('action:api.user.created') - }) - - it('Should run action:api.user.oauth2-got-token', async function () { - await servers[0].login.login({ user: { username: 'created_user' } }) - - await checkHook('action:api.user.oauth2-got-token') - }) - - it('Should run action:api.user.blocked', async function () { - await servers[0].users.banUser({ userId }) - - await checkHook('action:api.user.blocked') - }) - - it('Should run action:api.user.unblocked', async function () { - await servers[0].users.unbanUser({ userId }) - - await checkHook('action:api.user.unblocked') - }) - - it('Should run action:api.user.updated', async function () { - await servers[0].users.update({ userId, videoQuota: 50 }) - - await checkHook('action:api.user.updated') - }) - - it('Should run action:api.user.deleted', async function () { - await servers[0].users.remove({ userId }) - - await checkHook('action:api.user.deleted') - }) - }) - - describe('Playlist hooks', function () { - let playlistId: number - let videoId: number - - before(async function () { - { - const { id } = await servers[0].playlists.create({ - attributes: { - displayName: 'My playlist', - privacy: VideoPlaylistPrivacy.PRIVATE - } - }) - playlistId = id - } - - { - const { id } = await servers[0].videos.upload({ attributes: { name: 'my super name' } }) - videoId = id - } - }) - - it('Should run action:api.video-playlist-element.created', async function () { - await servers[0].playlists.addElement({ playlistId, attributes: { videoId } }) - - await checkHook('action:api.video-playlist-element.created') - }) - }) - - describe('Notification hook', function () { - - it('Should run action:notifier.notification.created', async function () { - await checkHook('action:notifier.notification.created', false) - }) - }) - - describe('Activity Pub hooks', function () { - let videoUUID: string - - it('Should run action:activity-pub.remote-video.created', async function () { - this.timeout(30000) - - const { uuid } = await servers[1].videos.quickUpload({ name: 'remote video' }) - videoUUID = uuid - - await servers[0].servers.waitUntilLog('action:activity-pub.remote-video.created - AP remote video - video remote video') - }) - - it('Should run action:activity-pub.remote-video.updated', async function () { - this.timeout(30000) - - await servers[1].videos.update({ id: videoUUID, attributes: { name: 'remote video updated' } }) - - await servers[0].servers.waitUntilLog( - 'action:activity-pub.remote-video.updated - AP remote video updated - video remote video updated', - 1, - false - ) - }) - }) - - after(async function () { - await cleanupTests(servers) - }) -}) diff --git a/server/tests/plugins/external-auth.ts b/server/tests/plugins/external-auth.ts deleted file mode 100644 index e4015939a..000000000 --- a/server/tests/plugins/external-auth.ts +++ /dev/null @@ -1,436 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { wait } from '@shared/core-utils' -import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models' -import { - cleanupTests, - createSingleServer, - decodeQueryString, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers -} from '@shared/server-commands' - -async function loginExternal (options: { - server: PeerTubeServer - npmName: string - authName: string - username: string - query?: any - expectedStatus?: HttpStatusCode - expectedStatusStep2?: HttpStatusCode -}) { - const res = await options.server.plugins.getExternalAuth({ - npmName: options.npmName, - npmVersion: '0.0.1', - authName: options.authName, - query: options.query, - expectedStatus: options.expectedStatus || HttpStatusCode.FOUND_302 - }) - - if (res.status !== HttpStatusCode.FOUND_302) return - - const location = res.header.location - const { externalAuthToken } = decodeQueryString(location) - - const resLogin = await options.server.login.loginUsingExternalToken({ - username: options.username, - externalAuthToken: externalAuthToken as string, - expectedStatus: options.expectedStatusStep2 - }) - - return resLogin.body -} - -describe('Test external auth plugins', function () { - let server: PeerTubeServer - - let cyanAccessToken: string - let cyanRefreshToken: string - - let kefkaAccessToken: string - let kefkaRefreshToken: string - let kefkaId: number - - let externalAuthToken: string - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1, { - rates_limit: { - login: { - max: 30 - } - } - }) - - await setAccessTokensToServers([ server ]) - - for (const suffix of [ 'one', 'two', 'three' ]) { - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-external-auth-' + suffix) }) - } - }) - - it('Should display the correct configuration', async function () { - const config = await server.config.getConfig() - - const auths = config.plugin.registeredExternalAuths - expect(auths).to.have.lengthOf(9) - - const auth2 = auths.find((a) => a.authName === 'external-auth-2') - expect(auth2).to.exist - expect(auth2.authDisplayName).to.equal('External Auth 2') - expect(auth2.npmName).to.equal('peertube-plugin-test-external-auth-one') - }) - - it('Should redirect for a Cyan login', async function () { - const res = await server.plugins.getExternalAuth({ - npmName: 'test-external-auth-one', - npmVersion: '0.0.1', - authName: 'external-auth-1', - query: { - username: 'cyan' - }, - expectedStatus: HttpStatusCode.FOUND_302 - }) - - const location = res.header.location - expect(location.startsWith('/login?')).to.be.true - - const searchParams = decodeQueryString(location) - - expect(searchParams.externalAuthToken).to.exist - expect(searchParams.username).to.equal('cyan') - - externalAuthToken = searchParams.externalAuthToken as string - }) - - it('Should reject auto external login with a missing or invalid token', async function () { - const command = server.login - - await command.loginUsingExternalToken({ username: 'cyan', externalAuthToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await command.loginUsingExternalToken({ username: 'cyan', externalAuthToken: 'blabla', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - }) - - it('Should reject auto external login with a missing or invalid username', async function () { - const command = server.login - - await command.loginUsingExternalToken({ username: '', externalAuthToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await command.loginUsingExternalToken({ username: '', externalAuthToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - }) - - it('Should reject auto external login with an expired token', async function () { - this.timeout(15000) - - await wait(5000) - - await server.login.loginUsingExternalToken({ - username: 'cyan', - externalAuthToken, - expectedStatus: HttpStatusCode.BAD_REQUEST_400 - }) - - await server.servers.waitUntilLog('expired external auth token', 4) - }) - - it('Should auto login Cyan, create the user and use the token', async function () { - { - const res = await loginExternal({ - server, - npmName: 'test-external-auth-one', - authName: 'external-auth-1', - query: { - username: 'cyan' - }, - username: 'cyan' - }) - - cyanAccessToken = res.access_token - cyanRefreshToken = res.refresh_token - } - - { - const body = await server.users.getMyInfo({ token: cyanAccessToken }) - expect(body.username).to.equal('cyan') - expect(body.account.displayName).to.equal('cyan') - expect(body.email).to.equal('cyan@example.com') - expect(body.role.id).to.equal(UserRole.USER) - expect(body.adminFlags).to.equal(UserAdminFlag.NONE) - expect(body.videoQuota).to.equal(5242880) - expect(body.videoQuotaDaily).to.equal(-1) - } - }) - - it('Should auto login Kefka, create the user and use the token', async function () { - { - const res = await loginExternal({ - server, - npmName: 'test-external-auth-one', - authName: 'external-auth-2', - username: 'kefka' - }) - - kefkaAccessToken = res.access_token - kefkaRefreshToken = res.refresh_token - } - - { - const body = await server.users.getMyInfo({ token: kefkaAccessToken }) - expect(body.username).to.equal('kefka') - expect(body.account.displayName).to.equal('Kefka Palazzo') - expect(body.email).to.equal('kefka@example.com') - expect(body.role.id).to.equal(UserRole.ADMINISTRATOR) - expect(body.adminFlags).to.equal(UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST) - expect(body.videoQuota).to.equal(42000) - expect(body.videoQuotaDaily).to.equal(42100) - - kefkaId = body.id - } - }) - - it('Should refresh Cyan token, but not Kefka token', async function () { - { - const resRefresh = await server.login.refreshToken({ refreshToken: cyanRefreshToken }) - cyanAccessToken = resRefresh.body.access_token - cyanRefreshToken = resRefresh.body.refresh_token - - const body = await server.users.getMyInfo({ token: cyanAccessToken }) - expect(body.username).to.equal('cyan') - } - - { - await server.login.refreshToken({ refreshToken: kefkaRefreshToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - } - }) - - it('Should update Cyan profile', async function () { - await server.users.updateMe({ - token: cyanAccessToken, - displayName: 'Cyan Garamonde', - description: 'Retainer to the king of Doma' - }) - - const body = await server.users.getMyInfo({ token: cyanAccessToken }) - expect(body.account.displayName).to.equal('Cyan Garamonde') - expect(body.account.description).to.equal('Retainer to the king of Doma') - }) - - it('Should logout Cyan', async function () { - await server.login.logout({ token: cyanAccessToken }) - }) - - it('Should have logged out Cyan', async function () { - await server.servers.waitUntilLog('On logout cyan') - - await server.users.getMyInfo({ token: cyanAccessToken, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) - }) - - it('Should login Cyan and keep the old existing profile', async function () { - { - const res = await loginExternal({ - server, - npmName: 'test-external-auth-one', - authName: 'external-auth-1', - query: { - username: 'cyan' - }, - username: 'cyan' - }) - - cyanAccessToken = res.access_token - } - - const body = await server.users.getMyInfo({ token: cyanAccessToken }) - expect(body.username).to.equal('cyan') - expect(body.account.displayName).to.equal('Cyan Garamonde') - expect(body.account.description).to.equal('Retainer to the king of Doma') - expect(body.role.id).to.equal(UserRole.USER) - }) - - it('Should login Kefka and update the profile', async function () { - { - await server.users.update({ userId: kefkaId, videoQuota: 43000, videoQuotaDaily: 43100 }) - await server.users.updateMe({ token: kefkaAccessToken, displayName: 'kefka updated' }) - - const body = await server.users.getMyInfo({ token: kefkaAccessToken }) - expect(body.username).to.equal('kefka') - expect(body.account.displayName).to.equal('kefka updated') - expect(body.videoQuota).to.equal(43000) - expect(body.videoQuotaDaily).to.equal(43100) - } - - { - const res = await loginExternal({ - server, - npmName: 'test-external-auth-one', - authName: 'external-auth-2', - username: 'kefka' - }) - - kefkaAccessToken = res.access_token - kefkaRefreshToken = res.refresh_token - - const body = await server.users.getMyInfo({ token: kefkaAccessToken }) - expect(body.username).to.equal('kefka') - expect(body.account.displayName).to.equal('Kefka Palazzo') - expect(body.videoQuota).to.equal(42000) - expect(body.videoQuotaDaily).to.equal(43100) - } - }) - - it('Should not update an external auth email', async function () { - await server.users.updateMe({ - token: cyanAccessToken, - email: 'toto@example.com', - currentPassword: 'toto', - expectedStatus: HttpStatusCode.BAD_REQUEST_400 - }) - }) - - it('Should reject token of Kefka by the plugin hook', async function () { - await wait(5000) - - await server.users.getMyInfo({ token: kefkaAccessToken, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) - }) - - it('Should unregister external-auth-2 and do not login existing Kefka', async function () { - await server.plugins.updateSettings({ - npmName: 'peertube-plugin-test-external-auth-one', - settings: { disableKefka: true } - }) - - await server.login.login({ user: { username: 'kefka', password: 'fake' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - - await loginExternal({ - server, - npmName: 'test-external-auth-one', - authName: 'external-auth-2', - query: { - username: 'kefka' - }, - username: 'kefka', - expectedStatus: HttpStatusCode.NOT_FOUND_404 - }) - }) - - it('Should have disabled this auth', async function () { - const config = await server.config.getConfig() - - const auths = config.plugin.registeredExternalAuths - expect(auths).to.have.lengthOf(8) - - const auth1 = auths.find(a => a.authName === 'external-auth-2') - expect(auth1).to.not.exist - }) - - it('Should uninstall the plugin one and do not login Cyan', async function () { - await server.plugins.uninstall({ npmName: 'peertube-plugin-test-external-auth-one' }) - - await loginExternal({ - server, - npmName: 'test-external-auth-one', - authName: 'external-auth-1', - query: { - username: 'cyan' - }, - username: 'cyan', - expectedStatus: HttpStatusCode.NOT_FOUND_404 - }) - - await server.login.login({ user: { username: 'cyan', password: null }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await server.login.login({ user: { username: 'cyan', password: '' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await server.login.login({ user: { username: 'cyan', password: 'fake' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - }) - - it('Should not login kefka with another plugin', async function () { - await loginExternal({ - server, - npmName: 'test-external-auth-two', - authName: 'external-auth-4', - username: 'kefka2', - expectedStatusStep2: HttpStatusCode.BAD_REQUEST_400 - }) - - await loginExternal({ - server, - npmName: 'test-external-auth-two', - authName: 'external-auth-4', - username: 'kefka', - expectedStatusStep2: HttpStatusCode.BAD_REQUEST_400 - }) - }) - - it('Should not login an existing user email', async function () { - await server.users.create({ username: 'existing_user', password: 'super_password' }) - - await loginExternal({ - server, - npmName: 'test-external-auth-two', - authName: 'external-auth-6', - username: 'existing_user', - expectedStatusStep2: HttpStatusCode.BAD_REQUEST_400 - }) - }) - - it('Should be able to login an existing user username and channel', async function () { - await server.users.create({ username: 'existing_user2' }) - await server.users.create({ username: 'existing_user2-1_channel' }) - - // Test twice to ensure we don't generate a username on every login - for (let i = 0; i < 2; i++) { - const res = await loginExternal({ - server, - npmName: 'test-external-auth-two', - authName: 'external-auth-7', - username: 'existing_user2' - }) - - const token = res.access_token - - const myInfo = await server.users.getMyInfo({ token }) - expect(myInfo.username).to.equal('existing_user2-1') - - expect(myInfo.videoChannels[0].name).to.equal('existing_user2-1_channel-1') - } - }) - - it('Should display the correct configuration', async function () { - const config = await server.config.getConfig() - - const auths = config.plugin.registeredExternalAuths - expect(auths).to.have.lengthOf(7) - - const auth2 = auths.find((a) => a.authName === 'external-auth-2') - expect(auth2).to.not.exist - }) - - after(async function () { - await cleanupTests([ server ]) - }) - - it('Should forward the redirectUrl if the plugin returns one', async function () { - const resLogin = await loginExternal({ - server, - npmName: 'test-external-auth-three', - authName: 'external-auth-7', - username: 'cid' - }) - - const { redirectUrl } = await server.login.logout({ token: resLogin.access_token }) - expect(redirectUrl).to.equal('https://example.com/redirectUrl') - }) - - it('Should call the plugin\'s onLogout method with the request', async function () { - const resLogin = await loginExternal({ - server, - npmName: 'test-external-auth-three', - authName: 'external-auth-8', - username: 'cid' - }) - - const { redirectUrl } = await server.login.logout({ token: resLogin.access_token }) - expect(redirectUrl).to.equal('https://example.com/redirectUrl?access_token=' + resLogin.access_token) - }) -}) diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts deleted file mode 100644 index 8382b400f..000000000 --- a/server/tests/plugins/filter-hooks.ts +++ /dev/null @@ -1,909 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { - HttpStatusCode, - PeerTubeProblemDocument, - VideoDetails, - VideoImportState, - VideoPlaylist, - VideoPlaylistPrivacy, - VideoPrivacy -} from '@shared/models' -import { - cleanupTests, - createMultipleServers, - doubleFollow, - makeActivityPubGetRequest, - makeGetRequest, - makeRawRequest, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers, - setDefaultVideoChannel, - waitJobs -} from '@shared/server-commands' -import { FIXTURE_URLS } from '../shared' - -describe('Test plugin filter hooks', function () { - let servers: PeerTubeServer[] - let videoUUID: string - let threadId: number - let videoPlaylistUUID: string - - before(async function () { - this.timeout(120000) - - servers = await createMultipleServers(2) - await setAccessTokensToServers(servers) - await setDefaultVideoChannel(servers) - await doubleFollow(servers[0], servers[1]) - - await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath() }) - await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath('-filter-translations') }) - { - ({ uuid: videoPlaylistUUID } = await servers[0].playlists.create({ - attributes: { - displayName: 'my super playlist', - privacy: VideoPlaylistPrivacy.PUBLIC, - description: 'my super description', - videoChannelId: servers[0].store.channel.id - } - })) - } - - for (let i = 0; i < 10; i++) { - const video = await servers[0].videos.upload({ attributes: { name: 'default video ' + i } }) - await servers[0].playlists.addElement({ playlistId: videoPlaylistUUID, attributes: { videoId: video.id } }) - } - - const { data } = await servers[0].videos.list() - videoUUID = data[0].uuid - - await servers[0].config.updateCustomSubConfig({ - newConfig: { - live: { enabled: true }, - signup: { enabled: true }, - videoFile: { - update: { - enabled: true - } - }, - import: { - videos: { - http: { enabled: true }, - torrent: { enabled: true } - } - } - } - }) - - // Root subscribes to itself - await servers[0].subscriptions.add({ targetUri: 'root_channel@' + servers[0].host }) - }) - - describe('Videos', function () { - - it('Should run filter:api.videos.list.params', async function () { - const { data } = await servers[0].videos.list({ start: 0, count: 2 }) - - // 2 plugins do +1 to the count parameter - expect(data).to.have.lengthOf(4) - }) - - it('Should run filter:api.videos.list.result', async function () { - const { total } = await servers[0].videos.list({ start: 0, count: 0 }) - - // Plugin do +1 to the total result - expect(total).to.equal(11) - }) - - it('Should run filter:api.video-playlist.videos.list.params', async function () { - const { data } = await servers[0].playlists.listVideos({ - count: 2, - playlistId: videoPlaylistUUID - }) - - // 1 plugin do +1 to the count parameter - expect(data).to.have.lengthOf(3) - }) - - it('Should run filter:api.video-playlist.videos.list.result', async function () { - const { total } = await servers[0].playlists.listVideos({ - count: 0, - playlistId: videoPlaylistUUID - }) - - // Plugin do +1 to the total result - expect(total).to.equal(11) - }) - - it('Should run filter:api.accounts.videos.list.params', async function () { - const { data } = await servers[0].videos.listByAccount({ handle: 'root', start: 0, count: 2 }) - - // 1 plugin do +1 to the count parameter - expect(data).to.have.lengthOf(3) - }) - - it('Should run filter:api.accounts.videos.list.result', async function () { - const { total } = await servers[0].videos.listByAccount({ handle: 'root', start: 0, count: 2 }) - - // Plugin do +2 to the total result - expect(total).to.equal(12) - }) - - it('Should run filter:api.video-channels.videos.list.params', async function () { - const { data } = await servers[0].videos.listByChannel({ handle: 'root_channel', start: 0, count: 2 }) - - // 1 plugin do +3 to the count parameter - expect(data).to.have.lengthOf(5) - }) - - it('Should run filter:api.video-channels.videos.list.result', async function () { - const { total } = await servers[0].videos.listByChannel({ handle: 'root_channel', start: 0, count: 2 }) - - // Plugin do +3 to the total result - expect(total).to.equal(13) - }) - - it('Should run filter:api.user.me.videos.list.params', async function () { - const { data } = await servers[0].videos.listMyVideos({ start: 0, count: 2 }) - - // 1 plugin do +4 to the count parameter - expect(data).to.have.lengthOf(6) - }) - - it('Should run filter:api.user.me.videos.list.result', async function () { - const { total } = await servers[0].videos.listMyVideos({ start: 0, count: 2 }) - - // Plugin do +4 to the total result - expect(total).to.equal(14) - }) - - it('Should run filter:api.user.me.subscription-videos.list.params', async function () { - const { data } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 }) - - // 1 plugin do +1 to the count parameter - expect(data).to.have.lengthOf(3) - }) - - it('Should run filter:api.user.me.subscription-videos.list.result', async function () { - const { total } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 }) - - // Plugin do +4 to the total result - expect(total).to.equal(14) - }) - - it('Should run filter:api.video.get.result', async function () { - const video = await servers[0].videos.get({ id: videoUUID }) - expect(video.name).to.contain('<3') - }) - }) - - describe('Video/live/import accept', function () { - - it('Should run filter:api.video.upload.accept.result', async function () { - const options = { attributes: { name: 'video with bad word' }, expectedStatus: HttpStatusCode.FORBIDDEN_403 } - await servers[0].videos.upload({ mode: 'legacy', ...options }) - await servers[0].videos.upload({ mode: 'resumable', ...options }) - }) - - it('Should run filter:api.video.update-file.accept.result', async function () { - const res = await servers[0].videos.replaceSourceFile({ - videoId: videoUUID, - fixture: 'video_short1.webm', - completedExpectedStatus: HttpStatusCode.FORBIDDEN_403 - }) - - expect((res as any)?.error).to.equal('no webm') - }) - - it('Should run filter:api.live-video.create.accept.result', async function () { - const attributes = { - name: 'video with bad word', - privacy: VideoPrivacy.PUBLIC, - channelId: servers[0].store.channel.id - } - - await servers[0].live.create({ fields: attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) - }) - - it('Should run filter:api.video.pre-import-url.accept.result', async function () { - const attributes = { - name: 'normal title', - privacy: VideoPrivacy.PUBLIC, - channelId: servers[0].store.channel.id, - targetUrl: FIXTURE_URLS.goodVideo + 'bad' - } - await servers[0].imports.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) - }) - - it('Should run filter:api.video.pre-import-torrent.accept.result', async function () { - const attributes = { - name: 'bad torrent', - privacy: VideoPrivacy.PUBLIC, - channelId: servers[0].store.channel.id, - torrentfile: 'video-720p.torrent' as any - } - await servers[0].imports.importVideo({ attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) - }) - - it('Should run filter:api.video.post-import-url.accept.result', async function () { - this.timeout(60000) - - let videoImportId: number - - { - const attributes = { - name: 'title with bad word', - privacy: VideoPrivacy.PUBLIC, - channelId: servers[0].store.channel.id, - targetUrl: FIXTURE_URLS.goodVideo - } - const body = await servers[0].imports.importVideo({ attributes }) - videoImportId = body.id - } - - await waitJobs(servers) - - { - const body = await servers[0].imports.getMyVideoImports() - const videoImports = body.data - - const videoImport = videoImports.find(i => i.id === videoImportId) - - expect(videoImport.state.id).to.equal(VideoImportState.REJECTED) - expect(videoImport.state.label).to.equal('Rejected') - } - }) - - it('Should run filter:api.video.post-import-torrent.accept.result', async function () { - this.timeout(60000) - - let videoImportId: number - - { - const attributes = { - name: 'title with bad word', - privacy: VideoPrivacy.PUBLIC, - channelId: servers[0].store.channel.id, - torrentfile: 'video-720p.torrent' as any - } - const body = await servers[0].imports.importVideo({ attributes }) - videoImportId = body.id - } - - await waitJobs(servers) - - { - const { data: videoImports } = await servers[0].imports.getMyVideoImports() - - const videoImport = videoImports.find(i => i.id === videoImportId) - - expect(videoImport.state.id).to.equal(VideoImportState.REJECTED) - expect(videoImport.state.label).to.equal('Rejected') - } - }) - }) - - describe('Video comments accept', function () { - - it('Should run filter:api.video-thread.create.accept.result', async function () { - await servers[0].comments.createThread({ - videoId: videoUUID, - text: 'comment with bad word', - expectedStatus: HttpStatusCode.FORBIDDEN_403 - }) - }) - - it('Should run filter:api.video-comment-reply.create.accept.result', async function () { - const created = await servers[0].comments.createThread({ videoId: videoUUID, text: 'thread' }) - threadId = created.id - - await servers[0].comments.addReply({ - videoId: videoUUID, - toCommentId: threadId, - text: 'comment with bad word', - expectedStatus: HttpStatusCode.FORBIDDEN_403 - }) - await servers[0].comments.addReply({ - videoId: videoUUID, - toCommentId: threadId, - text: 'comment with good word', - expectedStatus: HttpStatusCode.OK_200 - }) - }) - - it('Should run filter:activity-pub.remote-video-comment.create.accept.result on a thread creation', async function () { - this.timeout(30000) - - await servers[1].comments.createThread({ videoId: videoUUID, text: 'comment with bad word' }) - - await waitJobs(servers) - - { - const thread = await servers[0].comments.listThreads({ videoId: videoUUID }) - expect(thread.data).to.have.lengthOf(1) - expect(thread.data[0].text).to.not.include(' bad ') - } - - { - const thread = await servers[1].comments.listThreads({ videoId: videoUUID }) - expect(thread.data).to.have.lengthOf(2) - } - }) - - it('Should run filter:activity-pub.remote-video-comment.create.accept.result on a reply creation', async function () { - this.timeout(30000) - - const { data } = await servers[1].comments.listThreads({ videoId: videoUUID }) - const threadIdServer2 = data.find(t => t.text === 'thread').id - - await servers[1].comments.addReply({ - videoId: videoUUID, - toCommentId: threadIdServer2, - text: 'comment with bad word' - }) - - await waitJobs(servers) - - { - const tree = await servers[0].comments.getThread({ videoId: videoUUID, threadId }) - expect(tree.children).to.have.lengthOf(1) - expect(tree.children[0].comment.text).to.not.include(' bad ') - } - - { - const tree = await servers[1].comments.getThread({ videoId: videoUUID, threadId: threadIdServer2 }) - expect(tree.children).to.have.lengthOf(2) - } - }) - }) - - describe('Video comments', function () { - - it('Should run filter:api.video-threads.list.params', async function () { - const { data } = await servers[0].comments.listThreads({ videoId: videoUUID, start: 0, count: 0 }) - - // our plugin do +1 to the count parameter - expect(data).to.have.lengthOf(1) - }) - - it('Should run filter:api.video-threads.list.result', async function () { - const { total } = await servers[0].comments.listThreads({ videoId: videoUUID, start: 0, count: 0 }) - - // Plugin do +1 to the total result - expect(total).to.equal(2) - }) - - it('Should run filter:api.video-thread-comments.list.params') - - it('Should run filter:api.video-thread-comments.list.result', async function () { - const thread = await servers[0].comments.getThread({ videoId: videoUUID, threadId }) - - expect(thread.comment.text.endsWith(' <3')).to.be.true - }) - - it('Should run filter:api.overviews.videos.list.{params,result}', async function () { - await servers[0].overviews.getVideos({ page: 1 }) - - // 3 because we get 3 samples per page - await servers[0].servers.waitUntilLog('Run hook filter:api.overviews.videos.list.params', 3) - await servers[0].servers.waitUntilLog('Run hook filter:api.overviews.videos.list.result', 3) - }) - }) - - describe('filter:video.auto-blacklist.result', function () { - - async function checkIsBlacklisted (id: number | string, value: boolean) { - const video = await servers[0].videos.getWithToken({ id }) - expect(video.blacklisted).to.equal(value) - } - - it('Should blacklist on upload', async function () { - const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video please blacklist me' } }) - await checkIsBlacklisted(uuid, true) - }) - - it('Should blacklist on import', async function () { - this.timeout(15000) - - const attributes = { - name: 'video please blacklist me', - targetUrl: FIXTURE_URLS.goodVideo, - channelId: servers[0].store.channel.id - } - const body = await servers[0].imports.importVideo({ attributes }) - await checkIsBlacklisted(body.video.uuid, true) - }) - - it('Should blacklist on update', async function () { - const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video' } }) - await checkIsBlacklisted(uuid, false) - - await servers[0].videos.update({ id: uuid, attributes: { name: 'please blacklist me' } }) - await checkIsBlacklisted(uuid, true) - }) - - it('Should blacklist on remote upload', async function () { - this.timeout(120000) - - const { uuid } = await servers[1].videos.upload({ attributes: { name: 'remote please blacklist me' } }) - await waitJobs(servers) - - await checkIsBlacklisted(uuid, true) - }) - - it('Should blacklist on remote update', async function () { - this.timeout(120000) - - const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video' } }) - await waitJobs(servers) - - await checkIsBlacklisted(uuid, false) - - await servers[1].videos.update({ id: uuid, attributes: { name: 'please blacklist me' } }) - await waitJobs(servers) - - await checkIsBlacklisted(uuid, true) - }) - }) - - describe('Should run filter:api.user.signup.allowed.result', function () { - - before(async function () { - await servers[0].config.updateExistingSubConfig({ newConfig: { signup: { requiresApproval: false } } }) - }) - - it('Should run on config endpoint', async function () { - const body = await servers[0].config.getConfig() - expect(body.signup.allowed).to.be.true - }) - - it('Should allow a signup', async function () { - await servers[0].registrations.register({ username: 'john1' }) - }) - - it('Should not allow a signup', async function () { - const res = await servers[0].registrations.register({ - username: 'jma 1', - expectedStatus: HttpStatusCode.FORBIDDEN_403 - }) - - expect(res.body.error).to.equal('No jma 1') - }) - }) - - describe('Should run filter:api.user.request-signup.allowed.result', function () { - - before(async function () { - await servers[0].config.updateExistingSubConfig({ newConfig: { signup: { requiresApproval: true } } }) - }) - - it('Should run on config endpoint', async function () { - const body = await servers[0].config.getConfig() - expect(body.signup.allowed).to.be.true - }) - - it('Should allow a signup request', async function () { - await servers[0].registrations.requestRegistration({ username: 'john2', registrationReason: 'tt' }) - }) - - it('Should not allow a signup request', async function () { - const body = await servers[0].registrations.requestRegistration({ - username: 'jma 2', - registrationReason: 'tt', - expectedStatus: HttpStatusCode.FORBIDDEN_403 - }) - - expect((body as unknown as PeerTubeProblemDocument).error).to.equal('No jma 2') - }) - }) - - describe('Download hooks', function () { - const downloadVideos: VideoDetails[] = [] - let downloadVideo2Token: string - - before(async function () { - this.timeout(120000) - - await servers[0].config.updateCustomSubConfig({ - newConfig: { - transcoding: { - webVideos: { - enabled: true - }, - hls: { - enabled: true - } - } - } - }) - - const uuids: string[] = [] - - for (const name of [ 'bad torrent', 'bad file', 'bad playlist file' ]) { - const uuid = (await servers[0].videos.quickUpload({ name })).uuid - uuids.push(uuid) - } - - await waitJobs(servers) - - for (const uuid of uuids) { - downloadVideos.push(await servers[0].videos.get({ id: uuid })) - } - - downloadVideo2Token = await servers[0].videoToken.getVideoFileToken({ videoId: downloadVideos[2].uuid }) - }) - - it('Should run filter:api.download.torrent.allowed.result', async function () { - const res = await makeRawRequest({ url: downloadVideos[0].files[0].torrentDownloadUrl, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) - expect(res.body.error).to.equal('Liu Bei') - - await makeRawRequest({ url: downloadVideos[1].files[0].torrentDownloadUrl, expectedStatus: HttpStatusCode.OK_200 }) - await makeRawRequest({ url: downloadVideos[2].files[0].torrentDownloadUrl, expectedStatus: HttpStatusCode.OK_200 }) - }) - - it('Should run filter:api.download.video.allowed.result', async function () { - { - const refused = downloadVideos[1].files[0].fileDownloadUrl - const allowed = [ - downloadVideos[0].files[0].fileDownloadUrl, - downloadVideos[2].files[0].fileDownloadUrl - ] - - const res = await makeRawRequest({ url: refused, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) - expect(res.body.error).to.equal('Cao Cao') - - for (const url of allowed) { - await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 }) - await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 }) - } - } - - { - const refused = downloadVideos[2].streamingPlaylists[0].files[0].fileDownloadUrl - - const allowed = [ - downloadVideos[2].files[0].fileDownloadUrl, - downloadVideos[0].streamingPlaylists[0].files[0].fileDownloadUrl, - downloadVideos[1].streamingPlaylists[0].files[0].fileDownloadUrl - ] - - // Only streaming playlist is refuse - const res = await makeRawRequest({ url: refused, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) - expect(res.body.error).to.equal('Sun Jian') - - // But not we there is a user in res - await makeRawRequest({ url: refused, token: servers[0].accessToken, expectedStatus: HttpStatusCode.OK_200 }) - await makeRawRequest({ url: refused, query: { videoFileToken: downloadVideo2Token }, expectedStatus: HttpStatusCode.OK_200 }) - - // Other files work - for (const url of allowed) { - await makeRawRequest({ url, expectedStatus: HttpStatusCode.OK_200 }) - } - } - }) - }) - - describe('Embed filters', function () { - const embedVideos: VideoDetails[] = [] - const embedPlaylists: VideoPlaylist[] = [] - - before(async function () { - this.timeout(60000) - - await servers[0].config.disableTranscoding() - - for (const name of [ 'bad embed', 'good embed' ]) { - { - const uuid = (await servers[0].videos.quickUpload({ name })).uuid - embedVideos.push(await servers[0].videos.get({ id: uuid })) - } - - { - const attributes = { displayName: name, videoChannelId: servers[0].store.channel.id, privacy: VideoPlaylistPrivacy.PUBLIC } - const { id } = await servers[0].playlists.create({ attributes }) - - const playlist = await servers[0].playlists.get({ playlistId: id }) - embedPlaylists.push(playlist) - } - } - }) - - it('Should run filter:html.embed.video.allowed.result', async function () { - const res = await makeGetRequest({ url: servers[0].url, path: embedVideos[0].embedPath, expectedStatus: HttpStatusCode.OK_200 }) - expect(res.text).to.equal('Lu Bu') - }) - - it('Should run filter:html.embed.video-playlist.allowed.result', async function () { - const res = await makeGetRequest({ url: servers[0].url, path: embedPlaylists[0].embedPath, expectedStatus: HttpStatusCode.OK_200 }) - expect(res.text).to.equal('Diao Chan') - }) - }) - - describe('Client HTML filters', function () { - let videoUUID: string - - before(async function () { - this.timeout(60000) - - const { uuid } = await servers[0].videos.quickUpload({ name: 'html video' }) - videoUUID = uuid - }) - - it('Should run filter:html.client.json-ld.result', async function () { - const res = await makeGetRequest({ url: servers[0].url, path: '/w/' + videoUUID, expectedStatus: HttpStatusCode.OK_200 }) - expect(res.text).to.contain('"recordedAt":"http://example.com/recordedAt"') - }) - - it('Should not run filter:html.client.json-ld.result with an account', async function () { - const res = await makeGetRequest({ url: servers[0].url, path: '/a/root', expectedStatus: HttpStatusCode.OK_200 }) - expect(res.text).not.to.contain('"recordedAt":"http://example.com/recordedAt"') - }) - }) - - describe('Search filters', function () { - - before(async function () { - await servers[0].config.updateCustomSubConfig({ - newConfig: { - search: { - searchIndex: { - enabled: true, - isDefaultSearch: false, - disableLocalSearch: false - } - } - } - }) - }) - - it('Should run filter:api.search.videos.local.list.{params,result}', async function () { - await servers[0].search.advancedVideoSearch({ - search: { - search: 'Sun Quan' - } - }) - - await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.result', 1) - }) - - it('Should run filter:api.search.videos.index.list.{params,result}', async function () { - await servers[0].search.advancedVideoSearch({ - search: { - search: 'Sun Quan', - searchTarget: 'search-index' - } - }) - - await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.local.list.result', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.index.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.videos.index.list.result', 1) - }) - - it('Should run filter:api.search.video-channels.local.list.{params,result}', async function () { - await servers[0].search.advancedChannelSearch({ - search: { - search: 'Sun Ce' - } - }) - - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.result', 1) - }) - - it('Should run filter:api.search.video-channels.index.list.{params,result}', async function () { - await servers[0].search.advancedChannelSearch({ - search: { - search: 'Sun Ce', - searchTarget: 'search-index' - } - }) - - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.local.list.result', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.index.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-channels.index.list.result', 1) - }) - - it('Should run filter:api.search.video-playlists.local.list.{params,result}', async function () { - await servers[0].search.advancedPlaylistSearch({ - search: { - search: 'Sun Jian' - } - }) - - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.result', 1) - }) - - it('Should run filter:api.search.video-playlists.index.list.{params,result}', async function () { - await servers[0].search.advancedPlaylistSearch({ - search: { - search: 'Sun Jian', - searchTarget: 'search-index' - } - }) - - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.local.list.result', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.index.list.params', 1) - await servers[0].servers.waitUntilLog('Run hook filter:api.search.video-playlists.index.list.result', 1) - }) - }) - - describe('Upload/import/live attributes filters', function () { - - before(async function () { - await servers[0].config.enableLive({ transcoding: false, allowReplay: false }) - await servers[0].config.enableImports() - await servers[0].config.disableTranscoding() - }) - - it('Should run filter:api.video.upload.video-attribute.result', async function () { - for (const mode of [ 'legacy' as 'legacy', 'resumable' as 'resumable' ]) { - const { id } = await servers[0].videos.upload({ attributes: { name: 'video', description: 'upload' }, mode }) - - const video = await servers[0].videos.get({ id }) - expect(video.description).to.equal('upload - filter:api.video.upload.video-attribute.result') - } - }) - - it('Should run filter:api.video.import-url.video-attribute.result', async function () { - const attributes = { - name: 'video', - description: 'import url', - channelId: servers[0].store.channel.id, - targetUrl: FIXTURE_URLS.goodVideo, - privacy: VideoPrivacy.PUBLIC - } - const { video: { id } } = await servers[0].imports.importVideo({ attributes }) - - const video = await servers[0].videos.get({ id }) - expect(video.description).to.equal('import url - filter:api.video.import-url.video-attribute.result') - }) - - it('Should run filter:api.video.import-torrent.video-attribute.result', async function () { - const attributes = { - name: 'video', - description: 'import torrent', - channelId: servers[0].store.channel.id, - magnetUri: FIXTURE_URLS.magnet, - privacy: VideoPrivacy.PUBLIC - } - const { video: { id } } = await servers[0].imports.importVideo({ attributes }) - - const video = await servers[0].videos.get({ id }) - expect(video.description).to.equal('import torrent - filter:api.video.import-torrent.video-attribute.result') - }) - - it('Should run filter:api.video.live.video-attribute.result', async function () { - const fields = { - name: 'live', - description: 'live', - channelId: servers[0].store.channel.id, - privacy: VideoPrivacy.PUBLIC - } - const { id } = await servers[0].live.create({ fields }) - - const video = await servers[0].videos.get({ id }) - expect(video.description).to.equal('live - filter:api.video.live.video-attribute.result') - }) - }) - - describe('Stats filters', function () { - - it('Should run filter:api.server.stats.get.result', async function () { - const data = await servers[0].stats.get() - - expect((data as any).customStats).to.equal(14) - }) - - }) - - describe('Job queue filters', function () { - let videoUUID: string - - before(async function () { - this.timeout(120_000) - - await servers[0].config.enableMinimumTranscoding() - const { uuid } = await servers[0].videos.quickUpload({ name: 'studio' }) - - const video = await servers[0].videos.get({ id: uuid }) - expect(video.duration).at.least(2) - videoUUID = video.uuid - - await waitJobs(servers) - - await servers[0].config.enableStudio() - }) - - it('Should run filter:job-queue.process.params', async function () { - this.timeout(120_000) - - await servers[0].videoStudio.createEditionTasks({ - videoId: videoUUID, - tasks: [ - { - name: 'add-intro', - options: { - file: 'video_very_short_240p.mp4' - } - } - ] - }) - - await waitJobs(servers) - - await servers[0].servers.waitUntilLog('Run hook filter:job-queue.process.params', 1, false) - - const video = await servers[0].videos.get({ id: videoUUID }) - expect(video.duration).at.most(2) - }) - - it('Should run filter:job-queue.process.result', async function () { - await servers[0].servers.waitUntilLog('Run hook filter:job-queue.process.result', 1, false) - }) - }) - - describe('Transcoding filters', async function () { - - it('Should run filter:transcoding.auto.resolutions-to-transcode.result', async function () { - const { uuid } = await servers[0].videos.quickUpload({ name: 'transcode-filter' }) - - await waitJobs(servers) - - const video = await servers[0].videos.get({ id: uuid }) - expect(video.files).to.have.lengthOf(2) - expect(video.files.find(f => f.resolution.id === 100 as any)).to.exist - }) - }) - - describe('Video channel filters', async function () { - - it('Should run filter:api.video-channels.list.params', async function () { - const { data } = await servers[0].channels.list({ start: 0, count: 0 }) - - // plugin do +1 to the count parameter - expect(data).to.have.lengthOf(1) - }) - - it('Should run filter:api.video-channels.list.result', async function () { - const { total } = await servers[0].channels.list({ start: 0, count: 1 }) - - // plugin do +1 to the total parameter - expect(total).to.equal(4) - }) - - it('Should run filter:api.video-channel.get.result', async function () { - const channel = await servers[0].channels.get({ channelName: 'root_channel' }) - expect(channel.displayName).to.equal('Main root channel <3') - }) - }) - - describe('Activity Pub', function () { - - it('Should run filter:activity-pub.activity.context.build.result', async function () { - const { body } = await makeActivityPubGetRequest(servers[0].url, '/w/' + videoUUID) - expect(body.type).to.equal('Video') - - expect(body['@context'].some(c => { - return typeof c === 'object' && c.recordedAt === 'https://schema.org/recordedAt' - })).to.be.true - }) - - it('Should run filter:activity-pub.video.json-ld.build.result', async function () { - const { body } = await makeActivityPubGetRequest(servers[0].url, '/w/' + videoUUID) - expect(body.name).to.equal('default video 0') - expect(body.videoName).to.equal('default video 0') - }) - }) - - after(async function () { - await cleanupTests(servers) - }) -}) diff --git a/server/tests/plugins/html-injection.ts b/server/tests/plugins/html-injection.ts deleted file mode 100644 index fe16bf1e6..000000000 --- a/server/tests/plugins/html-injection.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { - cleanupTests, - createSingleServer, - makeHTMLRequest, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers -} from '@shared/server-commands' - -describe('Test plugins HTML injection', function () { - let server: PeerTubeServer = null - let command: PluginsCommand - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - command = server.plugins - }) - - it('Should not inject global css file in HTML', async function () { - { - const text = await command.getCSS() - expect(text).to.be.empty - } - - for (const path of [ '/', '/videos/embed/1', '/video-playlists/embed/1' ]) { - const res = await makeHTMLRequest(server.url, path) - expect(res.text).to.not.include('link rel="stylesheet" href="/plugins/global.css') - } - }) - - it('Should install a plugin and a theme', async function () { - this.timeout(30000) - - await command.install({ npmName: 'peertube-plugin-hello-world' }) - }) - - it('Should have the correct global css', async function () { - { - const text = await command.getCSS() - expect(text).to.contain('background-color: red') - } - - for (const path of [ '/', '/videos/embed/1', '/video-playlists/embed/1' ]) { - const res = await makeHTMLRequest(server.url, path) - expect(res.text).to.include('link rel="stylesheet" href="/plugins/global.css') - } - }) - - it('Should have an empty global css on uninstall', async function () { - await command.uninstall({ npmName: 'peertube-plugin-hello-world' }) - - { - const text = await command.getCSS() - expect(text).to.be.empty - } - - for (const path of [ '/', '/videos/embed/1', '/video-playlists/embed/1' ]) { - const res = await makeHTMLRequest(server.url, path) - expect(res.text).to.not.include('link rel="stylesheet" href="/plugins/global.css') - } - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/id-and-pass-auth.ts b/server/tests/plugins/id-and-pass-auth.ts deleted file mode 100644 index 127c29cbc..000000000 --- a/server/tests/plugins/id-and-pass-auth.ts +++ /dev/null @@ -1,242 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { wait } from '@shared/core-utils' -import { HttpStatusCode, UserRole } from '@shared/models' -import { cleanupTests, createSingleServer, PeerTubeServer, PluginsCommand, setAccessTokensToServers } from '@shared/server-commands' - -describe('Test id and pass auth plugins', function () { - let server: PeerTubeServer - - let crashAccessToken: string - let crashRefreshToken: string - - let lagunaAccessToken: string - let lagunaRefreshToken: string - let lagunaId: number - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - for (const suffix of [ 'one', 'two', 'three' ]) { - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-id-pass-auth-' + suffix) }) - } - }) - - it('Should display the correct configuration', async function () { - const config = await server.config.getConfig() - - const auths = config.plugin.registeredIdAndPassAuths - expect(auths).to.have.lengthOf(8) - - const crashAuth = auths.find(a => a.authName === 'crash-auth') - expect(crashAuth).to.exist - expect(crashAuth.npmName).to.equal('peertube-plugin-test-id-pass-auth-one') - expect(crashAuth.weight).to.equal(50) - }) - - it('Should not login', async function () { - await server.login.login({ user: { username: 'toto', password: 'password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - }) - - it('Should login Spyro, create the user and use the token', async function () { - const accessToken = await server.login.getAccessToken({ username: 'spyro', password: 'spyro password' }) - - const body = await server.users.getMyInfo({ token: accessToken }) - - expect(body.username).to.equal('spyro') - expect(body.account.displayName).to.equal('Spyro the Dragon') - expect(body.role.id).to.equal(UserRole.USER) - }) - - it('Should login Crash, create the user and use the token', async function () { - { - const body = await server.login.login({ user: { username: 'crash', password: 'crash password' } }) - crashAccessToken = body.access_token - crashRefreshToken = body.refresh_token - } - - { - const body = await server.users.getMyInfo({ token: crashAccessToken }) - - expect(body.username).to.equal('crash') - expect(body.account.displayName).to.equal('Crash Bandicoot') - expect(body.role.id).to.equal(UserRole.MODERATOR) - } - }) - - it('Should login the first Laguna, create the user and use the token', async function () { - { - const body = await server.login.login({ user: { username: 'laguna', password: 'laguna password' } }) - lagunaAccessToken = body.access_token - lagunaRefreshToken = body.refresh_token - } - - { - const body = await server.users.getMyInfo({ token: lagunaAccessToken }) - - expect(body.username).to.equal('laguna') - expect(body.account.displayName).to.equal('Laguna Loire') - expect(body.role.id).to.equal(UserRole.USER) - - lagunaId = body.id - } - }) - - it('Should refresh crash token, but not laguna token', async function () { - { - const resRefresh = await server.login.refreshToken({ refreshToken: crashRefreshToken }) - crashAccessToken = resRefresh.body.access_token - crashRefreshToken = resRefresh.body.refresh_token - - const body = await server.users.getMyInfo({ token: crashAccessToken }) - expect(body.username).to.equal('crash') - } - - { - await server.login.refreshToken({ refreshToken: lagunaRefreshToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - } - }) - - it('Should update Crash profile', async function () { - await server.users.updateMe({ - token: crashAccessToken, - displayName: 'Beautiful Crash', - description: 'Mutant eastern barred bandicoot' - }) - - const body = await server.users.getMyInfo({ token: crashAccessToken }) - - expect(body.account.displayName).to.equal('Beautiful Crash') - expect(body.account.description).to.equal('Mutant eastern barred bandicoot') - }) - - it('Should logout Crash', async function () { - await server.login.logout({ token: crashAccessToken }) - }) - - it('Should have logged out Crash', async function () { - await server.servers.waitUntilLog('On logout for auth 1 - 2') - - await server.users.getMyInfo({ token: crashAccessToken, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) - }) - - it('Should login Crash and keep the old existing profile', async function () { - crashAccessToken = await server.login.getAccessToken({ username: 'crash', password: 'crash password' }) - - const body = await server.users.getMyInfo({ token: crashAccessToken }) - - expect(body.username).to.equal('crash') - expect(body.account.displayName).to.equal('Beautiful Crash') - expect(body.account.description).to.equal('Mutant eastern barred bandicoot') - expect(body.role.id).to.equal(UserRole.MODERATOR) - }) - - it('Should login Laguna and update the profile', async function () { - { - await server.users.update({ userId: lagunaId, videoQuota: 43000, videoQuotaDaily: 43100 }) - await server.users.updateMe({ token: lagunaAccessToken, displayName: 'laguna updated' }) - - const body = await server.users.getMyInfo({ token: lagunaAccessToken }) - expect(body.username).to.equal('laguna') - expect(body.account.displayName).to.equal('laguna updated') - expect(body.videoQuota).to.equal(43000) - expect(body.videoQuotaDaily).to.equal(43100) - } - - { - const body = await server.login.login({ user: { username: 'laguna', password: 'laguna password' } }) - lagunaAccessToken = body.access_token - lagunaRefreshToken = body.refresh_token - } - - { - const body = await server.users.getMyInfo({ token: lagunaAccessToken }) - expect(body.username).to.equal('laguna') - expect(body.account.displayName).to.equal('Laguna Loire') - expect(body.videoQuota).to.equal(42000) - expect(body.videoQuotaDaily).to.equal(43100) - } - }) - - it('Should reject token of laguna by the plugin hook', async function () { - await wait(5000) - - await server.users.getMyInfo({ token: lagunaAccessToken, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) - }) - - it('Should reject an invalid username, email, role or display name', async function () { - const command = server.login - - await command.login({ user: { username: 'ward', password: 'ward password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await server.servers.waitUntilLog('valid username') - - await command.login({ user: { username: 'kiros', password: 'kiros password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await server.servers.waitUntilLog('valid displayName') - - await command.login({ user: { username: 'raine', password: 'raine password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await server.servers.waitUntilLog('valid role') - - await command.login({ user: { username: 'ellone', password: 'elonne password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await server.servers.waitUntilLog('valid email') - }) - - it('Should unregister spyro-auth and do not login existing Spyro', async function () { - await server.plugins.updateSettings({ - npmName: 'peertube-plugin-test-id-pass-auth-one', - settings: { disableSpyro: true } - }) - - const command = server.login - await command.login({ user: { username: 'spyro', password: 'spyro password' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await command.login({ user: { username: 'spyro', password: 'fake' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - }) - - it('Should have disabled this auth', async function () { - const config = await server.config.getConfig() - - const auths = config.plugin.registeredIdAndPassAuths - expect(auths).to.have.lengthOf(7) - - const spyroAuth = auths.find(a => a.authName === 'spyro-auth') - expect(spyroAuth).to.not.exist - }) - - it('Should uninstall the plugin one and do not login existing Crash', async function () { - await server.plugins.uninstall({ npmName: 'peertube-plugin-test-id-pass-auth-one' }) - - await server.login.login({ - user: { username: 'crash', password: 'crash password' }, - expectedStatus: HttpStatusCode.BAD_REQUEST_400 - }) - }) - - it('Should display the correct configuration', async function () { - const config = await server.config.getConfig() - - const auths = config.plugin.registeredIdAndPassAuths - expect(auths).to.have.lengthOf(6) - - const crashAuth = auths.find(a => a.authName === 'crash-auth') - expect(crashAuth).to.not.exist - }) - - it('Should display plugin auth information in users list', async function () { - const { data } = await server.users.list() - - const root = data.find(u => u.username === 'root') - const crash = data.find(u => u.username === 'crash') - const laguna = data.find(u => u.username === 'laguna') - - expect(root.pluginAuth).to.be.null - expect(crash.pluginAuth).to.equal('peertube-plugin-test-id-pass-auth-one') - expect(laguna.pluginAuth).to.equal('peertube-plugin-test-id-pass-auth-two') - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/index.ts b/server/tests/plugins/index.ts deleted file mode 100644 index 210af7236..000000000 --- a/server/tests/plugins/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import './action-hooks' -import './external-auth' -import './filter-hooks' -import './html-injection' -import './id-and-pass-auth' -import './plugin-helpers' -import './plugin-router' -import './plugin-storage' -import './plugin-transcoding' -import './plugin-unloading' -import './plugin-websocket' -import './translations' -import './video-constants' diff --git a/server/tests/plugins/plugin-helpers.ts b/server/tests/plugins/plugin-helpers.ts deleted file mode 100644 index f5a0cbe85..000000000 --- a/server/tests/plugins/plugin-helpers.ts +++ /dev/null @@ -1,383 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { pathExists } from 'fs-extra' -import { HttpStatusCode, ThumbnailType } from '@shared/models' -import { - cleanupTests, - createMultipleServers, - doubleFollow, - makeGetRequest, - makePostBodyRequest, - makeRawRequest, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers, - waitJobs -} from '@shared/server-commands' -import { checkVideoFilesWereRemoved } from '../shared' - -function postCommand (server: PeerTubeServer, command: string, bodyArg?: object) { - const body = { command } - if (bodyArg) Object.assign(body, bodyArg) - - return makePostBodyRequest({ - url: server.url, - path: '/plugins/test-four/router/commander', - fields: body, - expectedStatus: HttpStatusCode.NO_CONTENT_204 - }) -} - -describe('Test plugin helpers', function () { - let servers: PeerTubeServer[] - - before(async function () { - this.timeout(60000) - - servers = await createMultipleServers(2) - await setAccessTokensToServers(servers) - - await doubleFollow(servers[0], servers[1]) - - await servers[0].plugins.install({ path: PluginsCommand.getPluginTestPath('-four') }) - }) - - describe('Logger', function () { - - it('Should have logged things', async function () { - await servers[0].servers.waitUntilLog(servers[0].host + ' peertube-plugin-test-four', 1, false) - await servers[0].servers.waitUntilLog('Hello world from plugin four', 1) - }) - }) - - describe('Database', function () { - - it('Should have made a query', async function () { - await servers[0].servers.waitUntilLog(`root email is admin${servers[0].internalServerNumber}@example.com`) - }) - }) - - describe('Config', function () { - - it('Should have the correct webserver url', async function () { - await servers[0].servers.waitUntilLog(`server url is ${servers[0].url}`) - }) - - it('Should have the correct listening config', async function () { - const res = await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/server-listening-config', - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.config).to.exist - expect(res.body.config.hostname).to.equal('::') - expect(res.body.config.port).to.equal(servers[0].port) - }) - - it('Should have the correct config', async function () { - const res = await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/server-config', - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.serverConfig).to.exist - expect(res.body.serverConfig.instance.name).to.equal('PeerTube') - }) - }) - - describe('Server', function () { - - it('Should get the server actor', async function () { - await servers[0].servers.waitUntilLog('server actor name is peertube') - }) - }) - - describe('Socket', function () { - - it('Should sendNotification without any exceptions', async () => { - const user = await servers[0].users.create({ username: 'notis_redding', password: 'secret1234?' }) - await makePostBodyRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/send-notification', - fields: { - userId: user.id - }, - expectedStatus: HttpStatusCode.CREATED_201 - }) - }) - - it('Should sendVideoLiveNewState without any exceptions', async () => { - const res = await servers[0].videos.quickUpload({ name: 'video server 1' }) - - await makePostBodyRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/send-video-live-new-state/' + res.uuid, - expectedStatus: HttpStatusCode.CREATED_201 - }) - - await servers[0].videos.remove({ id: res.uuid }) - }) - }) - - describe('Plugin', function () { - - it('Should get the base static route', async function () { - const res = await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/static-route', - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.staticRoute).to.equal('/plugins/test-four/0.0.1/static/') - }) - - it('Should get the base static route', async function () { - const baseRouter = '/plugins/test-four/0.0.1/router/' - - const res = await makeGetRequest({ - url: servers[0].url, - path: baseRouter + 'router-route', - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.routerRoute).to.equal(baseRouter) - }) - }) - - describe('User', function () { - let rootId: number - - it('Should not get a user if not authenticated', async function () { - await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/user', - expectedStatus: HttpStatusCode.NOT_FOUND_404 - }) - }) - - it('Should get a user if authenticated', async function () { - const res = await makeGetRequest({ - url: servers[0].url, - token: servers[0].accessToken, - path: '/plugins/test-four/router/user', - expectedStatus: HttpStatusCode.OK_200 - }) - - 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 - - rootId = res.body.id - }) - - it('Should load a user by id', async function () { - { - const res = await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/user/' + rootId, - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.username).to.equal('root') - } - - { - await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/user/42', - expectedStatus: HttpStatusCode.NOT_FOUND_404 - }) - } - }) - }) - - describe('Moderation', function () { - let videoUUIDServer1: string - - before(async function () { - this.timeout(60000) - - { - const res = await servers[0].videos.quickUpload({ name: 'video server 1' }) - videoUUIDServer1 = res.uuid - } - - { - await servers[1].videos.quickUpload({ name: 'video server 2' }) - } - - await waitJobs(servers) - - const { data } = await servers[0].videos.list() - - expect(data).to.have.lengthOf(2) - }) - - it('Should mute server 2', async function () { - await postCommand(servers[0], 'blockServer', { hostToBlock: servers[1].host }) - - const { data } = await servers[0].videos.list() - - expect(data).to.have.lengthOf(1) - expect(data[0].name).to.equal('video server 1') - }) - - it('Should unmute server 2', async function () { - await postCommand(servers[0], 'unblockServer', { hostToUnblock: servers[1].host }) - - const { data } = await servers[0].videos.list() - - expect(data).to.have.lengthOf(2) - }) - - it('Should mute account of server 2', async function () { - await postCommand(servers[0], 'blockAccount', { handleToBlock: `root@${servers[1].host}` }) - - const { data } = await servers[0].videos.list() - - expect(data).to.have.lengthOf(1) - expect(data[0].name).to.equal('video server 1') - }) - - it('Should unmute account of server 2', async function () { - await postCommand(servers[0], 'unblockAccount', { handleToUnblock: `root@${servers[1].host}` }) - - const { data } = await servers[0].videos.list() - - expect(data).to.have.lengthOf(2) - }) - - it('Should blacklist video', async function () { - await postCommand(servers[0], 'blacklist', { videoUUID: videoUUIDServer1, unfederate: true }) - - await waitJobs(servers) - - for (const server of servers) { - const { data } = await server.videos.list() - - expect(data).to.have.lengthOf(1) - expect(data[0].name).to.equal('video server 2') - } - }) - - it('Should unblacklist video', async function () { - await postCommand(servers[0], 'unblacklist', { videoUUID: videoUUIDServer1 }) - - await waitJobs(servers) - - for (const server of servers) { - const { data } = await server.videos.list() - - expect(data).to.have.lengthOf(2) - } - }) - }) - - describe('Videos', function () { - let videoUUID: string - let videoPath: string - - before(async function () { - this.timeout(240000) - - await servers[0].config.enableTranscoding() - - const res = await servers[0].videos.quickUpload({ name: 'video1' }) - videoUUID = res.uuid - - await waitJobs(servers) - }) - - it('Should get video files', async function () { - const { body } = await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/video-files/' + videoUUID, - expectedStatus: HttpStatusCode.OK_200 - }) - - // Video files check - { - expect(body.webVideo.videoFiles).to.be.an('array') - expect(body.hls.videoFiles).to.be.an('array') - - for (const resolution of [ 144, 240, 360, 480, 720 ]) { - for (const files of [ body.webVideo.videoFiles, body.hls.videoFiles ]) { - const file = files.find(f => f.resolution === resolution) - expect(file).to.exist - - expect(file.size).to.be.a('number') - expect(file.fps).to.equal(25) - - expect(await pathExists(file.path)).to.be.true - await makeRawRequest({ url: file.url, expectedStatus: HttpStatusCode.OK_200 }) - } - } - - videoPath = body.webVideo.videoFiles[0].path - } - - // Thumbnails check - { - expect(body.thumbnails).to.be.an('array') - - const miniature = body.thumbnails.find(t => t.type === ThumbnailType.MINIATURE) - expect(miniature).to.exist - expect(await pathExists(miniature.path)).to.be.true - await makeRawRequest({ url: miniature.url, expectedStatus: HttpStatusCode.OK_200 }) - - const preview = body.thumbnails.find(t => t.type === ThumbnailType.PREVIEW) - expect(preview).to.exist - expect(await pathExists(preview.path)).to.be.true - await makeRawRequest({ url: preview.url, expectedStatus: HttpStatusCode.OK_200 }) - } - }) - - it('Should probe a file', async function () { - const { body } = await makeGetRequest({ - url: servers[0].url, - path: '/plugins/test-four/router/ffprobe', - query: { - path: videoPath - }, - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(body.streams).to.be.an('array') - expect(body.streams).to.have.lengthOf(2) - }) - - it('Should remove a video after a view', async function () { - this.timeout(40000) - - // Should not throw -> video exists - const video = await servers[0].videos.get({ id: videoUUID }) - // Should delete the video - await servers[0].views.simulateView({ id: videoUUID }) - - await servers[0].servers.waitUntilLog('Video deleted by plugin four.') - - try { - // Should throw because the video should have been deleted - await servers[0].videos.get({ id: videoUUID }) - throw new Error('Video exists') - } catch (err) { - if (err.message.includes('exists')) throw err - } - - await checkVideoFilesWereRemoved({ server: servers[0], video }) - }) - - it('Should have fetched the video by URL', async function () { - await servers[0].servers.waitUntilLog(`video from DB uuid is ${videoUUID}`) - }) - }) - - after(async function () { - await cleanupTests(servers) - }) -}) diff --git a/server/tests/plugins/plugin-router.ts b/server/tests/plugins/plugin-router.ts deleted file mode 100644 index 40b15eb79..000000000 --- a/server/tests/plugins/plugin-router.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { - cleanupTests, - createSingleServer, - makeGetRequest, - makePostBodyRequest, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers -} from '@shared/server-commands' -import { HttpStatusCode } from '@shared/models' - -describe('Test plugin helpers', function () { - let server: PeerTubeServer - const basePaths = [ - '/plugins/test-five/router/', - '/plugins/test-five/0.0.1/router/' - ] - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-five') }) - }) - - it('Should answer "pong"', async function () { - for (const path of basePaths) { - const res = await makeGetRequest({ - url: server.url, - path: path + 'ping', - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.message).to.equal('pong') - } - }) - - it('Should check if authenticated', async function () { - for (const path of basePaths) { - const res = await makeGetRequest({ - url: server.url, - path: path + 'is-authenticated', - token: server.accessToken, - expectedStatus: 200 - }) - - expect(res.body.isAuthenticated).to.equal(true) - - const secRes = await makeGetRequest({ - url: server.url, - path: path + 'is-authenticated', - expectedStatus: 200 - }) - - expect(secRes.body.isAuthenticated).to.equal(false) - } - }) - - it('Should mirror post body', async function () { - const body = { - hello: 'world', - riri: 'fifi', - loulou: 'picsou' - } - - for (const path of basePaths) { - const res = await makePostBodyRequest({ - url: server.url, - path: path + 'form/post/mirror', - fields: body, - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body).to.deep.equal(body) - } - }) - - it('Should remove the plugin and remove the routes', async function () { - await server.plugins.uninstall({ npmName: 'peertube-plugin-test-five' }) - - for (const path of basePaths) { - await makeGetRequest({ - url: server.url, - path: path + 'ping', - expectedStatus: HttpStatusCode.NOT_FOUND_404 - }) - - await makePostBodyRequest({ - url: server.url, - path: path + 'ping', - fields: {}, - expectedStatus: HttpStatusCode.NOT_FOUND_404 - }) - } - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/plugin-storage.ts b/server/tests/plugins/plugin-storage.ts deleted file mode 100644 index 112652a1f..000000000 --- a/server/tests/plugins/plugin-storage.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { pathExists, readdir, readFile } from 'fs-extra' -import { join } from 'path' -import { - cleanupTests, - createSingleServer, - makeGetRequest, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers -} from '@shared/server-commands' -import { HttpStatusCode } from '@shared/models' - -describe('Test plugin storage', function () { - let server: PeerTubeServer - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-six') }) - }) - - describe('DB storage', function () { - it('Should correctly store a subkey', async function () { - await server.servers.waitUntilLog('superkey stored value is toto') - }) - - it('Should correctly retrieve an array as array from the storage.', async function () { - await server.servers.waitUntilLog('storedArrayKey isArray is true') - await server.servers.waitUntilLog('storedArrayKey stored value is toto, toto2') - }) - }) - - describe('Disk storage', function () { - let dataPath: string - let pluginDataPath: string - - async function getFileContent () { - const files = await readdir(pluginDataPath) - expect(files).to.have.lengthOf(1) - - return readFile(join(pluginDataPath, files[0]), 'utf8') - } - - before(function () { - dataPath = server.servers.buildDirectory('plugins/data') - pluginDataPath = join(dataPath, 'peertube-plugin-test-six') - }) - - it('Should have created the directory on install', async function () { - const dataPath = server.servers.buildDirectory('plugins/data') - const pluginDataPath = join(dataPath, 'peertube-plugin-test-six') - - expect(await pathExists(dataPath)).to.be.true - expect(await pathExists(pluginDataPath)).to.be.true - expect(await readdir(pluginDataPath)).to.have.lengthOf(0) - }) - - it('Should have created a file', async function () { - await makeGetRequest({ - url: server.url, - token: server.accessToken, - path: '/plugins/test-six/router/create-file', - expectedStatus: HttpStatusCode.OK_200 - }) - - const content = await getFileContent() - expect(content).to.equal('Prince Ali') - }) - - it('Should still have the file after an uninstallation', async function () { - await server.plugins.uninstall({ npmName: 'peertube-plugin-test-six' }) - - const content = await getFileContent() - expect(content).to.equal('Prince Ali') - }) - - it('Should still have the file after the reinstallation', async function () { - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-six') }) - - const content = await getFileContent() - expect(content).to.equal('Prince Ali') - }) - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/plugin-transcoding.ts b/server/tests/plugins/plugin-transcoding.ts deleted file mode 100644 index 21f82fbac..000000000 --- a/server/tests/plugins/plugin-transcoding.ts +++ /dev/null @@ -1,279 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { getAudioStream, getVideoStream, getVideoStreamFPS } from '@shared/ffmpeg' -import { VideoPrivacy } from '@shared/models' -import { - cleanupTests, - createSingleServer, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers, - setDefaultVideoChannel, - testFfmpegStreamError, - waitJobs -} from '@shared/server-commands' - -async function createLiveWrapper (server: PeerTubeServer) { - const liveAttributes = { - name: 'live video', - channelId: server.store.channel.id, - privacy: VideoPrivacy.PUBLIC - } - - const { uuid } = await server.live.create({ fields: liveAttributes }) - - return uuid -} - -function updateConf (server: PeerTubeServer, vodProfile: string, liveProfile: string) { - return server.config.updateCustomSubConfig({ - newConfig: { - transcoding: { - enabled: true, - profile: vodProfile, - hls: { - enabled: true - }, - webVideos: { - enabled: true - }, - resolutions: { - '240p': true, - '360p': false, - '480p': false, - '720p': true - } - }, - live: { - transcoding: { - profile: liveProfile, - enabled: true, - resolutions: { - '240p': true, - '360p': false, - '480p': false, - '720p': true - } - } - } - } - }) -} - -describe('Test transcoding plugins', function () { - let server: PeerTubeServer - - before(async function () { - this.timeout(60000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - await setDefaultVideoChannel([ server ]) - - await updateConf(server, 'default', 'default') - }) - - describe('When using a plugin adding profiles to existing encoders', function () { - - async function checkVideoFPS (uuid: string, type: 'above' | 'below', fps: number) { - const video = await server.videos.get({ id: uuid }) - const files = video.files.concat(...video.streamingPlaylists.map(p => p.files)) - - for (const file of files) { - if (type === 'above') { - expect(file.fps).to.be.above(fps) - } else { - expect(file.fps).to.be.below(fps) - } - } - } - - async function checkLiveFPS (uuid: string, type: 'above' | 'below', fps: number) { - const playlistUrl = `${server.url}/static/streaming-playlists/hls/${uuid}/0.m3u8` - const videoFPS = await getVideoStreamFPS(playlistUrl) - - if (type === 'above') { - expect(videoFPS).to.be.above(fps) - } else { - expect(videoFPS).to.be.below(fps) - } - } - - before(async function () { - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-transcoding-one') }) - }) - - it('Should have the appropriate available profiles', async function () { - const config = await server.config.getConfig() - - expect(config.transcoding.availableProfiles).to.have.members([ 'default', 'low-vod', 'input-options-vod', 'bad-scale-vod' ]) - expect(config.live.transcoding.availableProfiles).to.have.members([ 'default', 'high-live', 'input-options-live', 'bad-scale-live' ]) - }) - - describe('VOD', function () { - - it('Should not use the plugin profile if not chosen by the admin', async function () { - this.timeout(240000) - - const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid - await waitJobs([ server ]) - - await checkVideoFPS(videoUUID, 'above', 20) - }) - - it('Should use the vod profile', async function () { - this.timeout(240000) - - await updateConf(server, 'low-vod', 'default') - - const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid - await waitJobs([ server ]) - - await checkVideoFPS(videoUUID, 'below', 12) - }) - - it('Should apply input options in vod profile', async function () { - this.timeout(240000) - - await updateConf(server, 'input-options-vod', 'default') - - const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid - await waitJobs([ server ]) - - await checkVideoFPS(videoUUID, 'below', 6) - }) - - it('Should apply the scale filter in vod profile', async function () { - this.timeout(240000) - - await updateConf(server, 'bad-scale-vod', 'default') - - const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid - await waitJobs([ server ]) - - // Transcoding failed - const video = await server.videos.get({ id: videoUUID }) - expect(video.files).to.have.lengthOf(1) - expect(video.streamingPlaylists).to.have.lengthOf(0) - }) - }) - - describe('Live', function () { - - it('Should not use the plugin profile if not chosen by the admin', async function () { - this.timeout(240000) - - const liveVideoId = await createLiveWrapper(server) - - await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' }) - await server.live.waitUntilPublished({ videoId: liveVideoId }) - await waitJobs([ server ]) - - await checkLiveFPS(liveVideoId, 'above', 20) - }) - - it('Should use the live profile', async function () { - this.timeout(240000) - - await updateConf(server, 'low-vod', 'high-live') - - const liveVideoId = await createLiveWrapper(server) - - await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' }) - await server.live.waitUntilPublished({ videoId: liveVideoId }) - await waitJobs([ server ]) - - await checkLiveFPS(liveVideoId, 'above', 45) - }) - - it('Should apply the input options on live profile', async function () { - this.timeout(240000) - - await updateConf(server, 'low-vod', 'input-options-live') - - const liveVideoId = await createLiveWrapper(server) - - await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' }) - await server.live.waitUntilPublished({ videoId: liveVideoId }) - await waitJobs([ server ]) - - await checkLiveFPS(liveVideoId, 'above', 45) - }) - - it('Should apply the scale filter name on live profile', async function () { - this.timeout(240000) - - await updateConf(server, 'low-vod', 'bad-scale-live') - - const liveVideoId = await createLiveWrapper(server) - - const command = await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' }) - await testFfmpegStreamError(command, true) - }) - - it('Should default to the default profile if the specified profile does not exist', async function () { - this.timeout(240000) - - await server.plugins.uninstall({ npmName: 'peertube-plugin-test-transcoding-one' }) - - const config = await server.config.getConfig() - - expect(config.transcoding.availableProfiles).to.deep.equal([ 'default' ]) - expect(config.live.transcoding.availableProfiles).to.deep.equal([ 'default' ]) - - const videoUUID = (await server.videos.quickUpload({ name: 'video', fixture: 'video_very_short_240p.mp4' })).uuid - await waitJobs([ server ]) - - await checkVideoFPS(videoUUID, 'above', 20) - }) - }) - - }) - - describe('When using a plugin adding new encoders', function () { - - before(async function () { - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-transcoding-two') }) - - await updateConf(server, 'test-vod-profile', 'test-live-profile') - }) - - it('Should use the new vod encoders', async function () { - this.timeout(240000) - - const videoUUID = (await server.videos.quickUpload({ name: 'video', fixture: 'video_very_short_240p.mp4' })).uuid - await waitJobs([ server ]) - - const video = await server.videos.get({ id: videoUUID }) - - const path = server.servers.buildWebVideoFilePath(video.files[0].fileUrl) - const audioProbe = await getAudioStream(path) - expect(audioProbe.audioStream.codec_name).to.equal('opus') - - const videoProbe = await getVideoStream(path) - expect(videoProbe.codec_name).to.equal('vp9') - }) - - it('Should use the new live encoders', async function () { - this.timeout(240000) - - const liveVideoId = await createLiveWrapper(server) - - await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' }) - await server.live.waitUntilPublished({ videoId: liveVideoId }) - await waitJobs([ server ]) - - const playlistUrl = `${server.url}/static/streaming-playlists/hls/${liveVideoId}/0.m3u8` - const audioProbe = await getAudioStream(playlistUrl) - expect(audioProbe.audioStream.codec_name).to.equal('opus') - - const videoProbe = await getVideoStream(playlistUrl) - expect(videoProbe.codec_name).to.equal('h264') - }) - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/plugin-unloading.ts b/server/tests/plugins/plugin-unloading.ts deleted file mode 100644 index 5aca1a0c0..000000000 --- a/server/tests/plugins/plugin-unloading.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { - cleanupTests, - createSingleServer, - makeGetRequest, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers -} from '@shared/server-commands' -import { HttpStatusCode } from '@shared/models' - -describe('Test plugins module unloading', function () { - let server: PeerTubeServer = null - const requestPath = '/plugins/test-unloading/router/get' - let value: string = null - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-unloading') }) - }) - - it('Should return a numeric value', async function () { - const res = await makeGetRequest({ - url: server.url, - path: requestPath, - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.message).to.match(/^\d+$/) - value = res.body.message - }) - - it('Should return the same value the second time', async function () { - const res = await makeGetRequest({ - url: server.url, - path: requestPath, - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.message).to.be.equal(value) - }) - - it('Should uninstall the plugin and free the route', async function () { - await server.plugins.uninstall({ npmName: 'peertube-plugin-test-unloading' }) - - await makeGetRequest({ - url: server.url, - path: requestPath, - expectedStatus: HttpStatusCode.NOT_FOUND_404 - }) - }) - - it('Should return a different numeric value', async function () { - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-unloading') }) - - const res = await makeGetRequest({ - url: server.url, - path: requestPath, - expectedStatus: HttpStatusCode.OK_200 - }) - - expect(res.body.message).to.match(/^\d+$/) - expect(res.body.message).to.be.not.equal(value) - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/plugin-websocket.ts b/server/tests/plugins/plugin-websocket.ts deleted file mode 100644 index adaa28b1d..000000000 --- a/server/tests/plugins/plugin-websocket.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import WebSocket from 'ws' -import { cleanupTests, createSingleServer, PeerTubeServer, PluginsCommand, setAccessTokensToServers } from '@shared/server-commands' - -function buildWebSocket (server: PeerTubeServer, path: string) { - return new WebSocket('ws://' + server.host + path) -} - -function expectErrorOrTimeout (server: PeerTubeServer, path: string, expectedTimeout: number) { - return new Promise((res, rej) => { - const ws = buildWebSocket(server, path) - ws.on('error', () => res()) - - const timeout = setTimeout(() => res(), expectedTimeout) - - ws.on('open', () => { - clearTimeout(timeout) - - return rej(new Error('Connect did not timeout')) - }) - }) -} - -describe('Test plugin websocket', function () { - let server: PeerTubeServer - const basePaths = [ - '/plugins/test-websocket/ws/', - '/plugins/test-websocket/0.0.1/ws/' - ] - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-websocket') }) - }) - - it('Should not connect to the websocket without the appropriate path', async function () { - const paths = [ - '/plugins/unknown/ws/', - '/plugins/unknown/0.0.1/ws/' - ] - - for (const path of paths) { - await expectErrorOrTimeout(server, path, 1000) - } - }) - - it('Should not connect to the websocket without the appropriate sub path', async function () { - for (const path of basePaths) { - await expectErrorOrTimeout(server, path + '/unknown', 1000) - } - }) - - it('Should connect to the websocket and receive pong', function (done) { - const ws = buildWebSocket(server, basePaths[0]) - - ws.on('open', () => ws.send('ping')) - ws.on('message', data => { - if (data.toString() === 'pong') return done() - }) - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/translations.ts b/server/tests/plugins/translations.ts deleted file mode 100644 index 67e4683f8..000000000 --- a/server/tests/plugins/translations.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { cleanupTests, createSingleServer, PeerTubeServer, PluginsCommand, setAccessTokensToServers } from '@shared/server-commands' - -describe('Test plugin translations', function () { - let server: PeerTubeServer - let command: PluginsCommand - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - command = server.plugins - - await command.install({ path: PluginsCommand.getPluginTestPath() }) - await command.install({ path: PluginsCommand.getPluginTestPath('-filter-translations') }) - }) - - it('Should not have translations for locale pt', async function () { - const body = await command.getTranslations({ locale: 'pt' }) - - expect(body).to.deep.equal({}) - }) - - it('Should have translations for locale fr', async function () { - const body = await command.getTranslations({ locale: 'fr-FR' }) - - expect(body).to.deep.equal({ - 'peertube-plugin-test': { - Hi: 'Coucou' - }, - 'peertube-plugin-test-filter-translations': { - 'Hello world': 'Bonjour le monde' - } - }) - }) - - it('Should have translations of locale it', async function () { - const body = await command.getTranslations({ locale: 'it-IT' }) - - expect(body).to.deep.equal({ - 'peertube-plugin-test-filter-translations': { - 'Hello world': 'Ciao, mondo!' - } - }) - }) - - it('Should remove the plugin and remove the locales', async function () { - await command.uninstall({ npmName: 'peertube-plugin-test-filter-translations' }) - - { - const body = await command.getTranslations({ locale: 'fr-FR' }) - - expect(body).to.deep.equal({ - 'peertube-plugin-test': { - Hi: 'Coucou' - } - }) - } - - { - const body = await command.getTranslations({ locale: 'it-IT' }) - - expect(body).to.deep.equal({}) - } - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) diff --git a/server/tests/plugins/video-constants.ts b/server/tests/plugins/video-constants.ts deleted file mode 100644 index c388f02d1..000000000 --- a/server/tests/plugins/video-constants.ts +++ /dev/null @@ -1,180 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import { expect } from 'chai' -import { - cleanupTests, - createSingleServer, - makeGetRequest, - PeerTubeServer, - PluginsCommand, - setAccessTokensToServers -} from '@shared/server-commands' -import { HttpStatusCode, VideoPlaylistPrivacy } from '@shared/models' - -describe('Test plugin altering video constants', function () { - let server: PeerTubeServer - - before(async function () { - this.timeout(30000) - - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) - - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-video-constants') }) - }) - - it('Should have updated languages', async function () { - const languages = await server.videos.getLanguages() - - expect(languages['en']).to.not.exist - expect(languages['fr']).to.not.exist - - expect(languages['al_bhed']).to.equal('Al Bhed') - expect(languages['al_bhed2']).to.equal('Al Bhed 2') - expect(languages['al_bhed3']).to.not.exist - }) - - it('Should have updated categories', async function () { - const categories = await server.videos.getCategories() - - expect(categories[1]).to.not.exist - expect(categories[2]).to.not.exist - - expect(categories[42]).to.equal('Best category') - expect(categories[43]).to.equal('High best category') - }) - - it('Should have updated licences', async function () { - const licences = await server.videos.getLicences() - - expect(licences[1]).to.not.exist - expect(licences[7]).to.not.exist - - expect(licences[42]).to.equal('Best licence') - expect(licences[43]).to.equal('High best licence') - }) - - it('Should have updated video privacies', async function () { - const privacies = await server.videos.getPrivacies() - - expect(privacies[1]).to.exist - expect(privacies[2]).to.not.exist - expect(privacies[3]).to.exist - expect(privacies[4]).to.exist - }) - - it('Should have updated playlist privacies', async function () { - const playlistPrivacies = await server.playlists.getPrivacies() - - expect(playlistPrivacies[1]).to.exist - expect(playlistPrivacies[2]).to.exist - expect(playlistPrivacies[3]).to.not.exist - }) - - it('Should not be able to create a video with this privacy', async function () { - const attributes = { name: 'video', privacy: 2 } - await server.videos.upload({ attributes, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - }) - - it('Should not be able to create a video with this privacy', async function () { - const attributes = { displayName: 'video playlist', privacy: VideoPlaylistPrivacy.PRIVATE } - await server.playlists.create({ attributes, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - }) - - it('Should be able to upload a video with these values', async function () { - const attributes = { name: 'video', category: 42, licence: 42, language: 'al_bhed2' } - const { uuid } = await server.videos.upload({ attributes }) - - const video = await server.videos.get({ id: uuid }) - expect(video.language.label).to.equal('Al Bhed 2') - expect(video.licence.label).to.equal('Best licence') - expect(video.category.label).to.equal('Best category') - }) - - it('Should uninstall the plugin and reset languages, categories, licences and privacies', async function () { - await server.plugins.uninstall({ npmName: 'peertube-plugin-test-video-constants' }) - - { - const languages = await server.videos.getLanguages() - - expect(languages['en']).to.equal('English') - expect(languages['fr']).to.equal('French') - - expect(languages['al_bhed']).to.not.exist - expect(languages['al_bhed2']).to.not.exist - expect(languages['al_bhed3']).to.not.exist - } - - { - const categories = await server.videos.getCategories() - - expect(categories[1]).to.equal('Music') - expect(categories[2]).to.equal('Films') - - expect(categories[42]).to.not.exist - expect(categories[43]).to.not.exist - } - - { - const licences = await server.videos.getLicences() - - expect(licences[1]).to.equal('Attribution') - expect(licences[7]).to.equal('Public Domain Dedication') - - expect(licences[42]).to.not.exist - expect(licences[43]).to.not.exist - } - - { - const privacies = await server.videos.getPrivacies() - - expect(privacies[1]).to.exist - expect(privacies[2]).to.exist - expect(privacies[3]).to.exist - expect(privacies[4]).to.exist - } - - { - const playlistPrivacies = await server.playlists.getPrivacies() - - expect(playlistPrivacies[1]).to.exist - expect(playlistPrivacies[2]).to.exist - expect(playlistPrivacies[3]).to.exist - } - }) - - it('Should be able to reset categories', async function () { - await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-video-constants') }) - - { - const categories = await server.videos.getCategories() - - expect(categories[1]).to.not.exist - expect(categories[2]).to.not.exist - - expect(categories[42]).to.exist - expect(categories[43]).to.exist - } - - await makeGetRequest({ - url: server.url, - token: server.accessToken, - path: '/plugins/test-video-constants/router/reset-categories', - expectedStatus: HttpStatusCode.NO_CONTENT_204 - }) - - { - const categories = await server.videos.getCategories() - - expect(categories[1]).to.exist - expect(categories[2]).to.exist - - expect(categories[42]).to.not.exist - expect(categories[43]).to.not.exist - } - }) - - after(async function () { - await cleanupTests([ server ]) - }) -}) -- cgit v1.2.3