aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/plugins.ts9
-rw-r--r--server/lib/plugins/plugin-index.ts2
-rw-r--r--server/lib/plugins/plugin-manager.ts13
-rw-r--r--server/lib/plugins/yarn.ts6
-rw-r--r--server/middlewares/validators/plugins.ts3
-rw-r--r--server/tests/api/check-params/plugins.ts14
-rw-r--r--server/tests/api/server/plugins.ts389
-rw-r--r--server/tests/plugins/action-hooks.ts4
-rw-r--r--server/tests/plugins/filter-hooks.ts2
-rw-r--r--server/tools/peertube-plugins.ts8
10 files changed, 380 insertions, 70 deletions
diff --git a/server/controllers/api/plugins.ts b/server/controllers/api/plugins.ts
index bb410e891..de58a7350 100644
--- a/server/controllers/api/plugins.ts
+++ b/server/controllers/api/plugins.ts
@@ -25,6 +25,7 @@ import { ManagePlugin } from '../../../shared/models/plugins/manage-plugin.model
25import { logger } from '../../helpers/logger' 25import { logger } from '../../helpers/logger'
26import { listAvailablePluginsFromIndex } from '../../lib/plugins/plugin-index' 26import { listAvailablePluginsFromIndex } from '../../lib/plugins/plugin-index'
27import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model' 27import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model'
28import { RegisteredSettings } from '../../../shared/models/plugins/register-setting.model'
28 29
29const pluginRouter = express.Router() 30const pluginRouter = express.Router()
30 31
@@ -103,9 +104,11 @@ export {
103 104
104async function listPlugins (req: express.Request, res: express.Response) { 105async function listPlugins (req: express.Request, res: express.Response) {
105 const pluginType = req.query.pluginType 106 const pluginType = req.query.pluginType
107 const uninstalled = req.query.uninstalled
106 108
107 const resultList = await PluginModel.listForApi({ 109 const resultList = await PluginModel.listForApi({
108 pluginType, 110 pluginType,
111 uninstalled,
109 start: req.query.start, 112 start: req.query.start,
110 count: req.query.count, 113 count: req.query.count,
111 sort: req.query.sort 114 sort: req.query.sort
@@ -161,9 +164,9 @@ async function uninstallPlugin (req: express.Request, res: express.Response) {
161function getPluginRegisteredSettings (req: express.Request, res: express.Response) { 164function getPluginRegisteredSettings (req: express.Request, res: express.Response) {
162 const settings = PluginManager.Instance.getRegisteredSettings(req.params.npmName) 165 const settings = PluginManager.Instance.getRegisteredSettings(req.params.npmName)
163 166
164 return res.json({ 167 const json: RegisteredSettings = { settings }
165 settings 168
166 }) 169 return res.json(json)
167} 170}
168 171
169async function updatePluginSettings (req: express.Request, res: express.Response) { 172async function updatePluginSettings (req: express.Request, res: express.Response) {
diff --git a/server/lib/plugins/plugin-index.ts b/server/lib/plugins/plugin-index.ts
index 6b7810618..25b4f3c61 100644
--- a/server/lib/plugins/plugin-index.ts
+++ b/server/lib/plugins/plugin-index.ts
@@ -21,7 +21,7 @@ async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList)
21 sort, 21 sort,
22 pluginType, 22 pluginType,
23 search, 23 search,
24 currentPeerTubeEngine: PEERTUBE_VERSION 24 currentPeerTubeEngine: options.currentPeerTubeEngine || PEERTUBE_VERSION
25 } 25 }
26 26
27 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins' 27 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins'
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts
index ac31b06dc..9afda97ea 100644
--- a/server/lib/plugins/plugin-manager.ts
+++ b/server/lib/plugins/plugin-manager.ts
@@ -8,7 +8,7 @@ import { createReadStream, createWriteStream } from 'fs'
8import { PLUGIN_GLOBAL_CSS_PATH } from '../../initializers/constants' 8import { PLUGIN_GLOBAL_CSS_PATH } from '../../initializers/constants'
9import { PluginType } from '../../../shared/models/plugins/plugin.type' 9import { PluginType } from '../../../shared/models/plugins/plugin.type'
10import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn' 10import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn'
11import { outputFile } from 'fs-extra' 11import { outputFile, readJSON } from 'fs-extra'
12import { RegisterSettingOptions } from '../../../shared/models/plugins/register-setting.model' 12import { RegisterSettingOptions } from '../../../shared/models/plugins/register-setting.model'
13import { RegisterHookOptions } from '../../../shared/models/plugins/register-hook.model' 13import { RegisterHookOptions } from '../../../shared/models/plugins/register-hook.model'
14import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model' 14import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model'
@@ -174,7 +174,7 @@ export class PluginManager implements ServerHook {
174 const pluginType = PluginModel.getTypeFromNpmName(npmName) 174 const pluginType = PluginModel.getTypeFromNpmName(npmName)
175 const pluginName = PluginModel.normalizePluginName(npmName) 175 const pluginName = PluginModel.normalizePluginName(npmName)
176 176
177 const packageJSON = this.getPackageJSON(pluginName, pluginType) 177 const packageJSON = await this.getPackageJSON(pluginName, pluginType)
178 if (!isPackageJSONValid(packageJSON, pluginType)) { 178 if (!isPackageJSONValid(packageJSON, pluginType)) {
179 throw new Error('PackageJSON is invalid.') 179 throw new Error('PackageJSON is invalid.')
180 } 180 }
@@ -251,7 +251,7 @@ export class PluginManager implements ServerHook {
251 251
252 logger.info('Registering plugin or theme %s.', npmName) 252 logger.info('Registering plugin or theme %s.', npmName)
253 253
254 const packageJSON = this.getPackageJSON(plugin.name, plugin.type) 254 const packageJSON = await this.getPackageJSON(plugin.name, plugin.type)
255 const pluginPath = this.getPluginPath(plugin.name, plugin.type) 255 const pluginPath = this.getPluginPath(plugin.name, plugin.type)
256 256
257 if (!isPackageJSONValid(packageJSON, plugin.type)) { 257 if (!isPackageJSONValid(packageJSON, plugin.type)) {
@@ -286,7 +286,10 @@ export class PluginManager implements ServerHook {
286 private async registerPlugin (plugin: PluginModel, pluginPath: string, packageJSON: PluginPackageJson) { 286 private async registerPlugin (plugin: PluginModel, pluginPath: string, packageJSON: PluginPackageJson) {
287 const npmName = PluginModel.buildNpmName(plugin.name, plugin.type) 287 const npmName = PluginModel.buildNpmName(plugin.name, plugin.type)
288 288
289 const library: PluginLibrary = require(join(pluginPath, packageJSON.library)) 289 // Delete cache if needed
290 const modulePath = join(pluginPath, packageJSON.library)
291 delete require.cache[modulePath]
292 const library: PluginLibrary = require(modulePath)
290 293
291 if (!isLibraryCodeValid(library)) { 294 if (!isLibraryCodeValid(library)) {
292 throw new Error('Library code is not valid (miss register or unregister function)') 295 throw new Error('Library code is not valid (miss register or unregister function)')
@@ -350,7 +353,7 @@ export class PluginManager implements ServerHook {
350 private getPackageJSON (pluginName: string, pluginType: PluginType) { 353 private getPackageJSON (pluginName: string, pluginType: PluginType) {
351 const pluginPath = join(this.getPluginPath(pluginName, pluginType), 'package.json') 354 const pluginPath = join(this.getPluginPath(pluginName, pluginType), 'package.json')
352 355
353 return require(pluginPath) as PluginPackageJson 356 return readJSON(pluginPath) as Promise<PluginPackageJson>
354 } 357 }
355 358
356 private getPluginPath (pluginName: string, pluginType: PluginType) { 359 private getPluginPath (pluginName: string, pluginType: PluginType) {
diff --git a/server/lib/plugins/yarn.ts b/server/lib/plugins/yarn.ts
index 74c67653c..e40351b6e 100644
--- a/server/lib/plugins/yarn.ts
+++ b/server/lib/plugins/yarn.ts
@@ -13,7 +13,9 @@ async function installNpmPlugin (npmName: string, version?: string) {
13 let toInstall = npmName 13 let toInstall = npmName
14 if (version) toInstall += `@${version}` 14 if (version) toInstall += `@${version}`
15 15
16 await execYarn('add ' + toInstall) 16 const { stdout } = await execYarn('add ' + toInstall)
17
18 logger.debug('Added a yarn package.', { yarnStdout: stdout })
17} 19}
18 20
19async function installNpmPluginFromDisk (path: string) { 21async function installNpmPluginFromDisk (path: string) {
@@ -46,7 +48,7 @@ async function execYarn (command: string) {
46 await outputJSON(pluginPackageJSON, {}) 48 await outputJSON(pluginPackageJSON, {})
47 } 49 }
48 50
49 await execShell(`yarn ${command}`, { cwd: pluginDirectory }) 51 return execShell(`yarn ${command}`, { cwd: pluginDirectory })
50 } catch (result) { 52 } catch (result) {
51 logger.error('Cannot exec yarn.', { command, err: result.err, stderr: result.stderr }) 53 logger.error('Cannot exec yarn.', { command, err: result.err, stderr: result.stderr })
52 54
diff --git a/server/middlewares/validators/plugins.ts b/server/middlewares/validators/plugins.ts
index 68704bf56..dc3f1454a 100644
--- a/server/middlewares/validators/plugins.ts
+++ b/server/middlewares/validators/plugins.ts
@@ -127,6 +127,9 @@ const listAvailablePluginsValidator = [
127 query('pluginType') 127 query('pluginType')
128 .optional() 128 .optional()
129 .custom(isPluginTypeValid).withMessage('Should have a valid plugin type'), 129 .custom(isPluginTypeValid).withMessage('Should have a valid plugin type'),
130 query('currentPeerTubeEngine')
131 .optional()
132 .custom(isPluginVersionValid).withMessage('Should have a valid current peertube engine'),
130 133
131 (req: express.Request, res: express.Response, next: express.NextFunction) => { 134 (req: express.Request, res: express.Response, next: express.NextFunction) => {
132 logger.debug('Checking enabledPluginValidator parameters', { parameters: req.query }) 135 logger.debug('Checking enabledPluginValidator parameters', { parameters: req.query })
diff --git a/server/tests/api/check-params/plugins.ts b/server/tests/api/check-params/plugins.ts
index dd03766c9..83ce6f451 100644
--- a/server/tests/api/check-params/plugins.ts
+++ b/server/tests/api/check-params/plugins.ts
@@ -152,7 +152,8 @@ describe('Test server plugins API validators', function () {
152 const path = '/api/v1/plugins/available' 152 const path = '/api/v1/plugins/available'
153 const baseQuery = { 153 const baseQuery = {
154 search: 'super search', 154 search: 'super search',
155 pluginType: PluginType.PLUGIN 155 pluginType: PluginType.PLUGIN,
156 currentPeerTubeEngine: '1.2.3'
156 } 157 }
157 158
158 it('Should fail with an invalid token', async function () { 159 it('Should fail with an invalid token', async function () {
@@ -198,6 +199,17 @@ describe('Test server plugins API validators', function () {
198 }) 199 })
199 }) 200 })
200 201
202 it('Should fail with an invalid current peertube engine', async function () {
203 const query = immutableAssign(baseQuery, { currentPeerTubeEngine: '1.0' })
204
205 await makeGetRequest({
206 url: server.url,
207 path,
208 token: server.accessToken,
209 query
210 })
211 })
212
201 it('Should success with the correct parameters', async function () { 213 it('Should success with the correct parameters', async function () {
202 await makeGetRequest({ 214 await makeGetRequest({
203 url: server.url, 215 url: server.url,
diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts
index 9a623c553..b3d003f45 100644
--- a/server/tests/api/server/plugins.ts
+++ b/server/tests/api/server/plugins.ts
@@ -2,129 +2,416 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { About } from '../../../../shared/models/server/about.model'
6import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
7import { 5import {
8 cleanupTests, 6 cleanupTests,
9 deleteCustomConfig, 7 closeAllSequelize,
10 flushAndRunServer, 8 flushAndRunServer,
11 getAbout, 9 getConfig, getMyUserInformation, getPluginPackageJSON,
12 getConfig, 10 getPlugin,
13 getCustomConfig, installPlugin, 11 getPluginRegisteredSettings,
14 killallServers, parallelTests, 12 getPluginsCSS,
15 registerUser, 13 installPlugin, killallServers,
16 reRunServer, ServerInfo, 14 listAvailablePlugins,
15 listPlugins, reRunServer,
16 ServerInfo,
17 setAccessTokensToServers, 17 setAccessTokensToServers,
18 updateCustomConfig, uploadVideo 18 setPluginVersion, uninstallPlugin,
19 updateCustomSubConfig, updateMyUser, updatePluginPackageJSON, updatePlugin,
20 updatePluginSettings,
21 wait
19} from '../../../../shared/extra-utils' 22} from '../../../../shared/extra-utils'
20import { ServerConfig } from '../../../../shared/models' 23import { PluginType } from '../../../../shared/models/plugins/plugin.type'
24import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model'
25import { ServerConfig } from '../../../../shared/models/server'
26import { RegisteredSettings } from '../../../../shared/models/plugins/register-setting.model'
21import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugin.model' 27import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugin.model'
28import { User } from '../../../../shared/models/users'
29import { PluginPackageJson } from '../../../../shared/models/plugins/plugin-package-json.model'
22 30
23const expect = chai.expect 31const expect = chai.expect
24 32
25describe('Test plugins', function () { 33describe('Test plugins', function () {
26 let server = null 34 let server: ServerInfo = null
27 35
28 before(async function () { 36 before(async function () {
29 this.timeout(30000) 37 this.timeout(30000)
30 38
31 server = await flushAndRunServer(1) 39 const configOverride = {
40 plugins: {
41 index: { check_latest_versions_interval: '5 seconds' }
42 }
43 }
44 server = await flushAndRunServer(1, configOverride)
32 await setAccessTokensToServers([ server ]) 45 await setAccessTokensToServers([ server ])
46 })
47
48 it('Should list and search available plugins and themes', async function () {
49 this.timeout(30000)
33 50
34 { 51 {
35 await installPlugin({ url: server.url, accessToken: server.accessToken, npmName: 'peertube-plugin-hello-world' }) 52 const res = await listAvailablePlugins({
53 url: server.url,
54 accessToken: server.accessToken,
55 count: 1,
56 start: 0,
57 pluginType: PluginType.THEME,
58 search: 'background-red'
59 })
60
61 expect(res.body.total).to.be.at.least(1)
62 expect(res.body.data).to.have.lengthOf(1)
36 } 63 }
37 64
38 { 65 {
39 await installPlugin({ url: server.url, accessToken: server.accessToken, npmName: 'peertube-plugin-background-color' }) 66 const res1 = await listAvailablePlugins({
67 url: server.url,
68 accessToken: server.accessToken,
69 count: 2,
70 start: 0,
71 sort: 'npmName'
72 })
73 const data1: PeerTubePluginIndex[] = res1.body.data
74
75 expect(res1.body.total).to.be.at.least(2)
76 expect(data1).to.have.lengthOf(2)
77
78 const res2 = await listAvailablePlugins({
79 url: server.url,
80 accessToken: server.accessToken,
81 count: 2,
82 start: 0,
83 sort: '-npmName'
84 })
85 const data2: PeerTubePluginIndex[] = res2.body.data
86
87 expect(res2.body.total).to.be.at.least(2)
88 expect(data2).to.have.lengthOf(2)
89
90 expect(data1[0].npmName).to.not.equal(data2[ 0 ].npmName)
40 } 91 }
41 })
42 92
43 it('Should list available plugins and themes', async function () { 93 {
44 // List without filter 94 const res = await listAvailablePlugins({
45 // List with filter (plugin and theme) 95 url: server.url,
46 }) 96 accessToken: server.accessToken,
97 count: 10,
98 start: 0,
99 pluginType: PluginType.THEME,
100 search: 'background-red',
101 currentPeerTubeEngine: '1.0.0'
102 })
103 const data: PeerTubePluginIndex[] = res.body.data
47 104
48 it('Should search available plugins', async function () { 105 const p = data.find(p => p.npmName === 'peertube-theme-background-red')
49 // Search with filter (plugin and theme) 106 expect(p).to.be.undefined
50 // Add pagination 107 }
51 // Add sort
52 // Add peertube engine
53 }) 108 })
54 109
55 it('Should have an empty global css', async function () { 110 it('Should have an empty global css', async function () {
56 // get /global.css 111 const res = await getPluginsCSS(server.url)
112
113 expect(res.text).to.be.empty
57 }) 114 })
58 115
59 it('Should install a plugin and a theme', async function () { 116 it('Should install a plugin and a theme', async function () {
117 this.timeout(30000)
118
119 await installPlugin({
120 url: server.url,
121 accessToken: server.accessToken,
122 npmName: 'peertube-plugin-hello-world'
123 })
60 124
125 await installPlugin({
126 url: server.url,
127 accessToken: server.accessToken,
128 npmName: 'peertube-theme-background-red'
129 })
61 }) 130 })
62 131
63 it('Should have the correct global css', async function () { 132 it('Should have the correct global css', async function () {
64 // get /global.css 133 const res = await getPluginsCSS(server.url)
134
135 expect(res.text).to.contain('--mainBackgroundColor')
65 }) 136 })
66 137
67 it('Should have the plugin loaded in the configuration', async function () { 138 it('Should have the plugin loaded in the configuration', async function () {
68 // Check registered themes/plugins 139 const res = await getConfig(server.url)
140 const config: ServerConfig = res.body
141
142 const theme = config.theme.registered.find(r => r.name === 'background-red')
143 expect(theme).to.not.be.undefined
144
145 const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
146 expect(plugin).to.not.be.undefined
69 }) 147 })
70 148
71 it('Should update the default theme in the configuration', async function () { 149 it('Should update the default theme in the configuration', async function () {
72 // Update config 150 await updateCustomSubConfig(server.url, server.accessToken, { theme: { default: 'background-red' } })
151
152 const res = await getConfig(server.url)
153 const config: ServerConfig = res.body
154
155 expect(config.theme.default).to.equal('background-red')
73 }) 156 })
74 157
75 it('Should list plugins and themes', async function () { 158 it('Should update my default theme', async function () {
76 // List without filter 159 await updateMyUser({
77 // List with filter (theme/plugin) 160 url: server.url,
78 // List with pagination 161 accessToken: server.accessToken,
79 // List with sort 162 theme: 'background-red'
163 })
164
165 const res = await getMyUserInformation(server.url, server.accessToken)
166 expect((res.body as User).theme).to.equal('background-red')
80 }) 167 })
81 168
82 it('Should get a plugin and a theme', async function () { 169 it('Should list plugins and themes', async function () {
83 // Get plugin 170 {
84 // Get theme 171 const res = await listPlugins({
172 url: server.url,
173 accessToken: server.accessToken,
174 count: 1,
175 start: 0,
176 pluginType: PluginType.THEME
177 })
178 const data: PeerTubePlugin[] = res.body.data
179
180 expect(res.body.total).to.be.at.least(1)
181 expect(data).to.have.lengthOf(1)
182 expect(data[0].name).to.equal('background-red')
183 }
184
185 {
186 const res = await listPlugins({
187 url: server.url,
188 accessToken: server.accessToken,
189 count: 2,
190 start: 0,
191 sort: 'name'
192 })
193 const data: PeerTubePlugin[] = res.body.data
194
195 expect(data[0].name).to.equal('background-red')
196 expect(data[1].name).to.equal('hello-world')
197 }
198
199 {
200 const res = await listPlugins({
201 url: server.url,
202 accessToken: server.accessToken,
203 count: 2,
204 start: 1,
205 sort: 'name'
206 })
207 const data: PeerTubePlugin[] = res.body.data
208
209 expect(data[0].name).to.equal('hello-world')
210 }
85 }) 211 })
86 212
87 it('Should get registered settings', async function () { 213 it('Should get registered settings', async function () {
88 // Get plugin 214 const res = await getPluginRegisteredSettings({
215 url: server.url,
216 accessToken: server.accessToken,
217 npmName: 'peertube-plugin-hello-world'
218 })
219
220 const settings = (res.body as RegisteredSettings).settings
221
222 expect(settings).to.have.length.at.least(1)
223
224 const adminNameSettings = settings.find(s => s.name === 'admin-name')
225 expect(adminNameSettings).to.not.be.undefined
89 }) 226 })
90 227
91 it('Should update the settings', async function () { 228 it('Should update the settings', async function () {
92 // Update /settings 229 const settings = {
230 'admin-name': 'Cid'
231 }
232
233 await updatePluginSettings({
234 url: server.url,
235 accessToken: server.accessToken,
236 npmName: 'peertube-plugin-hello-world',
237 settings
238 })
239 })
240
241 it('Should get a plugin and a theme', async function () {
242 {
243 const res = await getPlugin({
244 url: server.url,
245 accessToken: server.accessToken,
246 npmName: 'peertube-plugin-hello-world'
247 })
248
249 const plugin: PeerTubePlugin = res.body
250
251 expect(plugin.type).to.equal(PluginType.PLUGIN)
252 expect(plugin.name).to.equal('hello-world')
253 expect(plugin.description).to.exist
254 expect(plugin.homepage).to.exist
255 expect(plugin.uninstalled).to.be.false
256 expect(plugin.enabled).to.be.true
257 expect(plugin.description).to.exist
258 expect(plugin.version).to.exist
259 expect(plugin.peertubeEngine).to.exist
260 expect(plugin.createdAt).to.exist
261
262 expect(plugin.settings).to.not.be.undefined
263 expect(plugin.settings['admin-name']).to.equal('Cid')
264 }
265
266 {
267 const res = await getPlugin({
268 url: server.url,
269 accessToken: server.accessToken,
270 npmName: 'peertube-theme-background-red'
271 })
272
273 const plugin: PeerTubePlugin = res.body
93 274
94 // get /plugin 275 expect(plugin.type).to.equal(PluginType.THEME)
276 expect(plugin.name).to.equal('background-red')
277 expect(plugin.description).to.exist
278 expect(plugin.homepage).to.exist
279 expect(plugin.uninstalled).to.be.false
280 expect(plugin.enabled).to.be.true
281 expect(plugin.description).to.exist
282 expect(plugin.version).to.exist
283 expect(plugin.peertubeEngine).to.exist
284 expect(plugin.createdAt).to.exist
285
286 expect(plugin.settings).to.be.null
287 }
95 }) 288 })
96 289
97 it('Should update the plugin and the theme', async function () { 290 it('Should update the plugin and the theme', async function () {
98 // update BDD -> 0.0.1 291 this.timeout(30000)
99 // update package.json (theme + plugin) 292
100 // list to check versions 293 // Wait the scheduler that get the latest plugins versions
101 // update plugin + theme 294 await wait(6000)
102 // list to check they have been updated 295
103 // check package.json are upgraded too 296 // Fake update our plugin version
297 await setPluginVersion(server.internalServerNumber, 'hello-world', '0.0.1')
298
299 // Fake update package.json
300 const packageJSON: PluginPackageJson = await getPluginPackageJSON(server, 'peertube-plugin-hello-world')
301 const oldVersion = packageJSON.version
302
303 packageJSON.version = '0.0.1'
304 await updatePluginPackageJSON(server, 'peertube-plugin-hello-world', packageJSON)
305
306 // Restart the server to take into account this change
307 killallServers([ server ])
308 await reRunServer(server)
309
310 {
311 const res = await listPlugins({
312 url: server.url,
313 accessToken: server.accessToken,
314 pluginType: PluginType.PLUGIN
315 })
316
317 const plugin: PeerTubePlugin = res.body.data[0]
318
319 expect(plugin.version).to.equal('0.0.1')
320 expect(plugin.latestVersion).to.exist
321 expect(plugin.latestVersion).to.not.equal('0.0.1')
322 }
323
324 {
325 await updatePlugin({
326 url: server.url,
327 accessToken: server.accessToken,
328 npmName: 'peertube-plugin-hello-world'
329 })
330
331 const res = await listPlugins({
332 url: server.url,
333 accessToken: server.accessToken,
334 pluginType: PluginType.PLUGIN
335 })
336
337 const plugin: PeerTubePlugin = res.body.data[0]
338
339 expect(plugin.version).to.equal(oldVersion)
340
341 const updatedPackageJSON: PluginPackageJson = await getPluginPackageJSON(server, 'peertube-plugin-hello-world')
342 expect(updatedPackageJSON.version).to.equal(oldVersion)
343 }
104 }) 344 })
105 345
106 it('Should uninstall the plugin', async function () { 346 it('Should uninstall the plugin', async function () {
107 // uninstall 347 await uninstallPlugin({
108 // list 348 url: server.url,
349 accessToken: server.accessToken,
350 npmName: 'peertube-plugin-hello-world'
351 })
352
353 const res = await listPlugins({
354 url: server.url,
355 accessToken: server.accessToken,
356 pluginType: PluginType.PLUGIN
357 })
358
359 expect(res.body.total).to.equal(0)
360 expect(res.body.data).to.have.lengthOf(0)
109 }) 361 })
110 362
111 it('Should have an empty global css', async function () { 363 it('Should have an empty global css', async function () {
112 // get /global.css 364 const res = await getPluginsCSS(server.url)
365
366 expect(res.text).to.be.empty
113 }) 367 })
114 368
115 it('Should list uninstalled plugins', async function () { 369 it('Should list uninstalled plugins', async function () {
116 // { uninstalled: true } 370 const res = await listPlugins({
371 url: server.url,
372 accessToken: server.accessToken,
373 pluginType: PluginType.PLUGIN,
374 uninstalled: true
375 })
376
377 expect(res.body.total).to.equal(1)
378 expect(res.body.data).to.have.lengthOf(1)
379
380 const plugin: PeerTubePlugin = res.body.data[0]
381 expect(plugin.name).to.equal('hello-world')
382 expect(plugin.enabled).to.be.false
383 expect(plugin.uninstalled).to.be.true
117 }) 384 })
118 385
119 it('Should uninstall the theme', async function () { 386 it('Should uninstall the theme', async function () {
120 // Uninstall 387 await uninstallPlugin({
388 url: server.url,
389 accessToken: server.accessToken,
390 npmName: 'peertube-theme-background-red'
391 })
121 }) 392 })
122 393
123 it('Should have updated the configuration', async function () { 394 it('Should have updated the configuration', async function () {
124 // get /config (default theme + registered themes + registered plugins) 395 // get /config (default theme + registered themes + registered plugins)
396 const res = await getConfig(server.url)
397 const config: ServerConfig = res.body
398
399 expect(config.theme.default).to.equal('default')
400
401 const theme = config.theme.registered.find(r => r.name === 'background-red')
402 expect(theme).to.be.undefined
403
404 const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
405 expect(plugin).to.be.undefined
406 })
407
408 it('Should have updated the user theme', async function () {
409 const res = await getMyUserInformation(server.url, server.accessToken)
410 expect((res.body as User).theme).to.equal('instance-default')
125 }) 411 })
126 412
127 after(async function () { 413 after(async function () {
414 await closeAllSequelize([ server ])
128 await cleanupTests([ server ]) 415 await cleanupTests([ server ])
129 }) 416 })
130}) 417})
diff --git a/server/tests/plugins/action-hooks.ts b/server/tests/plugins/action-hooks.ts
index 8abab98c2..93dc57d09 100644
--- a/server/tests/plugins/action-hooks.ts
+++ b/server/tests/plugins/action-hooks.ts
@@ -7,7 +7,7 @@ import { setAccessTokensToServers } from '../../../shared/extra-utils'
7 7
8const expect = chai.expect 8const expect = chai.expect
9 9
10describe('Test plugin filter hooks', function () { 10describe('Test plugin action hooks', function () {
11 let server: ServerInfo 11 let server: ServerInfo
12 12
13 before(async function () { 13 before(async function () {
@@ -18,7 +18,7 @@ describe('Test plugin filter hooks', function () {
18 }) 18 })
19 19
20 it('Should execute ', async function () { 20 it('Should execute ', async function () {
21 21 // empty
22 }) 22 })
23 23
24 after(async function () { 24 after(async function () {
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts
index 8abab98c2..500728712 100644
--- a/server/tests/plugins/filter-hooks.ts
+++ b/server/tests/plugins/filter-hooks.ts
@@ -18,7 +18,7 @@ describe('Test plugin filter hooks', function () {
18 }) 18 })
19 19
20 it('Should execute ', async function () { 20 it('Should execute ', async function () {
21 21 // empty
22 }) 22 })
23 23
24 after(async function () { 24 after(async function () {
diff --git a/server/tools/peertube-plugins.ts b/server/tools/peertube-plugins.ts
index 10cff7dd7..20254b3b4 100644
--- a/server/tools/peertube-plugins.ts
+++ b/server/tools/peertube-plugins.ts
@@ -65,9 +65,9 @@ async function pluginsListCLI () {
65 const { url, username, password } = await getServerCredentials(program) 65 const { url, username, password } = await getServerCredentials(program)
66 const accessToken = await getAdminTokenOrDie(url, username, password) 66 const accessToken = await getAdminTokenOrDie(url, username, password)
67 67
68 let type: PluginType 68 let pluginType: PluginType
69 if (program['onlyThemes']) type = PluginType.THEME 69 if (program['onlyThemes']) pluginType = PluginType.THEME
70 if (program['onlyPlugins']) type = PluginType.PLUGIN 70 if (program['onlyPlugins']) pluginType = PluginType.PLUGIN
71 71
72 const res = await listPlugins({ 72 const res = await listPlugins({
73 url, 73 url,
@@ -75,7 +75,7 @@ async function pluginsListCLI () {
75 start: 0, 75 start: 0,
76 count: 100, 76 count: 100,
77 sort: 'name', 77 sort: 'name',
78 type 78 pluginType
79 }) 79 })
80 const plugins: PeerTubePlugin[] = res.body.data 80 const plugins: PeerTubePlugin[] = res.body.data
81 81