Browse Source

Add plugin API tests

Chocobozzz 4 years ago
parent
commit
09071200c7

+ 1 - 0
config/test-1.yaml

@@ -21,6 +21,7 @@ storage:
   torrents: 'test1/torrents/'
   captions: 'test1/captions/'
   cache: 'test1/cache/'
+  plugins: 'test1/plugins/'
 
 admin:
   email: 'admin1@example.com'

+ 1 - 0
config/test-2.yaml

@@ -21,6 +21,7 @@ storage:
   torrents: 'test2/torrents/'
   captions: 'test2/captions/'
   cache: 'test2/cache/'
+  plugins: 'test2/plugins/'
 
 admin:
   email: 'admin2@example.com'

+ 1 - 0
config/test-3.yaml

@@ -21,6 +21,7 @@ storage:
   torrents: 'test3/torrents/'
   captions: 'test3/captions/'
   cache: 'test3/cache/'
+  plugins: 'test3/plugins/'
 
 admin:
   email: 'admin3@example.com'

+ 1 - 0
config/test-4.yaml

@@ -21,6 +21,7 @@ storage:
   torrents: 'test4/torrents/'
   captions: 'test4/captions/'
   cache: 'test4/cache/'
+  plugins: 'test4/plugins/'
 
 admin:
   email: 'admin4@example.com'

+ 1 - 0
config/test-5.yaml

@@ -21,6 +21,7 @@ storage:
   torrents: 'test5/torrents/'
   captions: 'test5/captions/'
   cache: 'test5/cache/'
+  plugins: 'test5/plugins/'
 
 admin:
   email: 'admin5@example.com'

+ 1 - 0
config/test-6.yaml

@@ -21,6 +21,7 @@ storage:
   torrents: 'test6/torrents/'
   captions: 'test6/captions/'
   cache: 'test6/cache/'
+  plugins: 'test6/plugins/'
 
 admin:
   email: 'admin6@example.com'

+ 6 - 3
server/controllers/api/plugins.ts

@@ -25,6 +25,7 @@ import { ManagePlugin } from '../../../shared/models/plugins/manage-plugin.model
 import { logger } from '../../helpers/logger'
 import { listAvailablePluginsFromIndex } from '../../lib/plugins/plugin-index'
 import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model'
+import { RegisteredSettings } from '../../../shared/models/plugins/register-setting.model'
 
 const pluginRouter = express.Router()
 
@@ -103,9 +104,11 @@ export {
 
 async function listPlugins (req: express.Request, res: express.Response) {
   const pluginType = req.query.pluginType
+  const uninstalled = req.query.uninstalled
 
   const resultList = await PluginModel.listForApi({
     pluginType,
+    uninstalled,
     start: req.query.start,
     count: req.query.count,
     sort: req.query.sort
@@ -161,9 +164,9 @@ async function uninstallPlugin (req: express.Request, res: express.Response) {
 function getPluginRegisteredSettings (req: express.Request, res: express.Response) {
   const settings = PluginManager.Instance.getRegisteredSettings(req.params.npmName)
 
-  return res.json({
-    settings
-  })
+  const json: RegisteredSettings = { settings }
+
+  return res.json(json)
 }
 
 async function updatePluginSettings (req: express.Request, res: express.Response) {

+ 1 - 1
server/lib/plugins/plugin-index.ts

@@ -21,7 +21,7 @@ async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList)
     sort,
     pluginType,
     search,
-    currentPeerTubeEngine: PEERTUBE_VERSION
+    currentPeerTubeEngine: options.currentPeerTubeEngine || PEERTUBE_VERSION
   }
 
   const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins'

+ 8 - 5
server/lib/plugins/plugin-manager.ts

@@ -8,7 +8,7 @@ import { createReadStream, createWriteStream } from 'fs'
 import { PLUGIN_GLOBAL_CSS_PATH } from '../../initializers/constants'
 import { PluginType } from '../../../shared/models/plugins/plugin.type'
 import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn'
-import { outputFile } from 'fs-extra'
+import { outputFile, readJSON } from 'fs-extra'
 import { RegisterSettingOptions } from '../../../shared/models/plugins/register-setting.model'
 import { RegisterHookOptions } from '../../../shared/models/plugins/register-hook.model'
 import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model'
@@ -174,7 +174,7 @@ export class PluginManager implements ServerHook {
       const pluginType = PluginModel.getTypeFromNpmName(npmName)
       const pluginName = PluginModel.normalizePluginName(npmName)
 
-      const packageJSON = this.getPackageJSON(pluginName, pluginType)
+      const packageJSON = await this.getPackageJSON(pluginName, pluginType)
       if (!isPackageJSONValid(packageJSON, pluginType)) {
         throw new Error('PackageJSON is invalid.')
       }
@@ -251,7 +251,7 @@ export class PluginManager implements ServerHook {
 
     logger.info('Registering plugin or theme %s.', npmName)
 
-    const packageJSON = this.getPackageJSON(plugin.name, plugin.type)
+    const packageJSON = await this.getPackageJSON(plugin.name, plugin.type)
     const pluginPath = this.getPluginPath(plugin.name, plugin.type)
 
     if (!isPackageJSONValid(packageJSON, plugin.type)) {
@@ -286,7 +286,10 @@ export class PluginManager implements ServerHook {
   private async registerPlugin (plugin: PluginModel, pluginPath: string, packageJSON: PluginPackageJson) {
     const npmName = PluginModel.buildNpmName(plugin.name, plugin.type)
 
-    const library: PluginLibrary = require(join(pluginPath, packageJSON.library))
+    // Delete cache if needed
+    const modulePath = join(pluginPath, packageJSON.library)
+    delete require.cache[modulePath]
+    const library: PluginLibrary = require(modulePath)
 
     if (!isLibraryCodeValid(library)) {
       throw new Error('Library code is not valid (miss register or unregister function)')
@@ -350,7 +353,7 @@ export class PluginManager implements ServerHook {
   private getPackageJSON (pluginName: string, pluginType: PluginType) {
     const pluginPath = join(this.getPluginPath(pluginName, pluginType), 'package.json')
 
-    return require(pluginPath) as PluginPackageJson
+    return readJSON(pluginPath) as Promise<PluginPackageJson>
   }
 
   private getPluginPath (pluginName: string, pluginType: PluginType) {

+ 4 - 2
server/lib/plugins/yarn.ts

@@ -13,7 +13,9 @@ async function installNpmPlugin (npmName: string, version?: string) {
   let toInstall = npmName
   if (version) toInstall += `@${version}`
 
-  await execYarn('add ' + toInstall)
+  const { stdout } = await execYarn('add ' + toInstall)
+
+  logger.debug('Added a yarn package.', { yarnStdout: stdout })
 }
 
 async function installNpmPluginFromDisk (path: string) {
@@ -46,7 +48,7 @@ async function execYarn (command: string) {
       await outputJSON(pluginPackageJSON, {})
     }
 
-    await execShell(`yarn ${command}`, { cwd: pluginDirectory })
+    return execShell(`yarn ${command}`, { cwd: pluginDirectory })
   } catch (result) {
     logger.error('Cannot exec yarn.', { command, err: result.err, stderr: result.stderr })
 

+ 3 - 0
server/middlewares/validators/plugins.ts

@@ -127,6 +127,9 @@ const listAvailablePluginsValidator = [
   query('pluginType')
     .optional()
     .custom(isPluginTypeValid).withMessage('Should have a valid plugin type'),
+  query('currentPeerTubeEngine')
+    .optional()
+    .custom(isPluginVersionValid).withMessage('Should have a valid current peertube engine'),
 
   (req: express.Request, res: express.Response, next: express.NextFunction) => {
     logger.debug('Checking enabledPluginValidator parameters', { parameters: req.query })

+ 13 - 1
server/tests/api/check-params/plugins.ts

@@ -152,7 +152,8 @@ describe('Test server plugins API validators', function () {
     const path = '/api/v1/plugins/available'
     const baseQuery = {
       search: 'super search',
-      pluginType: PluginType.PLUGIN
+      pluginType: PluginType.PLUGIN,
+      currentPeerTubeEngine: '1.2.3'
     }
 
     it('Should fail with an invalid token', async function () {
@@ -198,6 +199,17 @@ describe('Test server plugins API validators', function () {
       })
     })
 
+    it('Should fail with an invalid current peertube engine', async function () {
+      const query = immutableAssign(baseQuery, { currentPeerTubeEngine: '1.0' })
+
+      await makeGetRequest({
+        url: server.url,
+        path,
+        token: server.accessToken,
+        query
+      })
+    })
+
     it('Should success with the correct parameters', async function () {
       await makeGetRequest({
         url: server.url,

+ 338 - 51
server/tests/api/server/plugins.ts

@@ -2,129 +2,416 @@
 
 import 'mocha'
 import * as chai from 'chai'
-import { About } from '../../../../shared/models/server/about.model'
-import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
 import {
   cleanupTests,
-  deleteCustomConfig,
+  closeAllSequelize,
   flushAndRunServer,
-  getAbout,
-  getConfig,
-  getCustomConfig, installPlugin,
-  killallServers, parallelTests,
-  registerUser,
-  reRunServer, ServerInfo,
+  getConfig, getMyUserInformation, getPluginPackageJSON,
+  getPlugin,
+  getPluginRegisteredSettings,
+  getPluginsCSS,
+  installPlugin, killallServers,
+  listAvailablePlugins,
+  listPlugins, reRunServer,
+  ServerInfo,
   setAccessTokensToServers,
-  updateCustomConfig, uploadVideo
+  setPluginVersion, uninstallPlugin,
+  updateCustomSubConfig, updateMyUser, updatePluginPackageJSON, updatePlugin,
+  updatePluginSettings,
+  wait
 } from '../../../../shared/extra-utils'
-import { ServerConfig } from '../../../../shared/models'
+import { PluginType } from '../../../../shared/models/plugins/plugin.type'
+import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model'
+import { ServerConfig } from '../../../../shared/models/server'
+import { RegisteredSettings } from '../../../../shared/models/plugins/register-setting.model'
 import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugin.model'
+import { User } from '../../../../shared/models/users'
+import { PluginPackageJson } from '../../../../shared/models/plugins/plugin-package-json.model'
 
 const expect = chai.expect
 
 describe('Test plugins', function () {
-  let server = null
+  let server: ServerInfo = null
 
   before(async function () {
     this.timeout(30000)
 
-    server = await flushAndRunServer(1)
+    const configOverride = {
+      plugins: {
+        index: { check_latest_versions_interval: '5 seconds' }
+      }
+    }
+    server = await flushAndRunServer(1, configOverride)
     await setAccessTokensToServers([ server ])
+  })
+
+  it('Should list and search available plugins and themes', async function () {
+    this.timeout(30000)
 
     {
-      await installPlugin({ url: server.url, accessToken: server.accessToken, npmName: 'peertube-plugin-hello-world' })
+      const res = await listAvailablePlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        count: 1,
+        start: 0,
+        pluginType: PluginType.THEME,
+        search: 'background-red'
+      })
+
+      expect(res.body.total).to.be.at.least(1)
+      expect(res.body.data).to.have.lengthOf(1)
     }
 
     {
-      await installPlugin({ url: server.url, accessToken: server.accessToken, npmName: 'peertube-plugin-background-color' })
+      const res1 = await listAvailablePlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        count: 2,
+        start: 0,
+        sort: 'npmName'
+      })
+      const data1: PeerTubePluginIndex[] = res1.body.data
+
+      expect(res1.body.total).to.be.at.least(2)
+      expect(data1).to.have.lengthOf(2)
+
+      const res2 = await listAvailablePlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        count: 2,
+        start: 0,
+        sort: '-npmName'
+      })
+      const data2: PeerTubePluginIndex[] = res2.body.data
+
+      expect(res2.body.total).to.be.at.least(2)
+      expect(data2).to.have.lengthOf(2)
+
+      expect(data1[0].npmName).to.not.equal(data2[ 0 ].npmName)
     }
-  })
 
-  it('Should list available plugins and themes', async function () {
-    // List without filter
-    // List with filter (plugin and theme)
-  })
+    {
+      const res = await listAvailablePlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        count: 10,
+        start: 0,
+        pluginType: PluginType.THEME,
+        search: 'background-red',
+        currentPeerTubeEngine: '1.0.0'
+      })
+      const data: PeerTubePluginIndex[] = res.body.data
 
-  it('Should search available plugins', async function () {
-    // Search with filter (plugin and theme)
-    // Add pagination
-    // Add sort
-    // Add peertube engine
+      const p = data.find(p => p.npmName === 'peertube-theme-background-red')
+      expect(p).to.be.undefined
+    }
   })
 
   it('Should have an empty global css', async function () {
-    // get /global.css
+    const res = await getPluginsCSS(server.url)
+
+    expect(res.text).to.be.empty
   })
 
   it('Should install a plugin and a theme', async function () {
+    this.timeout(30000)
+
+    await installPlugin({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-plugin-hello-world'
+    })
 
+    await installPlugin({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-theme-background-red'
+    })
   })
 
   it('Should have the correct global css', async function () {
-    // get /global.css
+    const res = await getPluginsCSS(server.url)
+
+    expect(res.text).to.contain('--mainBackgroundColor')
   })
 
   it('Should have the plugin loaded in the configuration', async function () {
-    // Check registered themes/plugins
+    const res = await getConfig(server.url)
+    const config: ServerConfig = res.body
+
+    const theme = config.theme.registered.find(r => r.name === 'background-red')
+    expect(theme).to.not.be.undefined
+
+    const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
+    expect(plugin).to.not.be.undefined
   })
 
   it('Should update the default theme in the configuration', async function () {
-    // Update config
+    await updateCustomSubConfig(server.url, server.accessToken, { theme: { default: 'background-red' } })
+
+    const res = await getConfig(server.url)
+    const config: ServerConfig = res.body
+
+    expect(config.theme.default).to.equal('background-red')
   })
 
-  it('Should list plugins and themes', async function () {
-    // List without filter
-    // List with filter (theme/plugin)
-    // List with pagination
-    // List with sort
+  it('Should update my default theme', async function () {
+    await updateMyUser({
+      url: server.url,
+      accessToken: server.accessToken,
+      theme: 'background-red'
+    })
+
+    const res = await getMyUserInformation(server.url, server.accessToken)
+    expect((res.body as User).theme).to.equal('background-red')
   })
 
-  it('Should get a plugin and a theme', async function () {
-    // Get plugin
-    // Get theme
+  it('Should list plugins and themes', async function () {
+    {
+      const res = await listPlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        count: 1,
+        start: 0,
+        pluginType: PluginType.THEME
+      })
+      const data: PeerTubePlugin[] = res.body.data
+
+      expect(res.body.total).to.be.at.least(1)
+      expect(data).to.have.lengthOf(1)
+      expect(data[0].name).to.equal('background-red')
+    }
+
+    {
+      const res = await listPlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        count: 2,
+        start: 0,
+        sort: 'name'
+      })
+      const data: PeerTubePlugin[] = res.body.data
+
+      expect(data[0].name).to.equal('background-red')
+      expect(data[1].name).to.equal('hello-world')
+    }
+
+    {
+      const res = await listPlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        count: 2,
+        start: 1,
+        sort: 'name'
+      })
+      const data: PeerTubePlugin[] = res.body.data
+
+      expect(data[0].name).to.equal('hello-world')
+    }
   })
 
   it('Should get registered settings', async function () {
-    // Get plugin
+    const res = await getPluginRegisteredSettings({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-plugin-hello-world'
+    })
+
+    const settings = (res.body as RegisteredSettings).settings
+
+    expect(settings).to.have.length.at.least(1)
+
+    const adminNameSettings = settings.find(s => s.name === 'admin-name')
+    expect(adminNameSettings).to.not.be.undefined
   })
 
   it('Should update the settings', async function () {
-    // Update /settings
+    const settings = {
+      'admin-name': 'Cid'
+    }
+
+    await updatePluginSettings({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-plugin-hello-world',
+      settings
+    })
+  })
+
+  it('Should get a plugin and a theme', async function () {
+    {
+      const res = await getPlugin({
+        url: server.url,
+        accessToken: server.accessToken,
+        npmName: 'peertube-plugin-hello-world'
+      })
+
+      const plugin: PeerTubePlugin = res.body
+
+      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')
+    }
+
+    {
+      const res = await getPlugin({
+        url: server.url,
+        accessToken: server.accessToken,
+        npmName: 'peertube-theme-background-red'
+      })
+
+      const plugin: PeerTubePlugin = res.body
 
-    // get /plugin
+      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
+    }
   })
 
   it('Should update the plugin and the theme', async function () {
-    // update BDD -> 0.0.1
-    // update package.json (theme + plugin)
-    // list to check versions
-    // update plugin + theme
-    // list to check they have been updated
-    // check package.json are upgraded too
+    this.timeout(30000)
+
+    // Wait the scheduler that get the latest plugins versions
+    await wait(6000)
+
+    // Fake update our plugin version
+    await setPluginVersion(server.internalServerNumber, 'hello-world', '0.0.1')
+
+    // Fake update package.json
+    const packageJSON: PluginPackageJson = await getPluginPackageJSON(server, 'peertube-plugin-hello-world')
+    const oldVersion = packageJSON.version
+
+    packageJSON.version = '0.0.1'
+    await updatePluginPackageJSON(server, 'peertube-plugin-hello-world', packageJSON)
+
+    // Restart the server to take into account this change
+    killallServers([ server ])
+    await reRunServer(server)
+
+    {
+      const res = await listPlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        pluginType: PluginType.PLUGIN
+      })
+
+      const plugin: PeerTubePlugin = res.body.data[0]
+
+      expect(plugin.version).to.equal('0.0.1')
+      expect(plugin.latestVersion).to.exist
+      expect(plugin.latestVersion).to.not.equal('0.0.1')
+    }
+
+    {
+      await updatePlugin({
+        url: server.url,
+        accessToken: server.accessToken,
+        npmName: 'peertube-plugin-hello-world'
+      })
+
+      const res = await listPlugins({
+        url: server.url,
+        accessToken: server.accessToken,
+        pluginType: PluginType.PLUGIN
+      })
+
+      const plugin: PeerTubePlugin = res.body.data[0]
+
+      expect(plugin.version).to.equal(oldVersion)
+
+      const updatedPackageJSON: PluginPackageJson = await getPluginPackageJSON(server, 'peertube-plugin-hello-world')
+      expect(updatedPackageJSON.version).to.equal(oldVersion)
+    }
   })
 
   it('Should uninstall the plugin', async function () {
-    // uninstall
-    // list
+    await uninstallPlugin({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-plugin-hello-world'
+    })
+
+    const res = await listPlugins({
+      url: server.url,
+      accessToken: server.accessToken,
+      pluginType: PluginType.PLUGIN
+    })
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.have.lengthOf(0)
   })
 
   it('Should have an empty global css', async function () {
-    // get /global.css
+    const res = await getPluginsCSS(server.url)
+
+    expect(res.text).to.be.empty
   })
 
   it('Should list uninstalled plugins', async function () {
-    // { uninstalled: true }
+    const res = await listPlugins({
+      url: server.url,
+      accessToken: server.accessToken,
+      pluginType: PluginType.PLUGIN,
+      uninstalled: true
+    })
+
+    expect(res.body.total).to.equal(1)
+    expect(res.body.data).to.have.lengthOf(1)
+
+    const plugin: PeerTubePlugin = res.body.data[0]
+    expect(plugin.name).to.equal('hello-world')
+    expect(plugin.enabled).to.be.false
+    expect(plugin.uninstalled).to.be.true
   })
 
   it('Should uninstall the theme', async function () {
-    // Uninstall
+    await uninstallPlugin({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-theme-background-red'
+    })
   })
 
   it('Should have updated the configuration', async function () {
     // get /config (default theme + registered themes + registered plugins)
+    const res = await getConfig(server.url)
+    const config: ServerConfig = res.body
+
+    expect(config.theme.default).to.equal('default')
+
+    const theme = config.theme.registered.find(r => r.name === 'background-red')
+    expect(theme).to.be.undefined
+
+    const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
+    expect(plugin).to.be.undefined
+  })
+
+  it('Should have updated the user theme', async function () {
+    const res = await getMyUserInformation(server.url, server.accessToken)
+    expect((res.body as User).theme).to.equal('instance-default')
   })
 
   after(async function () {
+    await closeAllSequelize([ server ])
     await cleanupTests([ server ])
   })
 })

+ 2 - 2
server/tests/plugins/action-hooks.ts

@@ -7,7 +7,7 @@ import { setAccessTokensToServers } from '../../../shared/extra-utils'
 
 const expect = chai.expect
 
-describe('Test plugin filter hooks', function () {
+describe('Test plugin action hooks', function () {
   let server: ServerInfo
 
   before(async function () {
@@ -18,7 +18,7 @@ describe('Test plugin filter hooks', function () {
   })
 
   it('Should execute ', async function () {
-
+    // empty
   })
 
   after(async function () {

+ 1 - 1
server/tests/plugins/filter-hooks.ts

@@ -18,7 +18,7 @@ describe('Test plugin filter hooks', function () {
   })
 
   it('Should execute ', async function () {
-
+    // empty
   })
 
   after(async function () {

+ 4 - 4
server/tools/peertube-plugins.ts

@@ -65,9 +65,9 @@ async function pluginsListCLI () {
   const { url, username, password } = await getServerCredentials(program)
   const accessToken = await getAdminTokenOrDie(url, username, password)
 
-  let type: PluginType
-  if (program['onlyThemes']) type = PluginType.THEME
-  if (program['onlyPlugins']) type = PluginType.PLUGIN
+  let pluginType: PluginType
+  if (program['onlyThemes']) pluginType = PluginType.THEME
+  if (program['onlyPlugins']) pluginType = PluginType.PLUGIN
 
   const res = await listPlugins({
     url,
@@ -75,7 +75,7 @@ async function pluginsListCLI () {
     start: 0,
     count: 100,
     sort: 'name',
-    type
+    pluginType
   })
   const plugins: PeerTubePlugin[] = res.body.data
 

+ 10 - 0
shared/extra-utils/miscs/sql.ts

@@ -1,5 +1,6 @@
 import { QueryTypes, Sequelize } from 'sequelize'
 import { ServerInfo } from '../server/servers'
+import { PluginType } from '../../models/plugins/plugin.type'
 
 let sequelizes: { [ id: number ]: Sequelize } = {}
 
@@ -72,10 +73,19 @@ async function closeAllSequelize (servers: ServerInfo[]) {
   }
 }
 
+function setPluginVersion (internalServerNumber: number, pluginName: string, newVersion: string) {
+  const seq = getSequelize(internalServerNumber)
+
+  const options = { type: QueryTypes.UPDATE }
+
+  return seq.query(`UPDATE "plugin" SET "version" = '${newVersion}' WHERE "name" = '${pluginName}'`, options)
+}
+
 export {
   setVideoField,
   setPlaylistField,
   setActorField,
   countVideoViewsOf,
+  setPluginVersion,
   closeAllSequelize
 }

+ 81 - 9
shared/extra-utils/server/plugins.ts

@@ -1,5 +1,10 @@
-import { makeGetRequest, makePostBodyRequest } from '../requests/requests'
+import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
 import { PluginType } from '../../models/plugins/plugin.type'
+import { PeertubePluginIndexList } from '../../models/plugins/peertube-plugin-index-list.model'
+import { readJSON, writeJSON } from 'fs-extra'
+import { ServerInfo } from './servers'
+import { root } from '../miscs/miscs'
+import { join } from 'path'
 
 function listPlugins (parameters: {
   url: string,
@@ -7,10 +12,11 @@ function listPlugins (parameters: {
   start?: number,
   count?: number,
   sort?: string,
-  type?: PluginType,
+  pluginType?: PluginType,
+  uninstalled?: boolean,
   expectedStatus?: number
 }) {
-  const { url, accessToken, start, count, sort, type, expectedStatus = 200 } = parameters
+  const { url, accessToken, start, count, sort, pluginType, uninstalled, expectedStatus = 200 } = parameters
   const path = '/api/v1/plugins'
 
   return makeGetRequest({
@@ -21,12 +27,45 @@ function listPlugins (parameters: {
       start,
       count,
       sort,
-      type
+      pluginType,
+      uninstalled
     },
     statusCodeExpected: expectedStatus
   })
 }
 
+function listAvailablePlugins (parameters: {
+  url: string,
+  accessToken: string,
+  start?: number,
+  count?: number,
+  sort?: string,
+  pluginType?: PluginType,
+  currentPeerTubeEngine?: string,
+  search?: string
+  expectedStatus?: number
+}) {
+  const { url, accessToken, start, count, sort, pluginType, search, currentPeerTubeEngine, expectedStatus = 200 } = parameters
+  const path = '/api/v1/plugins/available'
+
+  const query: PeertubePluginIndexList = {
+    start,
+    count,
+    sort,
+    pluginType,
+    currentPeerTubeEngine,
+    search
+  }
+
+  return makeGetRequest({
+    url,
+    path,
+    token: accessToken,
+    query,
+    statusCodeExpected: expectedStatus
+  })
+}
+
 function getPlugin (parameters: {
   url: string,
   accessToken: string,
@@ -44,19 +83,21 @@ function getPlugin (parameters: {
   })
 }
 
-function getPluginSettings (parameters: {
+function updatePluginSettings (parameters: {
   url: string,
   accessToken: string,
   npmName: string,
+  settings: any,
   expectedStatus?: number
 }) {
-  const { url, accessToken, npmName, expectedStatus = 200 } = parameters
+  const { url, accessToken, npmName, settings, expectedStatus = 204 } = parameters
   const path = '/api/v1/plugins/' + npmName + '/settings'
 
-  return makeGetRequest({
+  return makePutBodyRequest({
     url,
     path,
     token: accessToken,
+    fields: { settings },
     statusCodeExpected: expectedStatus
   })
 }
@@ -134,12 +175,43 @@ function uninstallPlugin (parameters: {
   })
 }
 
+function getPluginsCSS (url: string) {
+  const path = '/plugins/global.css'
+
+  return makeGetRequest({
+    url,
+    path,
+    statusCodeExpected: 200
+  })
+}
+
+function getPackageJSONPath (server: ServerInfo, npmName: string) {
+  return join(root(), 'test' + server.internalServerNumber, 'plugins', 'node_modules', npmName, 'package.json')
+}
+
+function updatePluginPackageJSON (server: ServerInfo, npmName: string, json: any) {
+  const path = getPackageJSONPath(server, npmName)
+
+  return writeJSON(path, json)
+}
+
+function getPluginPackageJSON (server: ServerInfo, npmName: string) {
+  const path = getPackageJSONPath(server, npmName)
+
+  return readJSON(path)
+}
+
 export {
   listPlugins,
+  listAvailablePlugins,
   installPlugin,
+  getPluginsCSS,
   updatePlugin,
   getPlugin,
   uninstallPlugin,
-  getPluginSettings,
-  getPluginRegisteredSettings
+  updatePluginSettings,
+  getPluginRegisteredSettings,
+  getPackageJSONPath,
+  updatePluginPackageJSON,
+  getPluginPackageJSON
 }

+ 4 - 0
shared/models/plugins/register-setting.model.ts

@@ -4,3 +4,7 @@ export interface RegisterSettingOptions {
   type: 'input'
   default?: string
 }
+
+export interface RegisteredSettings {
+  settings: RegisterSettingOptions[]
+}