]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/server/plugins.ts
Merge branch 'release/4.3.0' into develop
[github/Chocobozzz/PeerTube.git] / server / tests / api / server / plugins.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
9b474844 2
86347717 3import { expect } from 'chai'
c795e196
C
4import { pathExists, remove } from 'fs-extra'
5import { join } from 'path'
c55e3d72
C
6import { testHelloWorldRegisteredSettings } from '@server/tests/shared'
7import { wait } from '@shared/core-utils'
8import { HttpStatusCode, PluginType } from '@shared/models'
9b474844
C
9import {
10 cleanupTests,
254d3579 11 createSingleServer,
a1587156 12 killallServers,
c795e196 13 makeGetRequest,
254d3579 14 PeerTubeServer,
4c7e60bc 15 PluginsCommand,
c55e3d72 16 setAccessTokensToServers
bf54587a 17} from '@shared/server-commands'
9b474844 18
9b474844 19describe('Test plugins', function () {
254d3579 20 let server: PeerTubeServer = null
ae2abfd3 21 let command: PluginsCommand
9b474844
C
22
23 before(async function () {
24 this.timeout(30000)
25
09071200
C
26 const configOverride = {
27 plugins: {
28 index: { check_latest_versions_interval: '5 seconds' }
29 }
30 }
254d3579 31 server = await createSingleServer(1, configOverride)
9b474844 32 await setAccessTokensToServers([ server ])
a5461888 33
89d241a7 34 command = server.plugins
09071200
C
35 })
36
37 it('Should list and search available plugins and themes', async function () {
38 this.timeout(30000)
9b474844
C
39
40 {
ae2abfd3 41 const body = await command.listAvailable({
09071200
C
42 count: 1,
43 start: 0,
44 pluginType: PluginType.THEME,
45 search: 'background-red'
46 })
47
ae2abfd3
C
48 expect(body.total).to.be.at.least(1)
49 expect(body.data).to.have.lengthOf(1)
9b474844
C
50 }
51
52 {
ae2abfd3 53 const body1 = await command.listAvailable({
09071200
C
54 count: 2,
55 start: 0,
56 sort: 'npmName'
57 })
ae2abfd3 58 expect(body1.total).to.be.at.least(2)
09071200 59
ae2abfd3 60 const data1 = body1.data
09071200
C
61 expect(data1).to.have.lengthOf(2)
62
ae2abfd3 63 const body2 = await command.listAvailable({
09071200
C
64 count: 2,
65 start: 0,
66 sort: '-npmName'
67 })
ae2abfd3 68 expect(body2.total).to.be.at.least(2)
09071200 69
ae2abfd3 70 const data2 = body2.data
09071200
C
71 expect(data2).to.have.lengthOf(2)
72
a1587156 73 expect(data1[0].npmName).to.not.equal(data2[0].npmName)
9b474844 74 }
9b474844 75
09071200 76 {
ae2abfd3 77 const body = await command.listAvailable({
09071200
C
78 count: 10,
79 start: 0,
80 pluginType: PluginType.THEME,
81 search: 'background-red',
82 currentPeerTubeEngine: '1.0.0'
83 })
9b474844 84
ae2abfd3 85 const p = body.data.find(p => p.npmName === 'peertube-theme-background-red')
09071200
C
86 expect(p).to.be.undefined
87 }
9b474844
C
88 })
89
9b474844 90 it('Should install a plugin and a theme', async function () {
09071200
C
91 this.timeout(30000)
92
ae2abfd3
C
93 await command.install({ npmName: 'peertube-plugin-hello-world' })
94 await command.install({ npmName: 'peertube-theme-background-red' })
9b474844
C
95 })
96
9b474844 97 it('Should have the plugin loaded in the configuration', async function () {
2769876f
C
98 for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
99 const theme = config.theme.registered.find(r => r.name === 'background-red')
100 expect(theme).to.not.be.undefined
101 expect(theme.npmName).to.equal('peertube-theme-background-red')
102
103 const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
104 expect(plugin).to.not.be.undefined
105 expect(plugin.npmName).to.equal('peertube-plugin-hello-world')
106 }
9b474844
C
107 })
108
109 it('Should update the default theme in the configuration', async function () {
89d241a7 110 await server.config.updateCustomSubConfig({
65e6e260
C
111 newConfig: {
112 theme: { default: 'background-red' }
113 }
114 })
09071200 115
2769876f
C
116 for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
117 expect(config.theme.default).to.equal('background-red')
118 }
9b474844
C
119 })
120
09071200 121 it('Should update my default theme', async function () {
89d241a7 122 await server.users.updateMe({ theme: 'background-red' })
09071200 123
89d241a7 124 const user = await server.users.getMyInfo()
7926c5f9 125 expect(user.theme).to.equal('background-red')
9b474844
C
126 })
127
09071200
C
128 it('Should list plugins and themes', async function () {
129 {
ae2abfd3 130 const body = await command.list({
09071200
C
131 count: 1,
132 start: 0,
133 pluginType: PluginType.THEME
134 })
ae2abfd3 135 expect(body.total).to.be.at.least(1)
09071200 136
ae2abfd3 137 const data = body.data
09071200
C
138 expect(data).to.have.lengthOf(1)
139 expect(data[0].name).to.equal('background-red')
140 }
141
142 {
dd0ebb71 143 const { data } = await command.list({
09071200
C
144 count: 2,
145 start: 0,
146 sort: 'name'
147 })
09071200
C
148
149 expect(data[0].name).to.equal('background-red')
150 expect(data[1].name).to.equal('hello-world')
151 }
152
153 {
ae2abfd3 154 const body = await command.list({
09071200
C
155 count: 2,
156 start: 1,
157 sort: 'name'
158 })
09071200 159
ae2abfd3 160 expect(body.data[0].name).to.equal('hello-world')
09071200 161 }
9b474844
C
162 })
163
164 it('Should get registered settings', async function () {
353f8bc0 165 await testHelloWorldRegisteredSettings(server)
9b474844
C
166 })
167
ba211e73 168 it('Should get public settings', async function () {
ae2abfd3
C
169 const body = await command.getPublicSettings({ npmName: 'peertube-plugin-hello-world' })
170 const publicSettings = body.publicSettings
ba211e73
C
171
172 expect(Object.keys(publicSettings)).to.have.lengthOf(1)
173 expect(Object.keys(publicSettings)).to.deep.equal([ 'user-name' ])
174 expect(publicSettings['user-name']).to.be.null
175 })
176
9b474844 177 it('Should update the settings', async function () {
09071200
C
178 const settings = {
179 'admin-name': 'Cid'
180 }
181
ae2abfd3 182 await command.updateSettings({
09071200
C
183 npmName: 'peertube-plugin-hello-world',
184 settings
185 })
186 })
187
a5896799
C
188 it('Should have watched settings changes', async function () {
189 this.timeout(10000)
190
89d241a7 191 await server.servers.waitUntilLog('Settings changed!')
a5896799
C
192 })
193
09071200
C
194 it('Should get a plugin and a theme', async function () {
195 {
ae2abfd3 196 const plugin = await command.get({ npmName: 'peertube-plugin-hello-world' })
09071200
C
197
198 expect(plugin.type).to.equal(PluginType.PLUGIN)
199 expect(plugin.name).to.equal('hello-world')
200 expect(plugin.description).to.exist
201 expect(plugin.homepage).to.exist
202 expect(plugin.uninstalled).to.be.false
203 expect(plugin.enabled).to.be.true
204 expect(plugin.description).to.exist
205 expect(plugin.version).to.exist
206 expect(plugin.peertubeEngine).to.exist
207 expect(plugin.createdAt).to.exist
208
209 expect(plugin.settings).to.not.be.undefined
210 expect(plugin.settings['admin-name']).to.equal('Cid')
211 }
212
213 {
ae2abfd3 214 const plugin = await command.get({ npmName: 'peertube-theme-background-red' })
9b474844 215
09071200
C
216 expect(plugin.type).to.equal(PluginType.THEME)
217 expect(plugin.name).to.equal('background-red')
218 expect(plugin.description).to.exist
219 expect(plugin.homepage).to.exist
220 expect(plugin.uninstalled).to.be.false
221 expect(plugin.enabled).to.be.true
222 expect(plugin.description).to.exist
223 expect(plugin.version).to.exist
224 expect(plugin.peertubeEngine).to.exist
225 expect(plugin.createdAt).to.exist
226
227 expect(plugin.settings).to.be.null
228 }
9b474844
C
229 })
230
231 it('Should update the plugin and the theme', async function () {
2769876f 232 this.timeout(180000)
09071200
C
233
234 // Wait the scheduler that get the latest plugins versions
235 await wait(6000)
236
2769876f
C
237 async function testUpdate (type: 'plugin' | 'theme', name: string) {
238 // Fake update our plugin version
239 await server.sql.setPluginVersion(name, '0.0.1')
09071200 240
2769876f
C
241 // Fake update package.json
242 const packageJSON = await command.getPackageJSON(`peertube-${type}-${name}`)
243 const oldVersion = packageJSON.version
09071200 244
2769876f
C
245 packageJSON.version = '0.0.1'
246 await command.updatePackageJSON(`peertube-${type}-${name}`, packageJSON)
09071200 247
2769876f
C
248 // Restart the server to take into account this change
249 await killallServers([ server ])
250 await server.run()
09071200 251
2769876f
C
252 const checkConfig = async (version: string) => {
253 for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
254 expect(config[type].registered.find(r => r.name === name).version).to.equal(version)
255 }
256 }
09071200 257
2769876f
C
258 const getPluginFromAPI = async () => {
259 const body = await command.list({ pluginType: type === 'plugin' ? PluginType.PLUGIN : PluginType.THEME })
09071200 260
2769876f
C
261 return body.data.find(p => p.name === name)
262 }
09071200 263
2769876f
C
264 {
265 const plugin = await getPluginFromAPI()
266 expect(plugin.version).to.equal('0.0.1')
267 expect(plugin.latestVersion).to.exist
268 expect(plugin.latestVersion).to.not.equal('0.0.1')
269
270 await checkConfig('0.0.1')
271 }
272
273 {
274 await command.update({ npmName: `peertube-${type}-${name}` })
09071200 275
2769876f
C
276 const plugin = await getPluginFromAPI()
277 expect(plugin.version).to.equal(oldVersion)
09071200 278
2769876f
C
279 const updatedPackageJSON = await command.getPackageJSON(`peertube-${type}-${name}`)
280 expect(updatedPackageJSON.version).to.equal(oldVersion)
281
282 await checkConfig(oldVersion)
283 }
09071200 284 }
2769876f
C
285
286 await testUpdate('theme', 'background-red')
287 await testUpdate('plugin', 'hello-world')
9b474844
C
288 })
289
290 it('Should uninstall the plugin', async function () {
ae2abfd3 291 await command.uninstall({ npmName: 'peertube-plugin-hello-world' })
09071200 292
ae2abfd3
C
293 const body = await command.list({ pluginType: PluginType.PLUGIN })
294 expect(body.total).to.equal(0)
295 expect(body.data).to.have.lengthOf(0)
9b474844
C
296 })
297
9b474844 298 it('Should list uninstalled plugins', async function () {
ae2abfd3
C
299 const body = await command.list({ pluginType: PluginType.PLUGIN, uninstalled: true })
300 expect(body.total).to.equal(1)
301 expect(body.data).to.have.lengthOf(1)
09071200 302
ae2abfd3 303 const plugin = body.data[0]
09071200
C
304 expect(plugin.name).to.equal('hello-world')
305 expect(plugin.enabled).to.be.false
306 expect(plugin.uninstalled).to.be.true
9b474844
C
307 })
308
309 it('Should uninstall the theme', async function () {
ae2abfd3 310 await command.uninstall({ npmName: 'peertube-theme-background-red' })
9b474844
C
311 })
312
313 it('Should have updated the configuration', async function () {
2769876f
C
314 for (const config of [ await server.config.getConfig(), await server.config.getIndexHTMLConfig() ]) {
315 expect(config.theme.default).to.equal('default')
09071200 316
2769876f
C
317 const theme = config.theme.registered.find(r => r.name === 'background-red')
318 expect(theme).to.be.undefined
09071200 319
2769876f
C
320 const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
321 expect(plugin).to.be.undefined
322 }
09071200
C
323 })
324
325 it('Should have updated the user theme', async function () {
89d241a7 326 const user = await server.users.getMyInfo()
7926c5f9 327 expect(user.theme).to.equal('instance-default')
9b474844
C
328 })
329
9c2e051c
C
330 it('Should not install a broken plugin', async function () {
331 this.timeout(60000)
332
333 async function check () {
ae2abfd3
C
334 const body = await command.list({ pluginType: PluginType.PLUGIN })
335 const plugins = body.data
9c2e051c
C
336 expect(plugins.find(p => p.name === 'test-broken')).to.not.exist
337 }
338
ae2abfd3
C
339 await command.install({
340 path: PluginsCommand.getPluginTestPath('-broken'),
9c2e051c
C
341 expectedStatus: HttpStatusCode.BAD_REQUEST_400
342 })
343
344 await check()
345
9293139f 346 await killallServers([ server ])
254d3579 347 await server.run()
9c2e051c
C
348
349 await check()
350 })
351
c795e196 352 it('Should rebuild native modules on Node ABI change', async function () {
c543e414 353 this.timeout(60000)
94278907
C
354
355 const removeNativeModule = async () => {
356 await remove(join(baseNativeModule, 'build'))
357 await remove(join(baseNativeModule, 'prebuilds'))
358 }
359
c795e196
C
360 await command.install({ path: PluginsCommand.getPluginTestPath('-native') })
361
362 await makeGetRequest({
363 url: server.url,
364 path: '/plugins/test-native/router',
365 expectedStatus: HttpStatusCode.NO_CONTENT_204
366 })
367
368 const query = `UPDATE "application" SET "nodeABIVersion" = 1`
369 await server.sql.updateQuery(query)
370
371 const baseNativeModule = server.servers.buildDirectory(join('plugins', 'node_modules', 'a-native-example'))
c795e196 372
94278907 373 await removeNativeModule()
c795e196
C
374 await server.kill()
375 await server.run()
376
c543e414
C
377 await wait(3000)
378
94278907
C
379 expect(await pathExists(join(baseNativeModule, 'build'))).to.be.true
380 expect(await pathExists(join(baseNativeModule, 'prebuilds'))).to.be.true
c795e196
C
381
382 await makeGetRequest({
383 url: server.url,
384 path: '/plugins/test-native/router',
385 expectedStatus: HttpStatusCode.NO_CONTENT_204
386 })
94278907
C
387
388 await removeNativeModule()
389
390 await server.kill()
391 await server.run()
392
393 expect(await pathExists(join(baseNativeModule, 'build'))).to.be.false
394 expect(await pathExists(join(baseNativeModule, 'prebuilds'))).to.be.false
395
396 await makeGetRequest({
397 url: server.url,
398 path: '/plugins/test-native/router',
399 expectedStatus: HttpStatusCode.NOT_FOUND_404
400 })
c795e196
C
401 })
402
9b474844
C
403 after(async function () {
404 await cleanupTests([ server ])
405 })
406})