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