]>
Commit | Line | Data |
---|---|---|
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | |
2 | ||
3 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared' | |
4 | import { HttpStatusCode, PeerTubePlugin, PluginType } from '@shared/models' | |
5 | import { | |
6 | cleanupTests, | |
7 | createSingleServer, | |
8 | makeGetRequest, | |
9 | makePostBodyRequest, | |
10 | makePutBodyRequest, | |
11 | PeerTubeServer, | |
12 | setAccessTokensToServers | |
13 | } from '@shared/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 | }) |