1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
5 import { HttpStatusCode, PeerTubePlugin, PluginType } from '@shared/models'
13 setAccessTokensToServers
14 } from '@shared/server-commands'
16 describe('Test server plugins API validators', function () {
17 let server: PeerTubeServer
18 let userAccessToken = null
20 const npmPlugin = 'peertube-plugin-hello-world'
21 const pluginName = 'hello-world'
22 let npmVersion: string
24 const themePlugin = 'peertube-theme-background-red'
25 const themeName = 'background-red'
26 let themeVersion: string
28 // ---------------------------------------------------------------
30 before(async function () {
33 server = await createSingleServer(1)
35 await setAccessTokensToServers([ server ])
42 await server.users.create({ username: user.username, password: user.password })
43 userAccessToken = await server.login.getAccessToken(user)
46 const res = await server.plugins.install({ npmName: npmPlugin })
47 const plugin = res.body as PeerTubePlugin
48 npmVersion = plugin.version
52 const res = await server.plugins.install({ npmName: themePlugin })
53 const plugin = res.body as PeerTubePlugin
54 themeVersion = plugin.version
58 describe('With static plugin routes', function () {
59 it('Should fail with an unknown plugin name/plugin version', async function () {
61 '/plugins/' + pluginName + '/0.0.1/auth/fake-auth',
62 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png',
63 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js',
64 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png',
65 '/themes/' + themeName + '/0.0.1/client-scripts/client/video-watch-client-plugin.js',
66 '/themes/' + themeName + '/0.0.1/css/assets/style1.css'
69 for (const p of paths) {
70 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
74 it('Should fail when requesting a plugin in the theme path', async function () {
75 await makeGetRequest({
77 path: '/themes/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
78 expectedStatus: HttpStatusCode.NOT_FOUND_404
82 it('Should fail with invalid versions', async function () {
84 '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth',
85 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png',
86 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js',
87 '/themes/' + themeName + '/1/static/images/chocobo.png',
88 '/themes/' + themeName + '/0.0.1000a/client-scripts/client/video-watch-client-plugin.js',
89 '/themes/' + themeName + '/0.a.1/css/assets/style1.css'
92 for (const p of paths) {
93 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
97 it('Should fail with invalid paths', async function () {
99 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/../chocobo.png',
100 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/../client/common-client-plugin.js',
101 '/themes/' + themeName + '/' + themeVersion + '/static/../images/chocobo.png',
102 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js/..',
103 '/themes/' + themeName + '/' + themeVersion + '/css/../assets/style1.css'
106 for (const p of paths) {
107 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
111 it('Should fail with an unknown auth name', async function () {
112 const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth'
114 await makeGetRequest({ url: server.url, path, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
117 it('Should fail with an unknown static file', async function () {
119 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png',
120 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/fake.js',
121 '/themes/' + themeName + '/' + themeVersion + '/static/fake/chocobo.png',
122 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/fake.js'
125 for (const p of paths) {
126 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
130 it('Should fail with an unknown CSS file', async function () {
131 await makeGetRequest({
133 path: '/themes/' + themeName + '/' + themeVersion + '/css/assets/fake.css',
134 expectedStatus: HttpStatusCode.NOT_FOUND_404
138 it('Should succeed with the correct parameters', async function () {
140 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
141 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/common-client-plugin.js',
142 '/themes/' + themeName + '/' + themeVersion + '/static/images/chocobo.png',
143 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js',
144 '/themes/' + themeName + '/' + themeVersion + '/css/assets/style1.css'
147 for (const p of paths) {
148 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.OK_200 })
151 const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth'
152 await makeGetRequest({ url: server.url, path: authPath, expectedStatus: HttpStatusCode.FOUND_302 })
156 describe('When listing available plugins/themes', function () {
157 const path = '/api/v1/plugins/available'
159 search: 'super search',
160 pluginType: PluginType.PLUGIN,
161 currentPeerTubeEngine: '1.2.3'
164 it('Should fail with an invalid token', async function () {
165 await makeGetRequest({
170 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
174 it('Should fail if the user is not an administrator', async function () {
175 await makeGetRequest({
178 token: userAccessToken,
180 expectedStatus: HttpStatusCode.FORBIDDEN_403
184 it('Should fail with a bad start pagination', async function () {
185 await checkBadStartPagination(server.url, path, server.accessToken)
188 it('Should fail with a bad count pagination', async function () {
189 await checkBadCountPagination(server.url, path, server.accessToken)
192 it('Should fail with an incorrect sort', async function () {
193 await checkBadSortPagination(server.url, path, server.accessToken)
196 it('Should fail with an invalid plugin type', async function () {
197 const query = { ...baseQuery, pluginType: 5 }
199 await makeGetRequest({
202 token: server.accessToken,
207 it('Should fail with an invalid current peertube engine', async function () {
208 const query = { ...baseQuery, currentPeerTubeEngine: '1.0' }
210 await makeGetRequest({
213 token: server.accessToken,
218 it('Should success with the correct parameters', async function () {
219 await makeGetRequest({
222 token: server.accessToken,
224 expectedStatus: HttpStatusCode.OK_200
229 describe('When listing local plugins/themes', function () {
230 const path = '/api/v1/plugins'
232 pluginType: PluginType.THEME
235 it('Should fail with an invalid token', async function () {
236 await makeGetRequest({
241 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
245 it('Should fail if the user is not an administrator', async function () {
246 await makeGetRequest({
249 token: userAccessToken,
251 expectedStatus: HttpStatusCode.FORBIDDEN_403
255 it('Should fail with a bad start pagination', async function () {
256 await checkBadStartPagination(server.url, path, server.accessToken)
259 it('Should fail with a bad count pagination', async function () {
260 await checkBadCountPagination(server.url, path, server.accessToken)
263 it('Should fail with an incorrect sort', async function () {
264 await checkBadSortPagination(server.url, path, server.accessToken)
267 it('Should fail with an invalid plugin type', async function () {
268 const query = { ...baseQuery, pluginType: 5 }
270 await makeGetRequest({
273 token: server.accessToken,
278 it('Should success with the correct parameters', async function () {
279 await makeGetRequest({
282 token: server.accessToken,
284 expectedStatus: HttpStatusCode.OK_200
289 describe('When getting a plugin or the registered settings or public settings', function () {
290 const path = '/api/v1/plugins/'
292 it('Should fail with an invalid token', async function () {
293 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
294 await makeGetRequest({
298 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
303 it('Should fail if the user is not an administrator', async function () {
304 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
305 await makeGetRequest({
308 token: userAccessToken,
309 expectedStatus: HttpStatusCode.FORBIDDEN_403
314 it('Should fail with an invalid npm name', async function () {
315 for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) {
316 await makeGetRequest({
319 token: server.accessToken,
320 expectedStatus: HttpStatusCode.BAD_REQUEST_400
324 for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) {
325 await makeGetRequest({
328 token: server.accessToken,
329 expectedStatus: HttpStatusCode.BAD_REQUEST_400
334 it('Should fail with an unknown plugin', async function () {
335 for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) {
336 await makeGetRequest({
339 token: server.accessToken,
340 expectedStatus: HttpStatusCode.NOT_FOUND_404
345 it('Should succeed with the correct parameters', async function () {
346 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) {
347 await makeGetRequest({
350 token: server.accessToken,
351 expectedStatus: HttpStatusCode.OK_200
357 describe('When updating plugin settings', function () {
358 const path = '/api/v1/plugins/'
359 const settings = { setting1: 'value1' }
361 it('Should fail with an invalid token', async function () {
362 await makePutBodyRequest({
364 path: path + npmPlugin + '/settings',
365 fields: { settings },
367 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
371 it('Should fail if the user is not an administrator', async function () {
372 await makePutBodyRequest({
374 path: path + npmPlugin + '/settings',
375 fields: { settings },
376 token: userAccessToken,
377 expectedStatus: HttpStatusCode.FORBIDDEN_403
381 it('Should fail with an invalid npm name', async function () {
382 await makePutBodyRequest({
384 path: path + 'toto/settings',
385 fields: { settings },
386 token: server.accessToken,
387 expectedStatus: HttpStatusCode.BAD_REQUEST_400
390 await makePutBodyRequest({
392 path: path + 'peertube-plugin-TOTO/settings',
393 fields: { settings },
394 token: server.accessToken,
395 expectedStatus: HttpStatusCode.BAD_REQUEST_400
399 it('Should fail with an unknown plugin', async function () {
400 await makePutBodyRequest({
402 path: path + 'peertube-plugin-toto/settings',
403 fields: { settings },
404 token: server.accessToken,
405 expectedStatus: HttpStatusCode.NOT_FOUND_404
409 it('Should succeed with the correct parameters', async function () {
410 await makePutBodyRequest({
412 path: path + npmPlugin + '/settings',
413 fields: { settings },
414 token: server.accessToken,
415 expectedStatus: HttpStatusCode.NO_CONTENT_204
420 describe('When installing/updating/uninstalling a plugin', function () {
421 const path = '/api/v1/plugins/'
423 it('Should fail with an invalid token', async function () {
424 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
425 await makePostBodyRequest({
428 fields: { npmName: npmPlugin },
430 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
435 it('Should fail if the user is not an administrator', async function () {
436 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
437 await makePostBodyRequest({
440 fields: { npmName: npmPlugin },
441 token: userAccessToken,
442 expectedStatus: HttpStatusCode.FORBIDDEN_403
447 it('Should fail with an invalid npm name', async function () {
448 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
449 await makePostBodyRequest({
452 fields: { npmName: 'toto' },
453 token: server.accessToken,
454 expectedStatus: HttpStatusCode.BAD_REQUEST_400
458 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
459 await makePostBodyRequest({
462 fields: { npmName: 'peertube-plugin-TOTO' },
463 token: server.accessToken,
464 expectedStatus: HttpStatusCode.BAD_REQUEST_400
469 it('Should succeed with the correct parameters', async function () {
473 { suffix: 'install', status: HttpStatusCode.OK_200 },
474 { suffix: 'update', status: HttpStatusCode.OK_200 },
475 { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 }
478 for (const obj of it) {
479 await makePostBodyRequest({
481 path: path + obj.suffix,
482 fields: { npmName: npmPlugin },
483 token: server.accessToken,
484 expectedStatus: obj.status
490 after(async function () {
491 await cleanupTests([ server ])