diff options
Diffstat (limited to 'packages/tests/src/api/check-params/plugins.ts')
-rw-r--r-- | packages/tests/src/api/check-params/plugins.ts | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/packages/tests/src/api/check-params/plugins.ts b/packages/tests/src/api/check-params/plugins.ts new file mode 100644 index 000000000..ab2a426fe --- /dev/null +++ b/packages/tests/src/api/check-params/plugins.ts | |||
@@ -0,0 +1,490 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@tests/shared/checks.js' | ||
4 | import { HttpStatusCode, PeerTubePlugin, PluginType } from '@peertube/peertube-models' | ||
5 | import { | ||
6 | cleanupTests, | ||
7 | createSingleServer, | ||
8 | makeGetRequest, | ||
9 | makePostBodyRequest, | ||
10 | makePutBodyRequest, | ||
11 | PeerTubeServer, | ||
12 | setAccessTokensToServers | ||
13 | } from '@peertube/peertube-server-commands' | ||
14 | |||
15 | describe('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 | const it = [ | ||
470 | { suffix: 'install', status: HttpStatusCode.OK_200 }, | ||
471 | { suffix: 'update', status: HttpStatusCode.OK_200 }, | ||
472 | { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 } | ||
473 | ] | ||
474 | |||
475 | for (const obj of it) { | ||
476 | await makePostBodyRequest({ | ||
477 | url: server.url, | ||
478 | path: path + obj.suffix, | ||
479 | fields: { npmName: npmPlugin }, | ||
480 | token: server.accessToken, | ||
481 | expectedStatus: obj.status | ||
482 | }) | ||
483 | } | ||
484 | }) | ||
485 | }) | ||
486 | |||
487 | after(async function () { | ||
488 | await cleanupTests([ server ]) | ||
489 | }) | ||
490 | }) | ||