1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
5 checkBadCountPagination,
6 checkBadSortPagination,
7 checkBadStartPagination,
14 setAccessTokensToServers
15 } from '@shared/extra-utils'
16 import { HttpStatusCode, PeerTubePlugin, PluginType } from '@shared/models'
18 describe('Test server plugins API validators', function () {
19 let server: PeerTubeServer
20 let userAccessToken = null
22 const npmPlugin = 'peertube-plugin-hello-world'
23 const pluginName = 'hello-world'
24 let npmVersion: string
26 const themePlugin = 'peertube-theme-background-red'
27 const themeName = 'background-red'
28 let themeVersion: string
30 // ---------------------------------------------------------------
32 before(async function () {
35 server = await createSingleServer(1)
37 await setAccessTokensToServers([ server ])
44 await server.users.create({ username: user.username, password: user.password })
45 userAccessToken = await server.login.getAccessToken(user)
48 const res = await server.plugins.install({ npmName: npmPlugin })
49 const plugin = res.body as PeerTubePlugin
50 npmVersion = plugin.version
54 const res = await server.plugins.install({ npmName: themePlugin })
55 const plugin = res.body as PeerTubePlugin
56 themeVersion = plugin.version
60 describe('With static plugin routes', function () {
61 it('Should fail with an unknown plugin name/plugin version', async function () {
63 '/plugins/' + pluginName + '/0.0.1/auth/fake-auth',
64 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png',
65 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js',
66 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png',
67 '/themes/' + themeName + '/0.0.1/client-scripts/client/video-watch-client-plugin.js',
68 '/themes/' + themeName + '/0.0.1/css/assets/style1.css'
71 for (const p of paths) {
72 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
76 it('Should fail when requesting a plugin in the theme path', async function () {
77 await makeGetRequest({
79 path: '/themes/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
80 expectedStatus: HttpStatusCode.NOT_FOUND_404
84 it('Should fail with invalid versions', async function () {
86 '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth',
87 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png',
88 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js',
89 '/themes/' + themeName + '/1/static/images/chocobo.png',
90 '/themes/' + themeName + '/0.0.1000a/client-scripts/client/video-watch-client-plugin.js',
91 '/themes/' + themeName + '/0.a.1/css/assets/style1.css'
94 for (const p of paths) {
95 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
99 it('Should fail with invalid paths', async function () {
101 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/../chocobo.png',
102 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/../client/common-client-plugin.js',
103 '/themes/' + themeName + '/' + themeVersion + '/static/../images/chocobo.png',
104 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js/..',
105 '/themes/' + themeName + '/' + themeVersion + '/css/../assets/style1.css'
108 for (const p of paths) {
109 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
113 it('Should fail with an unknown auth name', async function () {
114 const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth'
116 await makeGetRequest({ url: server.url, path, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
119 it('Should fail with an unknown static file', async function () {
121 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png',
122 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/fake.js',
123 '/themes/' + themeName + '/' + themeVersion + '/static/fake/chocobo.png',
124 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/fake.js'
127 for (const p of paths) {
128 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
132 it('Should fail with an unknown CSS file', async function () {
133 await makeGetRequest({
135 path: '/themes/' + themeName + '/' + themeVersion + '/css/assets/fake.css',
136 expectedStatus: HttpStatusCode.NOT_FOUND_404
140 it('Should succeed with the correct parameters', async function () {
142 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
143 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/common-client-plugin.js',
144 '/themes/' + themeName + '/' + themeVersion + '/static/images/chocobo.png',
145 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js',
146 '/themes/' + themeName + '/' + themeVersion + '/css/assets/style1.css'
149 for (const p of paths) {
150 await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.OK_200 })
153 const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth'
154 await makeGetRequest({ url: server.url, path: authPath, expectedStatus: HttpStatusCode.FOUND_302 })
158 describe('When listing available plugins/themes', function () {
159 const path = '/api/v1/plugins/available'
161 search: 'super search',
162 pluginType: PluginType.PLUGIN,
163 currentPeerTubeEngine: '1.2.3'
166 it('Should fail with an invalid token', async function () {
167 await makeGetRequest({
172 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
176 it('Should fail if the user is not an administrator', async function () {
177 await makeGetRequest({
180 token: userAccessToken,
182 expectedStatus: HttpStatusCode.FORBIDDEN_403
186 it('Should fail with a bad start pagination', async function () {
187 await checkBadStartPagination(server.url, path, server.accessToken)
190 it('Should fail with a bad count pagination', async function () {
191 await checkBadCountPagination(server.url, path, server.accessToken)
194 it('Should fail with an incorrect sort', async function () {
195 await checkBadSortPagination(server.url, path, server.accessToken)
198 it('Should fail with an invalid plugin type', async function () {
199 const query = { ...baseQuery, pluginType: 5 }
201 await makeGetRequest({
204 token: server.accessToken,
209 it('Should fail with an invalid current peertube engine', async function () {
210 const query = { ...baseQuery, currentPeerTubeEngine: '1.0' }
212 await makeGetRequest({
215 token: server.accessToken,
220 it('Should success with the correct parameters', async function () {
221 await makeGetRequest({
224 token: server.accessToken,
226 expectedStatus: HttpStatusCode.OK_200
231 describe('When listing local plugins/themes', function () {
232 const path = '/api/v1/plugins'
234 pluginType: PluginType.THEME
237 it('Should fail with an invalid token', async function () {
238 await makeGetRequest({
243 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
247 it('Should fail if the user is not an administrator', async function () {
248 await makeGetRequest({
251 token: userAccessToken,
253 expectedStatus: HttpStatusCode.FORBIDDEN_403
257 it('Should fail with a bad start pagination', async function () {
258 await checkBadStartPagination(server.url, path, server.accessToken)
261 it('Should fail with a bad count pagination', async function () {
262 await checkBadCountPagination(server.url, path, server.accessToken)
265 it('Should fail with an incorrect sort', async function () {
266 await checkBadSortPagination(server.url, path, server.accessToken)
269 it('Should fail with an invalid plugin type', async function () {
270 const query = { ...baseQuery, pluginType: 5 }
272 await makeGetRequest({
275 token: server.accessToken,
280 it('Should success with the correct parameters', async function () {
281 await makeGetRequest({
284 token: server.accessToken,
286 expectedStatus: HttpStatusCode.OK_200
291 describe('When getting a plugin or the registered settings or public settings', function () {
292 const path = '/api/v1/plugins/'
294 it('Should fail with an invalid token', async function () {
295 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
296 await makeGetRequest({
300 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
305 it('Should fail if the user is not an administrator', async function () {
306 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
307 await makeGetRequest({
310 token: userAccessToken,
311 expectedStatus: HttpStatusCode.FORBIDDEN_403
316 it('Should fail with an invalid npm name', async function () {
317 for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) {
318 await makeGetRequest({
321 token: server.accessToken,
322 expectedStatus: HttpStatusCode.BAD_REQUEST_400
326 for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) {
327 await makeGetRequest({
330 token: server.accessToken,
331 expectedStatus: HttpStatusCode.BAD_REQUEST_400
336 it('Should fail with an unknown plugin', async function () {
337 for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) {
338 await makeGetRequest({
341 token: server.accessToken,
342 expectedStatus: HttpStatusCode.NOT_FOUND_404
347 it('Should succeed with the correct parameters', async function () {
348 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) {
349 await makeGetRequest({
352 token: server.accessToken,
353 expectedStatus: HttpStatusCode.OK_200
359 describe('When updating plugin settings', function () {
360 const path = '/api/v1/plugins/'
361 const settings = { setting1: 'value1' }
363 it('Should fail with an invalid token', async function () {
364 await makePutBodyRequest({
366 path: path + npmPlugin + '/settings',
367 fields: { settings },
369 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
373 it('Should fail if the user is not an administrator', async function () {
374 await makePutBodyRequest({
376 path: path + npmPlugin + '/settings',
377 fields: { settings },
378 token: userAccessToken,
379 expectedStatus: HttpStatusCode.FORBIDDEN_403
383 it('Should fail with an invalid npm name', async function () {
384 await makePutBodyRequest({
386 path: path + 'toto/settings',
387 fields: { settings },
388 token: server.accessToken,
389 expectedStatus: HttpStatusCode.BAD_REQUEST_400
392 await makePutBodyRequest({
394 path: path + 'peertube-plugin-TOTO/settings',
395 fields: { settings },
396 token: server.accessToken,
397 expectedStatus: HttpStatusCode.BAD_REQUEST_400
401 it('Should fail with an unknown plugin', async function () {
402 await makePutBodyRequest({
404 path: path + 'peertube-plugin-toto/settings',
405 fields: { settings },
406 token: server.accessToken,
407 expectedStatus: HttpStatusCode.NOT_FOUND_404
411 it('Should succeed with the correct parameters', async function () {
412 await makePutBodyRequest({
414 path: path + npmPlugin + '/settings',
415 fields: { settings },
416 token: server.accessToken,
417 expectedStatus: HttpStatusCode.NO_CONTENT_204
422 describe('When installing/updating/uninstalling a plugin', function () {
423 const path = '/api/v1/plugins/'
425 it('Should fail with an invalid token', async function () {
426 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
427 await makePostBodyRequest({
430 fields: { npmName: npmPlugin },
432 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
437 it('Should fail if the user is not an administrator', async function () {
438 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
439 await makePostBodyRequest({
442 fields: { npmName: npmPlugin },
443 token: userAccessToken,
444 expectedStatus: HttpStatusCode.FORBIDDEN_403
449 it('Should fail with an invalid npm name', async function () {
450 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
451 await makePostBodyRequest({
454 fields: { npmName: 'toto' },
455 token: server.accessToken,
456 expectedStatus: HttpStatusCode.BAD_REQUEST_400
460 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
461 await makePostBodyRequest({
464 fields: { npmName: 'peertube-plugin-TOTO' },
465 token: server.accessToken,
466 expectedStatus: HttpStatusCode.BAD_REQUEST_400
471 it('Should succeed with the correct parameters', async function () {
475 { suffix: 'install', status: HttpStatusCode.OK_200 },
476 { suffix: 'update', status: HttpStatusCode.OK_200 },
477 { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 }
480 for (const obj of it) {
481 await makePostBodyRequest({
483 path: path + obj.suffix,
484 fields: { npmName: npmPlugin },
485 token: server.accessToken,
486 expectedStatus: obj.status
492 after(async function () {
493 await cleanupTests([ server ])