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/channel-import-videos.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/channel-import-videos.ts')
-rw-r--r-- | packages/tests/src/api/check-params/channel-import-videos.ts | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/packages/tests/src/api/check-params/channel-import-videos.ts b/packages/tests/src/api/check-params/channel-import-videos.ts new file mode 100644 index 000000000..0e897dad7 --- /dev/null +++ b/packages/tests/src/api/check-params/channel-import-videos.ts | |||
@@ -0,0 +1,209 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { FIXTURE_URLS } from '@tests/shared/tests.js' | ||
4 | import { areHttpImportTestsDisabled } from '@peertube/peertube-node-utils' | ||
5 | import { HttpStatusCode } from '@peertube/peertube-models' | ||
6 | import { | ||
7 | ChannelsCommand, | ||
8 | cleanupTests, | ||
9 | createSingleServer, | ||
10 | PeerTubeServer, | ||
11 | setAccessTokensToServers, | ||
12 | setDefaultVideoChannel | ||
13 | } from '@peertube/peertube-server-commands' | ||
14 | |||
15 | describe('Test videos import in a channel API validator', function () { | ||
16 | let server: PeerTubeServer | ||
17 | const userInfo = { | ||
18 | accessToken: '', | ||
19 | channelName: 'fake_channel', | ||
20 | channelId: -1, | ||
21 | id: -1, | ||
22 | videoQuota: -1, | ||
23 | videoQuotaDaily: -1, | ||
24 | channelSyncId: -1 | ||
25 | } | ||
26 | let command: ChannelsCommand | ||
27 | |||
28 | // --------------------------------------------------------------- | ||
29 | |||
30 | before(async function () { | ||
31 | this.timeout(120000) | ||
32 | |||
33 | server = await createSingleServer(1) | ||
34 | |||
35 | await setAccessTokensToServers([ server ]) | ||
36 | await setDefaultVideoChannel([ server ]) | ||
37 | |||
38 | await server.config.enableImports() | ||
39 | await server.config.enableChannelSync() | ||
40 | |||
41 | const userCreds = { | ||
42 | username: 'fake', | ||
43 | password: 'fake_password' | ||
44 | } | ||
45 | |||
46 | { | ||
47 | const user = await server.users.create({ username: userCreds.username, password: userCreds.password }) | ||
48 | userInfo.id = user.id | ||
49 | userInfo.accessToken = await server.login.getAccessToken(userCreds) | ||
50 | |||
51 | const info = await server.users.getMyInfo({ token: userInfo.accessToken }) | ||
52 | userInfo.channelId = info.videoChannels[0].id | ||
53 | } | ||
54 | |||
55 | { | ||
56 | const { videoChannelSync } = await server.channelSyncs.create({ | ||
57 | token: userInfo.accessToken, | ||
58 | attributes: { | ||
59 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
60 | videoChannelId: userInfo.channelId | ||
61 | } | ||
62 | }) | ||
63 | userInfo.channelSyncId = videoChannelSync.id | ||
64 | } | ||
65 | |||
66 | command = server.channels | ||
67 | }) | ||
68 | |||
69 | it('Should fail when HTTP upload is disabled', async function () { | ||
70 | await server.config.disableChannelSync() | ||
71 | await server.config.disableImports() | ||
72 | |||
73 | await command.importVideos({ | ||
74 | channelName: server.store.channel.name, | ||
75 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
76 | token: server.accessToken, | ||
77 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
78 | }) | ||
79 | |||
80 | await server.config.enableImports() | ||
81 | }) | ||
82 | |||
83 | it('Should fail when externalChannelUrl is not provided', async function () { | ||
84 | await command.importVideos({ | ||
85 | channelName: server.store.channel.name, | ||
86 | externalChannelUrl: null, | ||
87 | token: server.accessToken, | ||
88 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
89 | }) | ||
90 | }) | ||
91 | |||
92 | it('Should fail when externalChannelUrl is malformed', async function () { | ||
93 | await command.importVideos({ | ||
94 | channelName: server.store.channel.name, | ||
95 | externalChannelUrl: 'not-a-url', | ||
96 | token: server.accessToken, | ||
97 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
98 | }) | ||
99 | }) | ||
100 | |||
101 | it('Should fail with a bad sync id', async function () { | ||
102 | await command.importVideos({ | ||
103 | channelName: server.store.channel.name, | ||
104 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
105 | videoChannelSyncId: 'toto' as any, | ||
106 | token: server.accessToken, | ||
107 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
108 | }) | ||
109 | }) | ||
110 | |||
111 | it('Should fail with a unknown sync id', async function () { | ||
112 | await command.importVideos({ | ||
113 | channelName: server.store.channel.name, | ||
114 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
115 | videoChannelSyncId: 42, | ||
116 | token: server.accessToken, | ||
117 | expectedStatus: HttpStatusCode.NOT_FOUND_404 | ||
118 | }) | ||
119 | }) | ||
120 | |||
121 | it('Should fail with a sync id of another channel', async function () { | ||
122 | await command.importVideos({ | ||
123 | channelName: server.store.channel.name, | ||
124 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
125 | videoChannelSyncId: userInfo.channelSyncId, | ||
126 | token: server.accessToken, | ||
127 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
128 | }) | ||
129 | }) | ||
130 | |||
131 | it('Should fail with no authentication', async function () { | ||
132 | await command.importVideos({ | ||
133 | channelName: server.store.channel.name, | ||
134 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
135 | token: null, | ||
136 | expectedStatus: HttpStatusCode.UNAUTHORIZED_401 | ||
137 | }) | ||
138 | }) | ||
139 | |||
140 | it('Should fail when sync is not owned by the user', async function () { | ||
141 | await command.importVideos({ | ||
142 | channelName: server.store.channel.name, | ||
143 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
144 | token: userInfo.accessToken, | ||
145 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
146 | }) | ||
147 | }) | ||
148 | |||
149 | it('Should fail when the user has no quota', async function () { | ||
150 | await server.users.update({ | ||
151 | userId: userInfo.id, | ||
152 | videoQuota: 0 | ||
153 | }) | ||
154 | |||
155 | await command.importVideos({ | ||
156 | channelName: 'fake_channel', | ||
157 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
158 | token: userInfo.accessToken, | ||
159 | expectedStatus: HttpStatusCode.PAYLOAD_TOO_LARGE_413 | ||
160 | }) | ||
161 | |||
162 | await server.users.update({ | ||
163 | userId: userInfo.id, | ||
164 | videoQuota: userInfo.videoQuota | ||
165 | }) | ||
166 | }) | ||
167 | |||
168 | it('Should fail when the user has no daily quota', async function () { | ||
169 | await server.users.update({ | ||
170 | userId: userInfo.id, | ||
171 | videoQuotaDaily: 0 | ||
172 | }) | ||
173 | |||
174 | await command.importVideos({ | ||
175 | channelName: 'fake_channel', | ||
176 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
177 | token: userInfo.accessToken, | ||
178 | expectedStatus: HttpStatusCode.PAYLOAD_TOO_LARGE_413 | ||
179 | }) | ||
180 | |||
181 | await server.users.update({ | ||
182 | userId: userInfo.id, | ||
183 | videoQuotaDaily: userInfo.videoQuotaDaily | ||
184 | }) | ||
185 | }) | ||
186 | |||
187 | it('Should succeed when sync is run by its owner', async function () { | ||
188 | if (!areHttpImportTestsDisabled()) return | ||
189 | |||
190 | await command.importVideos({ | ||
191 | channelName: 'fake_channel', | ||
192 | externalChannelUrl: FIXTURE_URLS.youtubeChannel, | ||
193 | token: userInfo.accessToken | ||
194 | }) | ||
195 | }) | ||
196 | |||
197 | it('Should succeed when sync is run with root and for another user\'s channel', async function () { | ||
198 | if (!areHttpImportTestsDisabled()) return | ||
199 | |||
200 | await command.importVideos({ | ||
201 | channelName: 'fake_channel', | ||
202 | externalChannelUrl: FIXTURE_URLS.youtubeChannel | ||
203 | }) | ||
204 | }) | ||
205 | |||
206 | after(async function () { | ||
207 | await cleanupTests([ server ]) | ||
208 | }) | ||
209 | }) | ||