]>
Commit | Line | Data |
---|---|---|
a1587156 | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
60cfd4cb | 2 | |
c55e3d72 C |
3 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared' |
4 | import { HttpStatusCode, PeerTubePlugin, PluginType } from '@shared/models' | |
60cfd4cb | 5 | import { |
60cfd4cb | 6 | cleanupTests, |
254d3579 | 7 | createSingleServer, |
428ccb8b C |
8 | makeGetRequest, |
9 | makePostBodyRequest, | |
10 | makePutBodyRequest, | |
254d3579 | 11 | PeerTubeServer, |
41d1d075 | 12 | setAccessTokensToServers |
bf54587a | 13 | } from '@shared/server-commands' |
60cfd4cb C |
14 | |
15 | describe('Test server plugins API validators', function () { | |
254d3579 | 16 | let server: PeerTubeServer |
60cfd4cb C |
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 () { | |
33675a47 | 30 | this.timeout(60000) |
60cfd4cb | 31 | |
254d3579 | 32 | server = await createSingleServer(1) |
60cfd4cb C |
33 | |
34 | await setAccessTokensToServers([ server ]) | |
35 | ||
36 | const user = { | |
37 | username: 'user1', | |
38 | password: 'password' | |
39 | } | |
40 | ||
89d241a7 C |
41 | await server.users.create({ username: user.username, password: user.password }) |
42 | userAccessToken = await server.login.getAccessToken(user) | |
60cfd4cb C |
43 | |
44 | { | |
89d241a7 | 45 | const res = await server.plugins.install({ npmName: npmPlugin }) |
60cfd4cb C |
46 | const plugin = res.body as PeerTubePlugin |
47 | npmVersion = plugin.version | |
48 | } | |
49 | ||
50 | { | |
89d241a7 | 51 | const res = await server.plugins.install({ npmName: themePlugin }) |
60cfd4cb C |
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 = [ | |
9107d791 | 60 | '/plugins/' + pluginName + '/0.0.1/auth/fake-auth', |
60cfd4cb C |
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) { | |
c0e8b12e | 69 | await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) |
60cfd4cb C |
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', | |
c0e8b12e | 77 | expectedStatus: HttpStatusCode.NOT_FOUND_404 |
60cfd4cb C |
78 | }) |
79 | }) | |
80 | ||
81 | it('Should fail with invalid versions', async function () { | |
82 | const paths = [ | |
9107d791 | 83 | '/plugins/' + pluginName + '/0.0.1.1/auth/fake-auth', |
60cfd4cb C |
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) { | |
c0e8b12e | 92 | await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) |
60cfd4cb C |
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) { | |
c0e8b12e | 106 | await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) |
60cfd4cb C |
107 | } |
108 | }) | |
109 | ||
9107d791 C |
110 | it('Should fail with an unknown auth name', async function () { |
111 | const path = '/plugins/' + pluginName + '/' + npmVersion + '/auth/bad-auth' | |
112 | ||
c0e8b12e | 113 | await makeGetRequest({ url: server.url, path, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) |
9107d791 C |
114 | }) |
115 | ||
60cfd4cb C |
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) { | |
c0e8b12e | 125 | await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) |
60cfd4cb C |
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', | |
c0e8b12e | 133 | expectedStatus: HttpStatusCode.NOT_FOUND_404 |
60cfd4cb C |
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) { | |
c0e8b12e | 147 | await makeGetRequest({ url: server.url, path: p, expectedStatus: HttpStatusCode.OK_200 }) |
60cfd4cb | 148 | } |
9107d791 C |
149 | |
150 | const authPath = '/plugins/' + pluginName + '/' + npmVersion + '/auth/fake-auth' | |
c0e8b12e | 151 | await makeGetRequest({ url: server.url, path: authPath, expectedStatus: HttpStatusCode.FOUND_302 }) |
60cfd4cb C |
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', | |
09071200 C |
159 | pluginType: PluginType.PLUGIN, |
160 | currentPeerTubeEngine: '1.2.3' | |
60cfd4cb C |
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, | |
c0e8b12e | 169 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 |
60cfd4cb C |
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, | |
c0e8b12e | 179 | expectedStatus: HttpStatusCode.FORBIDDEN_403 |
60cfd4cb C |
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 () { | |
6c5065a0 | 196 | const query = { ...baseQuery, pluginType: 5 } |
60cfd4cb C |
197 | |
198 | await makeGetRequest({ | |
199 | url: server.url, | |
200 | path, | |
201 | token: server.accessToken, | |
202 | query | |
203 | }) | |
204 | }) | |
205 | ||
09071200 | 206 | it('Should fail with an invalid current peertube engine', async function () { |
6c5065a0 | 207 | const query = { ...baseQuery, currentPeerTubeEngine: '1.0' } |
09071200 C |
208 | |
209 | await makeGetRequest({ | |
210 | url: server.url, | |
211 | path, | |
212 | token: server.accessToken, | |
213 | query | |
214 | }) | |
215 | }) | |
216 | ||
60cfd4cb C |
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, | |
c0e8b12e | 223 | expectedStatus: HttpStatusCode.OK_200 |
60cfd4cb C |
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, | |
c0e8b12e | 240 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 |
60cfd4cb C |
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, | |
c0e8b12e | 250 | expectedStatus: HttpStatusCode.FORBIDDEN_403 |
60cfd4cb C |
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 () { | |
6c5065a0 | 267 | const query = { ...baseQuery, pluginType: 5 } |
60cfd4cb C |
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, | |
c0e8b12e | 283 | expectedStatus: HttpStatusCode.OK_200 |
60cfd4cb C |
284 | }) |
285 | }) | |
286 | }) | |
287 | ||
ba211e73 | 288 | describe('When getting a plugin or the registered settings or public settings', function () { |
60cfd4cb C |
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', | |
c0e8b12e | 297 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 |
60cfd4cb C |
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, | |
c0e8b12e | 308 | expectedStatus: HttpStatusCode.FORBIDDEN_403 |
60cfd4cb C |
309 | }) |
310 | } | |
311 | }) | |
312 | ||
313 | it('Should fail with an invalid npm name', async function () { | |
ba211e73 | 314 | for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) { |
60cfd4cb C |
315 | await makeGetRequest({ |
316 | url: server.url, | |
317 | path: path + suffix, | |
318 | token: server.accessToken, | |
c0e8b12e | 319 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 |
60cfd4cb C |
320 | }) |
321 | } | |
322 | ||
ba211e73 | 323 | for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) { |
60cfd4cb C |
324 | await makeGetRequest({ |
325 | url: server.url, | |
326 | path: path + suffix, | |
327 | token: server.accessToken, | |
c0e8b12e | 328 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 |
60cfd4cb C |
329 | }) |
330 | } | |
331 | }) | |
332 | ||
333 | it('Should fail with an unknown plugin', async function () { | |
ba211e73 | 334 | for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) { |
60cfd4cb C |
335 | await makeGetRequest({ |
336 | url: server.url, | |
337 | path: path + suffix, | |
338 | token: server.accessToken, | |
c0e8b12e | 339 | expectedStatus: HttpStatusCode.NOT_FOUND_404 |
60cfd4cb C |
340 | }) |
341 | } | |
342 | }) | |
343 | ||
344 | it('Should succeed with the correct parameters', async function () { | |
ba211e73 | 345 | for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) { |
60cfd4cb C |
346 | await makeGetRequest({ |
347 | url: server.url, | |
348 | path: path + suffix, | |
349 | token: server.accessToken, | |
c0e8b12e | 350 | expectedStatus: HttpStatusCode.OK_200 |
60cfd4cb C |
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', | |
c0e8b12e | 366 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 |
60cfd4cb C |
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, | |
c0e8b12e | 376 | expectedStatus: HttpStatusCode.FORBIDDEN_403 |
60cfd4cb C |
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, | |
c0e8b12e | 386 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 |
60cfd4cb C |
387 | }) |
388 | ||
389 | await makePutBodyRequest({ | |
390 | url: server.url, | |
391 | path: path + 'peertube-plugin-TOTO/settings', | |
392 | fields: { settings }, | |
393 | token: server.accessToken, | |
c0e8b12e | 394 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 |
60cfd4cb C |
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, | |
c0e8b12e | 404 | expectedStatus: HttpStatusCode.NOT_FOUND_404 |
60cfd4cb C |
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, | |
c0e8b12e | 414 | expectedStatus: HttpStatusCode.NO_CONTENT_204 |
60cfd4cb C |
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', | |
c0e8b12e | 429 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 |
60cfd4cb C |
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, | |
c0e8b12e | 441 | expectedStatus: HttpStatusCode.FORBIDDEN_403 |
60cfd4cb C |
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, | |
c0e8b12e | 453 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 |
60cfd4cb C |
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, | |
c0e8b12e | 463 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 |
60cfd4cb C |
464 | }) |
465 | } | |
466 | }) | |
467 | ||
468 | it('Should succeed with the correct parameters', async function () { | |
9107d791 C |
469 | this.timeout(10000) |
470 | ||
60cfd4cb | 471 | const it = [ |
2d53be02 RK |
472 | { suffix: 'install', status: HttpStatusCode.OK_200 }, |
473 | { suffix: 'update', status: HttpStatusCode.OK_200 }, | |
474 | { suffix: 'uninstall', status: HttpStatusCode.NO_CONTENT_204 } | |
60cfd4cb C |
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, | |
c0e8b12e | 483 | expectedStatus: obj.status |
60cfd4cb C |
484 | }) |
485 | } | |
486 | }) | |
487 | }) | |
488 | ||
489 | after(async function () { | |
490 | await cleanupTests([ server ]) | |
491 | }) | |
492 | }) |