1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
6 checkBadCountPagination,
7 checkBadSortPagination,
8 checkBadStartPagination,
14 makeGetRequest, makePostBodyRequest, makePutBodyRequest,
16 setAccessTokensToServers,
18 } from '../../../../shared/extra-utils'
19 import { PluginType } from '../../../../shared/models/plugins/plugin.type'
20 import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugin.model'
21 import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
23 describe('Test server plugins API validators', function () {
24 let server: ServerInfo
25 let userAccessToken = null
27 const npmPlugin = 'peertube-plugin-hello-world'
28 const pluginName = 'hello-world'
29 let npmVersion: string
31 const themePlugin = 'peertube-theme-background-red'
32 const themeName = 'background-red'
33 let themeVersion: string
35 // ---------------------------------------------------------------
37 before(async function () {
40 server = await flushAndRunServer(1)
42 await setAccessTokensToServers([ server ])
49 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
50 userAccessToken = await userLogin(server, user)
53 const res = await installPlugin({ url: server.url, accessToken: server.accessToken, npmName: npmPlugin })
54 const plugin = res.body as PeerTubePlugin
55 npmVersion = plugin.version
59 const res = await installPlugin({ url: server.url, accessToken: server.accessToken, npmName: themePlugin })
60 const plugin = res.body as PeerTubePlugin
61 themeVersion = plugin.version
65 describe('With static plugin routes', function () {
66 it('Should fail with an unknown plugin name/plugin version', async function () {
68 '/plugins/' + pluginName + '/0.0.1/auth/fake-auth',
69 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png',
70 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js',
71 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png',
72 '/themes/' + themeName + '/0.0.1/client-scripts/client/video-watch-client-plugin.js',
73 '/themes/' + themeName + '/0.0.1/css/assets/style1.css'
76 for (const p of paths) {
77 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
81 it('Should fail when requesting a plugin in the theme path', async function () {
82 await makeGetRequest({
84 path: '/themes/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
85 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
89 it('Should fail with invalid versions', async function () {
91 '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth',
92 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png',
93 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js',
94 '/themes/' + themeName + '/1/static/images/chocobo.png',
95 '/themes/' + themeName + '/0.0.1000a/client-scripts/client/video-watch-client-plugin.js',
96 '/themes/' + themeName + '/0.a.1/css/assets/style1.css'
99 for (const p of paths) {
100 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 })
104 it('Should fail with invalid paths', async function () {
106 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/../chocobo.png',
107 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/../client/common-client-plugin.js',
108 '/themes/' + themeName + '/' + themeVersion + '/static/../images/chocobo.png',
109 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js/..',
110 '/themes/' + themeName + '/' + themeVersion + '/css/../assets/style1.css'
113 for (const p of paths) {
114 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 })
118 it('Should fail with an unknown auth name', async function () {
119 const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth'
121 await makeGetRequest({ url: server.url, path, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
124 it('Should fail with an unknown static file', async function () {
126 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png',
127 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/fake.js',
128 '/themes/' + themeName + '/' + themeVersion + '/static/fake/chocobo.png',
129 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/fake.js'
132 for (const p of paths) {
133 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
137 it('Should fail with an unknown CSS file', async function () {
138 await makeGetRequest({
140 path: '/themes/' + themeName + '/' + themeVersion + '/css/assets/fake.css',
141 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
145 it('Should succeed with the correct parameters', async function () {
147 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
148 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/common-client-plugin.js',
149 '/themes/' + themeName + '/' + themeVersion + '/static/images/chocobo.png',
150 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js',
151 '/themes/' + themeName + '/' + themeVersion + '/css/assets/style1.css'
154 for (const p of paths) {
155 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.OK_200 })
158 const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth'
159 await makeGetRequest({ url: server.url, path: authPath, statusCodeExpected: HttpStatusCode.FOUND_302 })
163 describe('When listing available plugins/themes', function () {
164 const path = '/api/v1/plugins/available'
166 search: 'super search',
167 pluginType: PluginType.PLUGIN,
168 currentPeerTubeEngine: '1.2.3'
171 it('Should fail with an invalid token', async function () {
172 await makeGetRequest({
177 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
181 it('Should fail if the user is not an administrator', async function () {
182 await makeGetRequest({
185 token: userAccessToken,
187 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
191 it('Should fail with a bad start pagination', async function () {
192 await checkBadStartPagination(server.url, path, server.accessToken)
195 it('Should fail with a bad count pagination', async function () {
196 await checkBadCountPagination(server.url, path, server.accessToken)
199 it('Should fail with an incorrect sort', async function () {
200 await checkBadSortPagination(server.url, path, server.accessToken)
203 it('Should fail with an invalid plugin type', async function () {
204 const query = immutableAssign(baseQuery, { pluginType: 5 })
206 await makeGetRequest({
209 token: server.accessToken,
214 it('Should fail with an invalid current peertube engine', async function () {
215 const query = immutableAssign(baseQuery, { currentPeerTubeEngine: '1.0' })
217 await makeGetRequest({
220 token: server.accessToken,
225 it('Should success with the correct parameters', async function () {
226 await makeGetRequest({
229 token: server.accessToken,
231 statusCodeExpected: HttpStatusCode.OK_200
236 describe('When listing local plugins/themes', function () {
237 const path = '/api/v1/plugins'
239 pluginType: PluginType.THEME
242 it('Should fail with an invalid token', async function () {
243 await makeGetRequest({
248 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
252 it('Should fail if the user is not an administrator', async function () {
253 await makeGetRequest({
256 token: userAccessToken,
258 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
262 it('Should fail with a bad start pagination', async function () {
263 await checkBadStartPagination(server.url, path, server.accessToken)
266 it('Should fail with a bad count pagination', async function () {
267 await checkBadCountPagination(server.url, path, server.accessToken)
270 it('Should fail with an incorrect sort', async function () {
271 await checkBadSortPagination(server.url, path, server.accessToken)
274 it('Should fail with an invalid plugin type', async function () {
275 const query = immutableAssign(baseQuery, { pluginType: 5 })
277 await makeGetRequest({
280 token: server.accessToken,
285 it('Should success with the correct parameters', async function () {
286 await makeGetRequest({
289 token: server.accessToken,
291 statusCodeExpected: HttpStatusCode.OK_200
296 describe('When getting a plugin or the registered settings or public settings', function () {
297 const path = '/api/v1/plugins/'
299 it('Should fail with an invalid token', async function () {
300 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
301 await makeGetRequest({
305 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
310 it('Should fail if the user is not an administrator', async function () {
311 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
312 await makeGetRequest({
315 token: userAccessToken,
316 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
321 it('Should fail with an invalid npm name', async function () {
322 for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) {
323 await makeGetRequest({
326 token: server.accessToken,
327 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
331 for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) {
332 await makeGetRequest({
335 token: server.accessToken,
336 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
341 it('Should fail with an unknown plugin', async function () {
342 for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) {
343 await makeGetRequest({
346 token: server.accessToken,
347 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
352 it('Should succeed with the correct parameters', async function () {
353 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) {
354 await makeGetRequest({
357 token: server.accessToken,
358 statusCodeExpected: HttpStatusCode.OK_200
364 describe('When updating plugin settings', function () {
365 const path = '/api/v1/plugins/'
366 const settings = { setting1: 'value1' }
368 it('Should fail with an invalid token', async function () {
369 await makePutBodyRequest({
371 path: path + npmPlugin + '/settings',
372 fields: { settings },
374 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
378 it('Should fail if the user is not an administrator', async function () {
379 await makePutBodyRequest({
381 path: path + npmPlugin + '/settings',
382 fields: { settings },
383 token: userAccessToken,
384 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
388 it('Should fail with an invalid npm name', async function () {
389 await makePutBodyRequest({
391 path: path + 'toto/settings',
392 fields: { settings },
393 token: server.accessToken,
394 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
397 await makePutBodyRequest({
399 path: path + 'peertube-plugin-TOTO/settings',
400 fields: { settings },
401 token: server.accessToken,
402 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
406 it('Should fail with an unknown plugin', async function () {
407 await makePutBodyRequest({
409 path: path + 'peertube-plugin-toto/settings',
410 fields: { settings },
411 token: server.accessToken,
412 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
416 it('Should succeed with the correct parameters', async function () {
417 await makePutBodyRequest({
419 path: path + npmPlugin + '/settings',
420 fields: { settings },
421 token: server.accessToken,
422 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
427 describe('When installing/updating/uninstalling a plugin', function () {
428 const path = '/api/v1/plugins/'
430 it('Should fail with an invalid token', async function () {
431 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
432 await makePostBodyRequest({
435 fields: { npmName: npmPlugin },
437 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
442 it('Should fail if the user is not an administrator', async function () {
443 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
444 await makePostBodyRequest({
447 fields: { npmName: npmPlugin },
448 token: userAccessToken,
449 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
454 it('Should fail with an invalid npm name', async function () {
455 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
456 await makePostBodyRequest({
459 fields: { npmName: 'toto' },
460 token: server.accessToken,
461 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
465 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
466 await makePostBodyRequest({
469 fields: { npmName: 'peertube-plugin-TOTO' },
470 token: server.accessToken,
471 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
476 it('Should succeed with the correct parameters', async function () {
480 { suffix: 'install', status: HttpStatusCode.OK_200 },
481 { suffix: 'update', status: HttpStatusCode.OK_200 },
482 { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 }
485 for (const obj of it) {
486 await makePostBodyRequest({
488 path: path + obj.suffix,
489 fields: { npmName: npmPlugin },
490 token: server.accessToken,
491 statusCodeExpected: obj.status
497 after(async function () {
498 await cleanupTests([ server ])