]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/check-params/plugins.ts
Introduce server commands
[github/Chocobozzz/PeerTube.git] / server / tests / api / check-params / plugins.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
60cfd4cb
C
2
3import 'mocha'
428ccb8b 4import { HttpStatusCode } from '@shared/core-utils'
60cfd4cb
C
5import {
6 checkBadCountPagination,
7 checkBadSortPagination,
8 checkBadStartPagination,
9 cleanupTests,
10 createUser,
11 flushAndRunServer,
428ccb8b
C
12 makeGetRequest,
13 makePostBodyRequest,
14 makePutBodyRequest,
60cfd4cb
C
15 ServerInfo,
16 setAccessTokensToServers,
17 userLogin
428ccb8b
C
18} from '@shared/extra-utils'
19import { PeerTubePlugin, PluginType } from '@shared/models'
60cfd4cb
C
20
21describe('Test server plugins API validators', function () {
22 let server: ServerInfo
23 let userAccessToken = null
24
25 const npmPlugin = 'peertube-plugin-hello-world'
26 const pluginName = 'hello-world'
27 let npmVersion: string
28
29 const themePlugin = 'peertube-theme-background-red'
30 const themeName = 'background-red'
31 let themeVersion: string
32
33 // ---------------------------------------------------------------
34
35 before(async function () {
36 this.timeout(30000)
37
38 server = await flushAndRunServer(1)
39
40 await setAccessTokensToServers([ server ])
41
42 const user = {
43 username: 'user1',
44 password: 'password'
45 }
46
47 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
48 userAccessToken = await userLogin(server, user)
49
50 {
ae2abfd3 51 const res = await server.pluginsCommand.install({ npmName: npmPlugin })
60cfd4cb
C
52 const plugin = res.body as PeerTubePlugin
53 npmVersion = plugin.version
54 }
55
56 {
ae2abfd3 57 const res = await server.pluginsCommand.install({ npmName: themePlugin })
60cfd4cb
C
58 const plugin = res.body as PeerTubePlugin
59 themeVersion = plugin.version
60 }
61 })
62
63 describe('With static plugin routes', function () {
64 it('Should fail with an unknown plugin name/plugin version', async function () {
65 const paths = [
9107d791 66 '/plugins/' + pluginName + '/0.0.1/auth/fake-auth',
60cfd4cb
C
67 '/plugins/' + pluginName + '/0.0.1/static/images/chocobo.png',
68 '/plugins/' + pluginName + '/0.0.1/client-scripts/client/common-client-plugin.js',
69 '/themes/' + themeName + '/0.0.1/static/images/chocobo.png',
70 '/themes/' + themeName + '/0.0.1/client-scripts/client/video-watch-client-plugin.js',
71 '/themes/' + themeName + '/0.0.1/css/assets/style1.css'
72 ]
73
74 for (const p of paths) {
2d53be02 75 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
60cfd4cb
C
76 }
77 })
78
79 it('Should fail when requesting a plugin in the theme path', async function () {
80 await makeGetRequest({
81 url: server.url,
82 path: '/themes/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
2d53be02 83 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
60cfd4cb
C
84 })
85 })
86
87 it('Should fail with invalid versions', async function () {
88 const paths = [
9107d791 89 '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth',
60cfd4cb
C
90 '/plugins/' + pluginName + '/0.0.1.1/static/images/chocobo.png',
91 '/plugins/' + pluginName + '/0.1/client-scripts/client/common-client-plugin.js',
92 '/themes/' + themeName + '/1/static/images/chocobo.png',
93 '/themes/' + themeName + '/0.0.1000a/client-scripts/client/video-watch-client-plugin.js',
94 '/themes/' + themeName + '/0.a.1/css/assets/style1.css'
95 ]
96
97 for (const p of paths) {
2d53be02 98 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 })
60cfd4cb
C
99 }
100 })
101
102 it('Should fail with invalid paths', async function () {
103 const paths = [
104 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/../chocobo.png',
105 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/../client/common-client-plugin.js',
106 '/themes/' + themeName + '/' + themeVersion + '/static/../images/chocobo.png',
107 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js/..',
108 '/themes/' + themeName + '/' + themeVersion + '/css/../assets/style1.css'
109 ]
110
111 for (const p of paths) {
2d53be02 112 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 })
60cfd4cb
C
113 }
114 })
115
9107d791
C
116 it('Should fail with an unknown auth name', async function () {
117 const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth'
118
2d53be02 119 await makeGetRequest({ url: server.url, path, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
9107d791
C
120 })
121
60cfd4cb
C
122 it('Should fail with an unknown static file', async function () {
123 const paths = [
124 '/plugins/' + pluginName + '/' + npmVersion + '/static/fake/chocobo.png',
125 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/fake.js',
126 '/themes/' + themeName + '/' + themeVersion + '/static/fake/chocobo.png',
127 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/fake.js'
128 ]
129
130 for (const p of paths) {
2d53be02 131 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.NOT_FOUND_404 })
60cfd4cb
C
132 }
133 })
134
135 it('Should fail with an unknown CSS file', async function () {
136 await makeGetRequest({
137 url: server.url,
138 path: '/themes/' + themeName + '/' + themeVersion + '/css/assets/fake.css',
2d53be02 139 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
60cfd4cb
C
140 })
141 })
142
143 it('Should succeed with the correct parameters', async function () {
144 const paths = [
145 '/plugins/' + pluginName + '/' + npmVersion + '/static/images/chocobo.png',
146 '/plugins/' + pluginName + '/' + npmVersion + '/client-scripts/client/common-client-plugin.js',
147 '/themes/' + themeName + '/' + themeVersion + '/static/images/chocobo.png',
148 '/themes/' + themeName + '/' + themeVersion + '/client-scripts/client/video-watch-client-plugin.js',
149 '/themes/' + themeName + '/' + themeVersion + '/css/assets/style1.css'
150 ]
151
152 for (const p of paths) {
2d53be02 153 await makeGetRequest({ url: server.url, path: p, statusCodeExpected: HttpStatusCode.OK_200 })
60cfd4cb 154 }
9107d791
C
155
156 const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth'
2d53be02 157 await makeGetRequest({ url: server.url, path: authPath, statusCodeExpected: HttpStatusCode.FOUND_302 })
60cfd4cb
C
158 })
159 })
160
161 describe('When listing available plugins/themes', function () {
162 const path = '/api/v1/plugins/available'
163 const baseQuery = {
164 search: 'super search',
09071200
C
165 pluginType: PluginType.PLUGIN,
166 currentPeerTubeEngine: '1.2.3'
60cfd4cb
C
167 }
168
169 it('Should fail with an invalid token', async function () {
170 await makeGetRequest({
171 url: server.url,
172 path,
173 token: 'fake_token',
174 query: baseQuery,
2d53be02 175 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
60cfd4cb
C
176 })
177 })
178
179 it('Should fail if the user is not an administrator', async function () {
180 await makeGetRequest({
181 url: server.url,
182 path,
183 token: userAccessToken,
184 query: baseQuery,
2d53be02 185 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
60cfd4cb
C
186 })
187 })
188
189 it('Should fail with a bad start pagination', async function () {
190 await checkBadStartPagination(server.url, path, server.accessToken)
191 })
192
193 it('Should fail with a bad count pagination', async function () {
194 await checkBadCountPagination(server.url, path, server.accessToken)
195 })
196
197 it('Should fail with an incorrect sort', async function () {
198 await checkBadSortPagination(server.url, path, server.accessToken)
199 })
200
201 it('Should fail with an invalid plugin type', async function () {
6c5065a0 202 const query = { ...baseQuery, pluginType: 5 }
60cfd4cb
C
203
204 await makeGetRequest({
205 url: server.url,
206 path,
207 token: server.accessToken,
208 query
209 })
210 })
211
09071200 212 it('Should fail with an invalid current peertube engine', async function () {
6c5065a0 213 const query = { ...baseQuery, currentPeerTubeEngine: '1.0' }
09071200
C
214
215 await makeGetRequest({
216 url: server.url,
217 path,
218 token: server.accessToken,
219 query
220 })
221 })
222
60cfd4cb
C
223 it('Should success with the correct parameters', async function () {
224 await makeGetRequest({
225 url: server.url,
226 path,
227 token: server.accessToken,
228 query: baseQuery,
2d53be02 229 statusCodeExpected: HttpStatusCode.OK_200
60cfd4cb
C
230 })
231 })
232 })
233
234 describe('When listing local plugins/themes', function () {
235 const path = '/api/v1/plugins'
236 const baseQuery = {
237 pluginType: PluginType.THEME
238 }
239
240 it('Should fail with an invalid token', async function () {
241 await makeGetRequest({
242 url: server.url,
243 path,
244 token: 'fake_token',
245 query: baseQuery,
2d53be02 246 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
60cfd4cb
C
247 })
248 })
249
250 it('Should fail if the user is not an administrator', async function () {
251 await makeGetRequest({
252 url: server.url,
253 path,
254 token: userAccessToken,
255 query: baseQuery,
2d53be02 256 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
60cfd4cb
C
257 })
258 })
259
260 it('Should fail with a bad start pagination', async function () {
261 await checkBadStartPagination(server.url, path, server.accessToken)
262 })
263
264 it('Should fail with a bad count pagination', async function () {
265 await checkBadCountPagination(server.url, path, server.accessToken)
266 })
267
268 it('Should fail with an incorrect sort', async function () {
269 await checkBadSortPagination(server.url, path, server.accessToken)
270 })
271
272 it('Should fail with an invalid plugin type', async function () {
6c5065a0 273 const query = { ...baseQuery, pluginType: 5 }
60cfd4cb
C
274
275 await makeGetRequest({
276 url: server.url,
277 path,
278 token: server.accessToken,
279 query
280 })
281 })
282
283 it('Should success with the correct parameters', async function () {
284 await makeGetRequest({
285 url: server.url,
286 path,
287 token: server.accessToken,
288 query: baseQuery,
2d53be02 289 statusCodeExpected: HttpStatusCode.OK_200
60cfd4cb
C
290 })
291 })
292 })
293
ba211e73 294 describe('When getting a plugin or the registered settings or public settings', function () {
60cfd4cb
C
295 const path = '/api/v1/plugins/'
296
297 it('Should fail with an invalid token', async function () {
298 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
299 await makeGetRequest({
300 url: server.url,
301 path: path + suffix,
302 token: 'fake_token',
2d53be02 303 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
60cfd4cb
C
304 })
305 }
306 })
307
308 it('Should fail if the user is not an administrator', async function () {
309 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) {
310 await makeGetRequest({
311 url: server.url,
312 path: path + suffix,
313 token: userAccessToken,
2d53be02 314 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
60cfd4cb
C
315 })
316 }
317 })
318
319 it('Should fail with an invalid npm name', async function () {
ba211e73 320 for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) {
60cfd4cb
C
321 await makeGetRequest({
322 url: server.url,
323 path: path + suffix,
324 token: server.accessToken,
2d53be02 325 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
60cfd4cb
C
326 })
327 }
328
ba211e73 329 for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) {
60cfd4cb
C
330 await makeGetRequest({
331 url: server.url,
332 path: path + suffix,
333 token: server.accessToken,
2d53be02 334 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
60cfd4cb
C
335 })
336 }
337 })
338
339 it('Should fail with an unknown plugin', async function () {
ba211e73 340 for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) {
60cfd4cb
C
341 await makeGetRequest({
342 url: server.url,
343 path: path + suffix,
344 token: server.accessToken,
2d53be02 345 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
60cfd4cb
C
346 })
347 }
348 })
349
350 it('Should succeed with the correct parameters', async function () {
ba211e73 351 for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) {
60cfd4cb
C
352 await makeGetRequest({
353 url: server.url,
354 path: path + suffix,
355 token: server.accessToken,
2d53be02 356 statusCodeExpected: HttpStatusCode.OK_200
60cfd4cb
C
357 })
358 }
359 })
360 })
361
362 describe('When updating plugin settings', function () {
363 const path = '/api/v1/plugins/'
364 const settings = { setting1: 'value1' }
365
366 it('Should fail with an invalid token', async function () {
367 await makePutBodyRequest({
368 url: server.url,
369 path: path + npmPlugin + '/settings',
370 fields: { settings },
371 token: 'fake_token',
2d53be02 372 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
60cfd4cb
C
373 })
374 })
375
376 it('Should fail if the user is not an administrator', async function () {
377 await makePutBodyRequest({
378 url: server.url,
379 path: path + npmPlugin + '/settings',
380 fields: { settings },
381 token: userAccessToken,
2d53be02 382 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
60cfd4cb
C
383 })
384 })
385
386 it('Should fail with an invalid npm name', async function () {
387 await makePutBodyRequest({
388 url: server.url,
389 path: path + 'toto/settings',
390 fields: { settings },
391 token: server.accessToken,
2d53be02 392 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
60cfd4cb
C
393 })
394
395 await makePutBodyRequest({
396 url: server.url,
397 path: path + 'peertube-plugin-TOTO/settings',
398 fields: { settings },
399 token: server.accessToken,
2d53be02 400 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
60cfd4cb
C
401 })
402 })
403
404 it('Should fail with an unknown plugin', async function () {
405 await makePutBodyRequest({
406 url: server.url,
407 path: path + 'peertube-plugin-toto/settings',
408 fields: { settings },
409 token: server.accessToken,
2d53be02 410 statusCodeExpected: HttpStatusCode.NOT_FOUND_404
60cfd4cb
C
411 })
412 })
413
414 it('Should succeed with the correct parameters', async function () {
415 await makePutBodyRequest({
416 url: server.url,
417 path: path + npmPlugin + '/settings',
418 fields: { settings },
419 token: server.accessToken,
2d53be02 420 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
60cfd4cb
C
421 })
422 })
423 })
424
425 describe('When installing/updating/uninstalling a plugin', function () {
426 const path = '/api/v1/plugins/'
427
428 it('Should fail with an invalid token', async function () {
429 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
430 await makePostBodyRequest({
431 url: server.url,
432 path: path + suffix,
433 fields: { npmName: npmPlugin },
434 token: 'fake_token',
2d53be02 435 statusCodeExpected: HttpStatusCode.UNAUTHORIZED_401
60cfd4cb
C
436 })
437 }
438 })
439
440 it('Should fail if the user is not an administrator', async function () {
441 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
442 await makePostBodyRequest({
443 url: server.url,
444 path: path + suffix,
445 fields: { npmName: npmPlugin },
446 token: userAccessToken,
2d53be02 447 statusCodeExpected: HttpStatusCode.FORBIDDEN_403
60cfd4cb
C
448 })
449 }
450 })
451
452 it('Should fail with an invalid npm name', async function () {
453 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
454 await makePostBodyRequest({
455 url: server.url,
456 path: path + suffix,
457 fields: { npmName: 'toto' },
458 token: server.accessToken,
2d53be02 459 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
60cfd4cb
C
460 })
461 }
462
463 for (const suffix of [ 'install', 'update', 'uninstall' ]) {
464 await makePostBodyRequest({
465 url: server.url,
466 path: path + suffix,
467 fields: { npmName: 'peertube-plugin-TOTO' },
468 token: server.accessToken,
2d53be02 469 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400
60cfd4cb
C
470 })
471 }
472 })
473
474 it('Should succeed with the correct parameters', async function () {
9107d791
C
475 this.timeout(10000)
476
60cfd4cb 477 const it = [
2d53be02
RK
478 { suffix: 'install', status: HttpStatusCode.OK_200 },
479 { suffix: 'update', status: HttpStatusCode.OK_200 },
480 { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 }
60cfd4cb
C
481 ]
482
483 for (const obj of it) {
484 await makePostBodyRequest({
485 url: server.url,
486 path: path + obj.suffix,
487 fields: { npmName: npmPlugin },
488 token: server.accessToken,
489 statusCodeExpected: obj.status
490 })
491 }
492 })
493 })
494
495 after(async function () {
496 await cleanupTests([ server ])
497 })
498})