1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import { HttpStatusCode } from '@shared/core-utils'
6 checkBadCountPagination,
7 checkBadSortPagination,
8 checkBadStartPagination,
16 setAccessTokensToServers
17 } from '@shared/extra-utils'
18 import { PeerTubePlugin, PluginType } from '@shared/models'
20 describe('Test server plugins API validators', function () {
21 let server: ServerInfo
22 let userAccessToken = null
24 const npmPlugin = 'peertube-plugin-hello-world'
25 const pluginName = 'hello-world'
26 let npmVersion: string
28 const themePlugin = 'peertube-theme-background-red'
29 const themeName = 'background-red'
30 let themeVersion: string
32 // ---------------------------------------------------------------
34 before(async function () {
37 server = await flushAndRunServer(1)
39 await setAccessTokensToServers([ server ])
46 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
47 userAccessToken = await server.loginCommand.getAccessToken(user)
50 const res = await server.pluginsCommand.install({ npmName: npmPlugin })
51 const plugin = res.body as PeerTubePlugin
52 npmVersion = plugin.version
56 const res = await server.pluginsCommand.install({ npmName: themePlugin })
57 const plugin = res.body as PeerTubePlugin
58 themeVersion = plugin.version
62 describe('With static plugin routes', function () {
63 it('Should fail with an unknown plugin name/plugin version', async function () {
65 '/plugins/' + pluginName + '/0.0.1/auth/fake-auth',
66 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png',
67 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js',
68 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png',
69 '/themes/' + themeName + '/0.0.1/client-scripts/client/video-watch-client-plugin.js',
70 '/themes/' + themeName + '/0.0.1/css/assets/style1.css'
73 for (const p of paths) {
74 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
78 it('Should fail when requesting a plugin in the theme path', async function () {
79 await makeGetRequest({
81 path: '/themes/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
82 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
86 it('Should fail with invalid versions', async function () {
88 '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth',
89 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png',
90 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js',
91 '/themes/' + themeName + '/1/static/images/chocobo.png',
92 '/themes/' + themeName + '/0.0.1000a/client-scripts/client/video-watch-client-plugin.js',
93 '/themes/' + themeName + '/0.a.1/css/assets/style1.css'
96 for (const p of paths) {
97 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 })
101 it('Should fail with invalid paths', async function () {
103 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/../chocobo.png',
104 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/../client/common-client-plugin.js',
105 '/themes/' + themeName + '/' + themeVersion + '/static/../images/chocobo.png',
106 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js/..',
107 '/themes/' + themeName + '/' + themeVersion + '/css/../assets/style1.css'
110 for (const p of paths) {
111 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 })
115 it('Should fail with an unknown auth name', async function () {
116 const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth'
118 await makeGetRequest({ url: server.url, path, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
121 it('Should fail with an unknown static file', async function () {
123 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png',
124 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/fake.js',
125 '/themes/' + themeName + '/' + themeVersion + '/static/fake/chocobo.png',
126 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/fake.js'
129 for (const p of paths) {
130 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
134 it('Should fail with an unknown CSS file', async function () {
135 await makeGetRequest({
137 path: '/themes/' + themeName + '/' + themeVersion + '/css/assets/fake.css',
138 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
142 it('Should succeed with the correct parameters', async function () {
144 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
145 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/common-client-plugin.js',
146 '/themes/' + themeName + '/' + themeVersion + '/static/images/chocobo.png',
147 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js',
148 '/themes/' + themeName + '/' + themeVersion + '/css/assets/style1.css'
151 for (const p of paths) {
152 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.OK_200 })
155 const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth'
156 await makeGetRequest({ url: server.url, path: authPath, statusCodeExpected: HttpStatusCode.FOUND_302 })
160 describe('When listing available plugins/themes', function () {
161 const path = '/api/v1/plugins/available'
163 search: 'super search',
164 pluginType: PluginType.PLUGIN,
165 currentPeerTubeEngine: '1.2.3'
168 it('Should fail with an invalid token', async function () {
169 await makeGetRequest({
174 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
178 it('Should fail if the user is not an administrator', async function () {
179 await makeGetRequest({
182 token: userAccessToken,
184 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
188 it('Should fail with a bad start pagination', async function () {
189 await checkBadStartPagination(server.url, path, server.accessToken)
192 it('Should fail with a bad count pagination', async function () {
193 await checkBadCountPagination(server.url, path, server.accessToken)
196 it('Should fail with an incorrect sort', async function () {
197 await checkBadSortPagination(server.url, path, server.accessToken)
200 it('Should fail with an invalid plugin type', async function () {
201 const query = { ...baseQuery, pluginType: 5 }
203 await makeGetRequest({
206 token: server.accessToken,
211 it('Should fail with an invalid current peertube engine', async function () {
212 const query = { ...baseQuery, currentPeerTubeEngine: '1.0' }
214 await makeGetRequest({
217 token: server.accessToken,
222 it('Should success with the correct parameters', async function () {
223 await makeGetRequest({
226 token: server.accessToken,
228 statusCodeExpected: HttpStatusCode.OK_200
233 describe('When listing local plugins/themes', function () {
234 const path = '/api/v1/plugins'
236 pluginType: PluginType.THEME
239 it('Should fail with an invalid token', async function () {
240 await makeGetRequest({
245 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
249 it('Should fail if the user is not an administrator', async function () {
250 await makeGetRequest({
253 token: userAccessToken,
255 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
259 it('Should fail with a bad start pagination', async function () {
260 await checkBadStartPagination(server.url, path, server.accessToken)
263 it('Should fail with a bad count pagination', async function () {
264 await checkBadCountPagination(server.url, path, server.accessToken)
267 it('Should fail with an incorrect sort', async function () {
268 await checkBadSortPagination(server.url, path, server.accessToken)
271 it('Should fail with an invalid plugin type', async function () {
272 const query = { ...baseQuery, pluginType: 5 }
274 await makeGetRequest({
277 token: server.accessToken,
282 it('Should success with the correct parameters', async function () {
283 await makeGetRequest({
286 token: server.accessToken,
288 statusCodeExpected: HttpStatusCode.OK_200
293 describe('When getting a plugin or the registered settings or public settings', function () {
294 const path = '/api/v1/plugins/'
296 it('Should fail with an invalid token', async function () {
297 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
298 await makeGetRequest({
302 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
307 it('Should fail if the user is not an administrator', async function () {
308 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
309 await makeGetRequest({
312 token: userAccessToken,
313 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
318 it('Should fail with an invalid npm name', async function () {
319 for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) {
320 await makeGetRequest({
323 token: server.accessToken,
324 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
328 for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) {
329 await makeGetRequest({
332 token: server.accessToken,
333 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
338 it('Should fail with an unknown plugin', async function () {
339 for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) {
340 await makeGetRequest({
343 token: server.accessToken,
344 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
349 it('Should succeed with the correct parameters', async function () {
350 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) {
351 await makeGetRequest({
354 token: server.accessToken,
355 statusCodeExpected: HttpStatusCode.OK_200
361 describe('When updating plugin settings', function () {
362 const path = '/api/v1/plugins/'
363 const settings = { setting1: 'value1' }
365 it('Should fail with an invalid token', async function () {
366 await makePutBodyRequest({
368 path: path + npmPlugin + '/settings',
369 fields: { settings },
371 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
375 it('Should fail if the user is not an administrator', async function () {
376 await makePutBodyRequest({
378 path: path + npmPlugin + '/settings',
379 fields: { settings },
380 token: userAccessToken,
381 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
385 it('Should fail with an invalid npm name', async function () {
386 await makePutBodyRequest({
388 path: path + 'toto/settings',
389 fields: { settings },
390 token: server.accessToken,
391 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
394 await makePutBodyRequest({
396 path: path + 'peertube-plugin-TOTO/settings',
397 fields: { settings },
398 token: server.accessToken,
399 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
403 it('Should fail with an unknown plugin', async function () {
404 await makePutBodyRequest({
406 path: path + 'peertube-plugin-toto/settings',
407 fields: { settings },
408 token: server.accessToken,
409 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
413 it('Should succeed with the correct parameters', async function () {
414 await makePutBodyRequest({
416 path: path + npmPlugin + '/settings',
417 fields: { settings },
418 token: server.accessToken,
419 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
424 describe('When installing/updating/uninstalling a plugin', function () {
425 const path = '/api/v1/plugins/'
427 it('Should fail with an invalid token', async function () {
428 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
429 await makePostBodyRequest({
432 fields: { npmName: npmPlugin },
434 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
439 it('Should fail if the user is not an administrator', async function () {
440 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
441 await makePostBodyRequest({
444 fields: { npmName: npmPlugin },
445 token: userAccessToken,
446 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
451 it('Should fail with an invalid npm name', async function () {
452 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
453 await makePostBodyRequest({
456 fields: { npmName: 'toto' },
457 token: server.accessToken,
458 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
462 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
463 await makePostBodyRequest({
466 fields: { npmName: 'peertube-plugin-TOTO' },
467 token: server.accessToken,
468 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
473 it('Should succeed with the correct parameters', async function () {
477 { suffix: 'install', status: HttpStatusCode.OK_200 },
478 { suffix: 'update', status: HttpStatusCode.OK_200 },
479 { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 }
482 for (const obj of it) {
483 await makePostBodyRequest({
485 path: path + obj.suffix,
486 fields: { npmName: npmPlugin },
487 token: server.accessToken,
488 statusCodeExpected: obj.status
494 after(async function () {
495 await cleanupTests([ server ])