1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
4 import { HttpStatusCode, PeerTubePlugin, PluginType } from '@shared/models'
12 setAccessTokensToServers
13 } from '@shared/server-commands'
15 describe('Test server plugins API validators', function () {
16 let server: PeerTubeServer
17 let userAccessToken = null
19 const npmPlugin = 'peertube-plugin-hello-world'
20 const pluginName = 'hello-world'
21 let npmVersion: string
23 const themePlugin = 'peertube-theme-background-red'
24 const themeName = 'background-red'
25 let themeVersion: string
27 // ---------------------------------------------------------------
29 before(async function () {
32 server = await createSingleServer(1)
34 await setAccessTokensToServers([ server ])
41 await server.users.create({ username: user.username, password: user.password })
42 userAccessToken = await server.login.getAccessToken(user)
45 const res = await server.plugins.install({ npmName: npmPlugin })
46 const plugin = res.body as PeerTubePlugin
47 npmVersion = plugin.version
51 const res = await server.plugins.install({ npmName: themePlugin })
52 const plugin = res.body as PeerTubePlugin
53 themeVersion = plugin.version
57 describe('With static plugin routes', function () {
58 it('Should fail with an unknown plugin name/plugin version', async function () {
60 '/plugins/' + pluginName + '/0.0.1/auth/fake-auth',
61 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png',
62 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js',
63 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png',
64 '/themes/' + themeName + '/0.0.1/client-scripts/client/video-watch-client-plugin.js',
65 '/themes/' + themeName + '/0.0.1/css/assets/style1.css'
68 for (const p of paths) {
69 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
73 it('Should fail when requesting a plugin in the theme path', async function () {
74 await makeGetRequest({
76 path: '/themes/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
77 expectedStatus: HttpStatusCode.NOT_FOUND_404
81 it('Should fail with invalid versions', async function () {
83 '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth',
84 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png',
85 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js',
86 '/themes/' + themeName + '/1/static/images/chocobo.png',
87 '/themes/' + themeName + '/0.0.1000a/client-scripts/client/video-watch-client-plugin.js',
88 '/themes/' + themeName + '/0.a.1/css/assets/style1.css'
91 for (const p of paths) {
92 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
96 it('Should fail with invalid paths', async function () {
98 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/../chocobo.png',
99 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/../client/common-client-plugin.js',
100 '/themes/' + themeName + '/' + themeVersion + '/static/../images/chocobo.png',
101 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js/..',
102 '/themes/' + themeName + '/' + themeVersion + '/css/../assets/style1.css'
105 for (const p of paths) {
106 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
110 it('Should fail with an unknown auth name', async function () {
111 const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth'
113 await makeGetRequest({ url: server.url, path, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
116 it('Should fail with an unknown static file', async function () {
118 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png',
119 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/fake.js',
120 '/themes/' + themeName + '/' + themeVersion + '/static/fake/chocobo.png',
121 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/fake.js'
124 for (const p of paths) {
125 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
129 it('Should fail with an unknown CSS file', async function () {
130 await makeGetRequest({
132 path: '/themes/' + themeName + '/' + themeVersion + '/css/assets/fake.css',
133 expectedStatus: HttpStatusCode.NOT_FOUND_404
137 it('Should succeed with the correct parameters', async function () {
139 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
140 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/common-client-plugin.js',
141 '/themes/' + themeName + '/' + themeVersion + '/static/images/chocobo.png',
142 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js',
143 '/themes/' + themeName + '/' + themeVersion + '/css/assets/style1.css'
146 for (const p of paths) {
147 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.OK_200 })
150 const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth'
151 await makeGetRequest({ url: server.url, path: authPath, expectedStatus: HttpStatusCode.FOUND_302 })
155 describe('When listing available plugins/themes', function () {
156 const path = '/api/v1/plugins/available'
158 search: 'super search',
159 pluginType: PluginType.PLUGIN,
160 currentPeerTubeEngine: '1.2.3'
163 it('Should fail with an invalid token', async function () {
164 await makeGetRequest({
169 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
173 it('Should fail if the user is not an administrator', async function () {
174 await makeGetRequest({
177 token: userAccessToken,
179 expectedStatus: HttpStatusCode.FORBIDDEN_403
183 it('Should fail with a bad start pagination', async function () {
184 await checkBadStartPagination(server.url, path, server.accessToken)
187 it('Should fail with a bad count pagination', async function () {
188 await checkBadCountPagination(server.url, path, server.accessToken)
191 it('Should fail with an incorrect sort', async function () {
192 await checkBadSortPagination(server.url, path, server.accessToken)
195 it('Should fail with an invalid plugin type', async function () {
196 const query = { ...baseQuery, pluginType: 5 }
198 await makeGetRequest({
201 token: server.accessToken,
206 it('Should fail with an invalid current peertube engine', async function () {
207 const query = { ...baseQuery, currentPeerTubeEngine: '1.0' }
209 await makeGetRequest({
212 token: server.accessToken,
217 it('Should success with the correct parameters', async function () {
218 await makeGetRequest({
221 token: server.accessToken,
223 expectedStatus: HttpStatusCode.OK_200
228 describe('When listing local plugins/themes', function () {
229 const path = '/api/v1/plugins'
231 pluginType: PluginType.THEME
234 it('Should fail with an invalid token', async function () {
235 await makeGetRequest({
240 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
244 it('Should fail if the user is not an administrator', async function () {
245 await makeGetRequest({
248 token: userAccessToken,
250 expectedStatus: HttpStatusCode.FORBIDDEN_403
254 it('Should fail with a bad start pagination', async function () {
255 await checkBadStartPagination(server.url, path, server.accessToken)
258 it('Should fail with a bad count pagination', async function () {
259 await checkBadCountPagination(server.url, path, server.accessToken)
262 it('Should fail with an incorrect sort', async function () {
263 await checkBadSortPagination(server.url, path, server.accessToken)
266 it('Should fail with an invalid plugin type', async function () {
267 const query = { ...baseQuery, pluginType: 5 }
269 await makeGetRequest({
272 token: server.accessToken,
277 it('Should success with the correct parameters', async function () {
278 await makeGetRequest({
281 token: server.accessToken,
283 expectedStatus: HttpStatusCode.OK_200
288 describe('When getting a plugin or the registered settings or public settings', function () {
289 const path = '/api/v1/plugins/'
291 it('Should fail with an invalid token', async function () {
292 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
293 await makeGetRequest({
297 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
302 it('Should fail if the user is not an administrator', async function () {
303 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
304 await makeGetRequest({
307 token: userAccessToken,
308 expectedStatus: HttpStatusCode.FORBIDDEN_403
313 it('Should fail with an invalid npm name', async function () {
314 for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) {
315 await makeGetRequest({
318 token: server.accessToken,
319 expectedStatus: HttpStatusCode.BAD_REQUEST_400
323 for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) {
324 await makeGetRequest({
327 token: server.accessToken,
328 expectedStatus: HttpStatusCode.BAD_REQUEST_400
333 it('Should fail with an unknown plugin', async function () {
334 for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) {
335 await makeGetRequest({
338 token: server.accessToken,
339 expectedStatus: HttpStatusCode.NOT_FOUND_404
344 it('Should succeed with the correct parameters', async function () {
345 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) {
346 await makeGetRequest({
349 token: server.accessToken,
350 expectedStatus: HttpStatusCode.OK_200
356 describe('When updating plugin settings', function () {
357 const path = '/api/v1/plugins/'
358 const settings = { setting1: 'value1' }
360 it('Should fail with an invalid token', async function () {
361 await makePutBodyRequest({
363 path: path + npmPlugin + '/settings',
364 fields: { settings },
366 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
370 it('Should fail if the user is not an administrator', async function () {
371 await makePutBodyRequest({
373 path: path + npmPlugin + '/settings',
374 fields: { settings },
375 token: userAccessToken,
376 expectedStatus: HttpStatusCode.FORBIDDEN_403
380 it('Should fail with an invalid npm name', async function () {
381 await makePutBodyRequest({
383 path: path + 'toto/settings',
384 fields: { settings },
385 token: server.accessToken,
386 expectedStatus: HttpStatusCode.BAD_REQUEST_400
389 await makePutBodyRequest({
391 path: path + 'peertube-plugin-TOTO/settings',
392 fields: { settings },
393 token: server.accessToken,
394 expectedStatus: HttpStatusCode.BAD_REQUEST_400
398 it('Should fail with an unknown plugin', async function () {
399 await makePutBodyRequest({
401 path: path + 'peertube-plugin-toto/settings',
402 fields: { settings },
403 token: server.accessToken,
404 expectedStatus: HttpStatusCode.NOT_FOUND_404
408 it('Should succeed with the correct parameters', async function () {
409 await makePutBodyRequest({
411 path: path + npmPlugin + '/settings',
412 fields: { settings },
413 token: server.accessToken,
414 expectedStatus: HttpStatusCode.NO_CONTENT_204
419 describe('When installing/updating/uninstalling a plugin', function () {
420 const path = '/api/v1/plugins/'
422 it('Should fail with an invalid token', async function () {
423 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
424 await makePostBodyRequest({
427 fields: { npmName: npmPlugin },
429 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
434 it('Should fail if the user is not an administrator', async function () {
435 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
436 await makePostBodyRequest({
439 fields: { npmName: npmPlugin },
440 token: userAccessToken,
441 expectedStatus: HttpStatusCode.FORBIDDEN_403
446 it('Should fail with an invalid npm name', async function () {
447 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
448 await makePostBodyRequest({
451 fields: { npmName: 'toto' },
452 token: server.accessToken,
453 expectedStatus: HttpStatusCode.BAD_REQUEST_400
457 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
458 await makePostBodyRequest({
461 fields: { npmName: 'peertube-plugin-TOTO' },
462 token: server.accessToken,
463 expectedStatus: HttpStatusCode.BAD_REQUEST_400
468 it('Should succeed with the correct parameters', async function () {
472 { suffix: 'install', status: HttpStatusCode.OK_200 },
473 { suffix: 'update', status: HttpStatusCode.OK_200 },
474 { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 }
477 for (const obj of it) {
478 await makePostBodyRequest({
480 path: path + obj.suffix,
481 fields: { npmName: npmPlugin },
482 token: server.accessToken,
483 expectedStatus: obj.status
489 after(async function () {
490 await cleanupTests([ server ])