PeerTube/packages/tests/src/api/server/plugins.ts

411 lines
12 KiB
TypeScript
Raw Normal View History

2020-01-31 16:56:52 +01:00
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2019-07-19 10:37:35 +02:00
2022-08-17 15:44:32 +02:00
import { expect } from 'chai'
import { pathExists, remove } from 'fs-extra/esm'
import { join } from 'path'
import { wait } from '@peertube/peertube-core-utils'
import { HttpStatusCode, PluginType } from '@peertube/peertube-models'
2019-07-19 10:37:35 +02:00
import {
cleanupTests,
2021-07-16 09:47:51 +02:00
createSingleServer,
2020-01-31 16:56:52 +01:00
killallServers,
makeGetRequest,
2021-07-16 09:47:51 +02:00
PeerTubeServer,
2021-07-16 14:27:30 +02:00
PluginsCommand,
setAccessTokensToServers
} from '@peertube/peertube-server-commands'
import { SQLCommand } from '@tests/shared/sql-command.js'
import { testHelloWorldRegisteredSettings } from '@tests/shared/plugins.js'
2019-07-19 10:37:35 +02:00
describe('Test plugins', function () {
2023-04-21 15:00:01 +02:00
let server: PeerTubeServer
let sqlCommand: SQLCommand
2021-07-07 10:33:49 +02:00
let command: PluginsCommand
2019-07-19 10:37:35 +02:00
before(async function () {
this.timeout(30000)
2019-07-19 14:36:04 +02:00
const configOverride = {
plugins: {
index: { check_latest_versions_interval: '5 seconds' }
}
}
2021-07-16 09:47:51 +02:00
server = await createSingleServer(1, configOverride)
2019-07-19 10:37:35 +02:00
await setAccessTokensToServers([ server ])
2021-07-09 11:21:30 +02:00
2021-07-16 09:04:35 +02:00
command = server.plugins
2023-04-21 15:00:01 +02:00
sqlCommand = new SQLCommand(server)
2019-07-19 14:36:04 +02:00
})
it('Should list and search available plugins and themes', async function () {
this.timeout(30000)
2019-07-19 10:37:35 +02:00
{
2021-07-07 10:33:49 +02:00
const body = await command.listAvailable({
2019-07-19 14:36:04 +02:00
count: 1,
start: 0,
pluginType: PluginType.THEME,
search: 'background-red'
})
2021-07-07 10:33:49 +02:00
expect(body.total).to.be.at.least(1)
expect(body.data).to.have.lengthOf(1)
2019-07-19 10:37:35 +02:00
}
{
2021-07-07 10:33:49 +02:00
const body1 = await command.listAvailable({
2019-07-19 14:36:04 +02:00
count: 2,
start: 0,
sort: 'npmName'
})
2021-07-07 10:33:49 +02:00
expect(body1.total).to.be.at.least(2)
2019-07-19 14:36:04 +02:00
2021-07-07 10:33:49 +02:00
const data1 = body1.data
2019-07-19 14:36:04 +02:00
expect(data1).to.have.lengthOf(2)
2021-07-07 10:33:49 +02:00
const body2 = await command.listAvailable({
2019-07-19 14:36:04 +02:00
count: 2,
start: 0,
sort: '-npmName'
})
2021-07-07 10:33:49 +02:00
expect(body2.total).to.be.at.least(2)
2019-07-19 14:36:04 +02:00
2021-07-07 10:33:49 +02:00
const data2 = body2.data
2019-07-19 14:36:04 +02:00
expect(data2).to.have.lengthOf(2)
2020-01-31 16:56:52 +01:00
expect(data1[0].npmName).to.not.equal(data2[0].npmName)
2019-07-19 10:37:35 +02:00
}
2019-07-19 14:36:04 +02:00
{
2021-07-07 10:33:49 +02:00
const body = await command.listAvailable({
2019-07-19 14:36:04 +02:00
count: 10,
start: 0,
pluginType: PluginType.THEME,
search: 'background-red',
currentPeerTubeEngine: '1.0.0'
})
2019-07-19 10:37:35 +02:00
2021-07-07 10:33:49 +02:00
const p = body.data.find(p => p.npmName === 'peertube-theme-background-red')
2019-07-19 14:36:04 +02:00
expect(p).to.be.undefined
}
2019-07-19 10:37:35 +02:00
})
it('Should install a plugin and a theme', async function () {
2019-07-19 14:36:04 +02:00
this.timeout(30000)
2021-07-07 10:33:49 +02:00
await command.install({ npmName: 'peertube-plugin-hello-world' })
await command.install({ npmName: 'peertube-theme-background-red' })
2019-07-19 10:37:35 +02:00
})
it('Should have the plugin loaded in the configuration', async function () {
2022-03-17 09:09:06 +01:00
for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
const theme = config.theme.registered.find(r => r.name === 'background-red')
expect(theme).to.not.be.undefined
expect(theme.npmName).to.equal('peertube-theme-background-red')
const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
expect(plugin).to.not.be.undefined
expect(plugin.npmName).to.equal('peertube-plugin-hello-world')
}
2019-07-19 10:37:35 +02:00
})
it('Should update the default theme in the configuration', async function () {
await server.config.updateExistingConfig({
2021-07-07 11:51:09 +02:00
newConfig: {
theme: { default: 'background-red' }
}
})
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
expect(config.theme.default).to.equal('background-red')
}
2019-07-19 10:37:35 +02:00
})
2019-07-19 14:36:04 +02:00
it('Should update my default theme', async function () {
2021-07-16 09:04:35 +02:00
await server.users.updateMe({ theme: 'background-red' })
2019-07-19 14:36:04 +02:00
2021-07-16 09:04:35 +02:00
const user = await server.users.getMyInfo()
2021-07-13 14:23:01 +02:00
expect(user.theme).to.equal('background-red')
2019-07-19 10:37:35 +02:00
})
2019-07-19 14:36:04 +02:00
it('Should list plugins and themes', async function () {
{
2021-07-07 10:33:49 +02:00
const body = await command.list({
2019-07-19 14:36:04 +02:00
count: 1,
start: 0,
pluginType: PluginType.THEME
})
2021-07-07 10:33:49 +02:00
expect(body.total).to.be.at.least(1)
2019-07-19 14:36:04 +02:00
2021-07-07 10:33:49 +02:00
const data = body.data
2019-07-19 14:36:04 +02:00
expect(data).to.have.lengthOf(1)
expect(data[0].name).to.equal('background-red')
}
{
2021-07-09 16:23:01 +02:00
const { data } = await command.list({
2019-07-19 14:36:04 +02:00
count: 2,
start: 0,
sort: 'name'
})
expect(data[0].name).to.equal('background-red')
expect(data[1].name).to.equal('hello-world')
}
{
2021-07-07 10:33:49 +02:00
const body = await command.list({
2019-07-19 14:36:04 +02:00
count: 2,
start: 1,
sort: 'name'
})
2021-07-07 10:33:49 +02:00
expect(body.data[0].name).to.equal('hello-world')
2019-07-19 14:36:04 +02:00
}
2019-07-19 10:37:35 +02:00
})
it('Should get registered settings', async function () {
await testHelloWorldRegisteredSettings(server)
2019-07-19 10:37:35 +02:00
})
2019-07-26 09:35:43 +02:00
it('Should get public settings', async function () {
2021-07-07 10:33:49 +02:00
const body = await command.getPublicSettings({ npmName: 'peertube-plugin-hello-world' })
const publicSettings = body.publicSettings
2019-07-26 09:35:43 +02:00
expect(Object.keys(publicSettings)).to.have.lengthOf(1)
expect(Object.keys(publicSettings)).to.deep.equal([ 'user-name' ])
expect(publicSettings['user-name']).to.be.null
})
2019-07-19 10:37:35 +02:00
it('Should update the settings', async function () {
2019-07-19 14:36:04 +02:00
const settings = {
'admin-name': 'Cid'
}
2021-07-07 10:33:49 +02:00
await command.updateSettings({
2019-07-19 14:36:04 +02:00
npmName: 'peertube-plugin-hello-world',
settings
})
})
2020-04-30 09:28:39 +02:00
it('Should have watched settings changes', async function () {
2021-07-16 09:04:35 +02:00
await server.servers.waitUntilLog('Settings changed!')
2020-04-30 09:28:39 +02:00
})
2019-07-19 14:36:04 +02:00
it('Should get a plugin and a theme', async function () {
{
2021-07-07 10:33:49 +02:00
const plugin = await command.get({ npmName: 'peertube-plugin-hello-world' })
2019-07-19 14:36:04 +02:00
expect(plugin.type).to.equal(PluginType.PLUGIN)
expect(plugin.name).to.equal('hello-world')
expect(plugin.description).to.exist
expect(plugin.homepage).to.exist
expect(plugin.uninstalled).to.be.false
expect(plugin.enabled).to.be.true
expect(plugin.description).to.exist
expect(plugin.version).to.exist
expect(plugin.peertubeEngine).to.exist
expect(plugin.createdAt).to.exist
expect(plugin.settings).to.not.be.undefined
expect(plugin.settings['admin-name']).to.equal('Cid')
}
{
2021-07-07 10:33:49 +02:00
const plugin = await command.get({ npmName: 'peertube-theme-background-red' })
2019-07-19 10:37:35 +02:00
2019-07-19 14:36:04 +02:00
expect(plugin.type).to.equal(PluginType.THEME)
expect(plugin.name).to.equal('background-red')
expect(plugin.description).to.exist
expect(plugin.homepage).to.exist
expect(plugin.uninstalled).to.be.false
expect(plugin.enabled).to.be.true
expect(plugin.description).to.exist
expect(plugin.version).to.exist
expect(plugin.peertubeEngine).to.exist
expect(plugin.createdAt).to.exist
expect(plugin.settings).to.be.null
}
2019-07-19 10:37:35 +02:00
})
it('Should update the plugin and the theme', async function () {
2022-03-17 09:09:06 +01:00
this.timeout(180000)
2019-07-19 14:36:04 +02:00
// Wait the scheduler that get the latest plugins versions
await wait(6000)
2022-03-17 09:09:06 +01:00
async function testUpdate (type: 'plugin' | 'theme', name: string) {
// Fake update our plugin version
2023-04-21 15:00:01 +02:00
await sqlCommand.setPluginVersion(name, '0.0.1')
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
// Fake update package.json
const packageJSON = await command.getPackageJSON(`peertube-${type}-${name}`)
const oldVersion = packageJSON.version
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
packageJSON.version = '0.0.1'
await command.updatePackageJSON(`peertube-${type}-${name}`, packageJSON)
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
// Restart the server to take into account this change
await killallServers([ server ])
await server.run()
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
const checkConfig = async (version: string) => {
for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
expect(config[type].registered.find(r => r.name === name).version).to.equal(version)
}
}
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
const getPluginFromAPI = async () => {
const body = await command.list({ pluginType: type === 'plugin' ? PluginType.PLUGIN : PluginType.THEME })
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
return body.data.find(p => p.name === name)
}
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
{
const plugin = await getPluginFromAPI()
expect(plugin.version).to.equal('0.0.1')
expect(plugin.latestVersion).to.exist
expect(plugin.latestVersion).to.not.equal('0.0.1')
await checkConfig('0.0.1')
}
{
await command.update({ npmName: `peertube-${type}-${name}` })
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
const plugin = await getPluginFromAPI()
expect(plugin.version).to.equal(oldVersion)
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
const updatedPackageJSON = await command.getPackageJSON(`peertube-${type}-${name}`)
expect(updatedPackageJSON.version).to.equal(oldVersion)
await checkConfig(oldVersion)
}
2019-07-19 14:36:04 +02:00
}
2022-03-17 09:09:06 +01:00
await testUpdate('theme', 'background-red')
await testUpdate('plugin', 'hello-world')
2019-07-19 10:37:35 +02:00
})
it('Should uninstall the plugin', async function () {
2021-07-07 10:33:49 +02:00
await command.uninstall({ npmName: 'peertube-plugin-hello-world' })
2019-07-19 14:36:04 +02:00
2021-07-07 10:33:49 +02:00
const body = await command.list({ pluginType: PluginType.PLUGIN })
expect(body.total).to.equal(0)
expect(body.data).to.have.lengthOf(0)
2019-07-19 10:37:35 +02:00
})
it('Should list uninstalled plugins', async function () {
2021-07-07 10:33:49 +02:00
const body = await command.list({ pluginType: PluginType.PLUGIN, uninstalled: true })
expect(body.total).to.equal(1)
expect(body.data).to.have.lengthOf(1)
2019-07-19 14:36:04 +02:00
2021-07-07 10:33:49 +02:00
const plugin = body.data[0]
2019-07-19 14:36:04 +02:00
expect(plugin.name).to.equal('hello-world')
expect(plugin.enabled).to.be.false
expect(plugin.uninstalled).to.be.true
2019-07-19 10:37:35 +02:00
})
it('Should uninstall the theme', async function () {
2021-07-07 10:33:49 +02:00
await command.uninstall({ npmName: 'peertube-theme-background-red' })
2019-07-19 10:37:35 +02:00
})
it('Should have updated the configuration', async function () {
2022-03-17 09:09:06 +01:00
for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
expect(config.theme.default).to.equal('default')
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
const theme = config.theme.registered.find(r => r.name === 'background-red')
expect(theme).to.be.undefined
2019-07-19 14:36:04 +02:00
2022-03-17 09:09:06 +01:00
const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
expect(plugin).to.be.undefined
}
2019-07-19 14:36:04 +02:00
})
it('Should have updated the user theme', async function () {
2021-07-16 09:04:35 +02:00
const user = await server.users.getMyInfo()
2021-07-13 14:23:01 +02:00
expect(user.theme).to.equal('instance-default')
2019-07-19 10:37:35 +02:00
})
2021-06-30 11:45:06 +02:00
it('Should not install a broken plugin', async function () {
this.timeout(60000)
async function check () {
2021-07-07 10:33:49 +02:00
const body = await command.list({ pluginType: PluginType.PLUGIN })
const plugins = body.data
2021-06-30 11:45:06 +02:00
expect(plugins.find(p => p.name === 'test-broken')).to.not.exist
}
2021-07-07 10:33:49 +02:00
await command.install({
path: PluginsCommand.getPluginTestPath('-broken'),
2021-06-30 11:45:06 +02:00
expectedStatus: HttpStatusCode.BAD_REQUEST_400
})
await check()
2021-07-09 15:37:43 +02:00
await killallServers([ server ])
2021-07-16 09:47:51 +02:00
await server.run()
2021-06-30 11:45:06 +02:00
await check()
})
it('Should rebuild native modules on Node ABI change', async function () {
2022-08-09 11:24:08 +02:00
this.timeout(60000)
2022-08-03 15:16:56 +02:00
const removeNativeModule = async () => {
await remove(join(baseNativeModule, 'build'))
await remove(join(baseNativeModule, 'prebuilds'))
}
await command.install({ path: PluginsCommand.getPluginTestPath('-native') })
await makeGetRequest({
url: server.url,
path: '/plugins/test-native/router',
expectedStatus: HttpStatusCode.NO_CONTENT_204
})
const query = `UPDATE "application" SET "nodeABIVersion" = 1`
2023-04-21 15:00:01 +02:00
await sqlCommand.updateQuery(query)
const baseNativeModule = server.servers.buildDirectory(join('plugins', 'node_modules', 'a-native-example'))
2022-08-03 15:16:56 +02:00
await removeNativeModule()
await server.kill()
await server.run()
2022-08-09 11:24:08 +02:00
await wait(3000)
2022-08-03 15:16:56 +02:00
expect(await pathExists(join(baseNativeModule, 'build'))).to.be.true
expect(await pathExists(join(baseNativeModule, 'prebuilds'))).to.be.true
await makeGetRequest({
url: server.url,
path: '/plugins/test-native/router',
expectedStatus: HttpStatusCode.NO_CONTENT_204
})
2022-08-03 15:16:56 +02:00
await removeNativeModule()
await server.kill()
await server.run()
expect(await pathExists(join(baseNativeModule, 'build'))).to.be.false
expect(await pathExists(join(baseNativeModule, 'prebuilds'))).to.be.false
await makeGetRequest({
url: server.url,
path: '/plugins/test-native/router',
expectedStatus: HttpStatusCode.NOT_FOUND_404
})
})
2019-07-19 10:37:35 +02:00
after(async function () {
2023-04-21 15:00:01 +02:00
await sqlCommand.cleanup()
2019-07-19 10:37:35 +02:00
await cleanupTests([ server ])
})
})