diff options
author | Chocobozzz <me@florianbigard.com> | 2023-07-31 14:34:36 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2023-08-11 15:02:33 +0200 |
commit | 3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch) | |
tree | e4510b39bdac9c318fdb4b47018d08f15368b8f0 /packages/tests/src/api/check-params/redundancy.ts | |
parent | 04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff) | |
download | PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip |
Migrate server to ESM
Sorry for the very big commit that may lead to git log issues and merge
conflicts, but it's a major step forward:
* Server can be faster at startup because imports() are async and we can
easily lazy import big modules
* Angular doesn't seem to support ES import (with .js extension), so we
had to correctly organize peertube into a monorepo:
* Use yarn workspace feature
* Use typescript reference projects for dependencies
* Shared projects have been moved into "packages", each one is now a
node module (with a dedicated package.json/tsconfig.json)
* server/tools have been moved into apps/ and is now a dedicated app
bundled and published on NPM so users don't have to build peertube
cli tools manually
* server/tests have been moved into packages/ so we don't compile
them every time we want to run the server
* Use isolatedModule option:
* Had to move from const enum to const
(https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums)
* Had to explictely specify "type" imports when used in decorators
* Prefer tsx (that uses esbuild under the hood) instead of ts-node to
load typescript files (tests with mocha or scripts):
* To reduce test complexity as esbuild doesn't support decorator
metadata, we only test server files that do not import server
models
* We still build tests files into js files for a faster CI
* Remove unmaintained peertube CLI import script
* Removed some barrels to speed up execution (less imports)
Diffstat (limited to 'packages/tests/src/api/check-params/redundancy.ts')
-rw-r--r-- | packages/tests/src/api/check-params/redundancy.ts | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/packages/tests/src/api/check-params/redundancy.ts b/packages/tests/src/api/check-params/redundancy.ts new file mode 100644 index 000000000..16a5d0a3d --- /dev/null +++ b/packages/tests/src/api/check-params/redundancy.ts | |||
@@ -0,0 +1,240 @@ | |||
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, VideoCreateResult } from '@peertube/peertube-models' | ||
5 | import { | ||
6 | cleanupTests, | ||
7 | createMultipleServers, | ||
8 | doubleFollow, | ||
9 | makeDeleteRequest, | ||
10 | makeGetRequest, | ||
11 | makePostBodyRequest, | ||
12 | makePutBodyRequest, | ||
13 | PeerTubeServer, | ||
14 | setAccessTokensToServers, | ||
15 | waitJobs | ||
16 | } from '@peertube/peertube-server-commands' | ||
17 | |||
18 | describe('Test server redundancy API validators', function () { | ||
19 | let servers: PeerTubeServer[] | ||
20 | let userAccessToken = null | ||
21 | let videoIdLocal: number | ||
22 | let videoRemote: VideoCreateResult | ||
23 | |||
24 | // --------------------------------------------------------------- | ||
25 | |||
26 | before(async function () { | ||
27 | this.timeout(160000) | ||
28 | |||
29 | servers = await createMultipleServers(2) | ||
30 | |||
31 | await setAccessTokensToServers(servers) | ||
32 | await doubleFollow(servers[0], servers[1]) | ||
33 | |||
34 | const user = { | ||
35 | username: 'user1', | ||
36 | password: 'password' | ||
37 | } | ||
38 | |||
39 | await servers[0].users.create({ username: user.username, password: user.password }) | ||
40 | userAccessToken = await servers[0].login.getAccessToken(user) | ||
41 | |||
42 | videoIdLocal = (await servers[0].videos.quickUpload({ name: 'video' })).id | ||
43 | |||
44 | const remoteUUID = (await servers[1].videos.quickUpload({ name: 'video' })).uuid | ||
45 | |||
46 | await waitJobs(servers) | ||
47 | |||
48 | videoRemote = await servers[0].videos.get({ id: remoteUUID }) | ||
49 | }) | ||
50 | |||
51 | describe('When listing redundancies', function () { | ||
52 | const path = '/api/v1/server/redundancy/videos' | ||
53 | |||
54 | let url: string | ||
55 | let token: string | ||
56 | |||
57 | before(function () { | ||
58 | url = servers[0].url | ||
59 | token = servers[0].accessToken | ||
60 | }) | ||
61 | |||
62 | it('Should fail with an invalid token', async function () { | ||
63 | await makeGetRequest({ url, path, token: 'fake_token', expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
64 | }) | ||
65 | |||
66 | it('Should fail if the user is not an administrator', async function () { | ||
67 | await makeGetRequest({ url, path, token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
68 | }) | ||
69 | |||
70 | it('Should fail with a bad start pagination', async function () { | ||
71 | await checkBadStartPagination(url, path, servers[0].accessToken) | ||
72 | }) | ||
73 | |||
74 | it('Should fail with a bad count pagination', async function () { | ||
75 | await checkBadCountPagination(url, path, servers[0].accessToken) | ||
76 | }) | ||
77 | |||
78 | it('Should fail with an incorrect sort', async function () { | ||
79 | await checkBadSortPagination(url, path, servers[0].accessToken) | ||
80 | }) | ||
81 | |||
82 | it('Should fail with a bad target', async function () { | ||
83 | await makeGetRequest({ url, path, token, query: { target: 'bad target' } }) | ||
84 | }) | ||
85 | |||
86 | it('Should fail without target', async function () { | ||
87 | await makeGetRequest({ url, path, token }) | ||
88 | }) | ||
89 | |||
90 | it('Should succeed with the correct params', async function () { | ||
91 | await makeGetRequest({ url, path, token, query: { target: 'my-videos' }, expectedStatus: HttpStatusCode.OK_200 }) | ||
92 | }) | ||
93 | }) | ||
94 | |||
95 | describe('When manually adding a redundancy', function () { | ||
96 | const path = '/api/v1/server/redundancy/videos' | ||
97 | |||
98 | let url: string | ||
99 | let token: string | ||
100 | |||
101 | before(function () { | ||
102 | url = servers[0].url | ||
103 | token = servers[0].accessToken | ||
104 | }) | ||
105 | |||
106 | it('Should fail with an invalid token', async function () { | ||
107 | await makePostBodyRequest({ url, path, token: 'fake_token', expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
108 | }) | ||
109 | |||
110 | it('Should fail if the user is not an administrator', async function () { | ||
111 | await makePostBodyRequest({ url, path, token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
112 | }) | ||
113 | |||
114 | it('Should fail without a video id', async function () { | ||
115 | await makePostBodyRequest({ url, path, token }) | ||
116 | }) | ||
117 | |||
118 | it('Should fail with an incorrect video id', async function () { | ||
119 | await makePostBodyRequest({ url, path, token, fields: { videoId: 'peertube' } }) | ||
120 | }) | ||
121 | |||
122 | it('Should fail with a not found video id', async function () { | ||
123 | await makePostBodyRequest({ url, path, token, fields: { videoId: 6565 }, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
124 | }) | ||
125 | |||
126 | it('Should fail with a local a video id', async function () { | ||
127 | await makePostBodyRequest({ url, path, token, fields: { videoId: videoIdLocal } }) | ||
128 | }) | ||
129 | |||
130 | it('Should succeed with the correct params', async function () { | ||
131 | await makePostBodyRequest({ | ||
132 | url, | ||
133 | path, | ||
134 | token, | ||
135 | fields: { videoId: videoRemote.shortUUID }, | ||
136 | expectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
137 | }) | ||
138 | }) | ||
139 | |||
140 | it('Should fail if the video is already duplicated', async function () { | ||
141 | this.timeout(30000) | ||
142 | |||
143 | await waitJobs(servers) | ||
144 | |||
145 | await makePostBodyRequest({ | ||
146 | url, | ||
147 | path, | ||
148 | token, | ||
149 | fields: { videoId: videoRemote.uuid }, | ||
150 | expectedStatus: HttpStatusCode.CONFLICT_409 | ||
151 | }) | ||
152 | }) | ||
153 | }) | ||
154 | |||
155 | describe('When manually removing a redundancy', function () { | ||
156 | const path = '/api/v1/server/redundancy/videos/' | ||
157 | |||
158 | let url: string | ||
159 | let token: string | ||
160 | |||
161 | before(function () { | ||
162 | url = servers[0].url | ||
163 | token = servers[0].accessToken | ||
164 | }) | ||
165 | |||
166 | it('Should fail with an invalid token', async function () { | ||
167 | await makeDeleteRequest({ url, path: path + '1', token: 'fake_token', expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
168 | }) | ||
169 | |||
170 | it('Should fail if the user is not an administrator', async function () { | ||
171 | await makeDeleteRequest({ url, path: path + '1', token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
172 | }) | ||
173 | |||
174 | it('Should fail with an incorrect video id', async function () { | ||
175 | await makeDeleteRequest({ url, path: path + 'toto', token }) | ||
176 | }) | ||
177 | |||
178 | it('Should fail with a not found video redundancy', async function () { | ||
179 | await makeDeleteRequest({ url, path: path + '454545', token, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
180 | }) | ||
181 | }) | ||
182 | |||
183 | describe('When updating server redundancy', function () { | ||
184 | const path = '/api/v1/server/redundancy' | ||
185 | |||
186 | it('Should fail with an invalid token', async function () { | ||
187 | await makePutBodyRequest({ | ||
188 | url: servers[0].url, | ||
189 | path: path + '/' + servers[1].host, | ||
190 | fields: { redundancyAllowed: true }, | ||
191 | token: 'fake_token', | ||
192 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 | ||
193 | }) | ||
194 | }) | ||
195 | |||
196 | it('Should fail if the user is not an administrator', async function () { | ||
197 | await makePutBodyRequest({ | ||
198 | url: servers[0].url, | ||
199 | path: path + '/' + servers[1].host, | ||
200 | fields: { redundancyAllowed: true }, | ||
201 | token: userAccessToken, | ||
202 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
203 | }) | ||
204 | }) | ||
205 | |||
206 | it('Should fail if we do not follow this server', async function () { | ||
207 | await makePutBodyRequest({ | ||
208 | url: servers[0].url, | ||
209 | path: path + '/example.com', | ||
210 | fields: { redundancyAllowed: true }, | ||
211 | token: servers[0].accessToken, | ||
212 | expectedStatus: HttpStatusCode.NOT_FOUND_404 | ||
213 | }) | ||
214 | }) | ||
215 | |||
216 | it('Should fail without de redundancyAllowed param', async function () { | ||
217 | await makePutBodyRequest({ | ||
218 | url: servers[0].url, | ||
219 | path: path + '/' + servers[1].host, | ||
220 | fields: { blabla: true }, | ||
221 | token: servers[0].accessToken, | ||
222 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
223 | }) | ||
224 | }) | ||
225 | |||
226 | it('Should succeed with the correct parameters', async function () { | ||
227 | await makePutBodyRequest({ | ||
228 | url: servers[0].url, | ||
229 | path: path + '/' + servers[1].host, | ||
230 | fields: { redundancyAllowed: true }, | ||
231 | token: servers[0].accessToken, | ||
232 | expectedStatus: HttpStatusCode.NO_CONTENT_204 | ||
233 | }) | ||
234 | }) | ||
235 | }) | ||
236 | |||
237 | after(async function () { | ||
238 | await cleanupTests(servers) | ||
239 | }) | ||
240 | }) | ||