aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/tests/src/api/check-params/video-channel-syncs.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/tests/src/api/check-params/video-channel-syncs.ts')
-rw-r--r--packages/tests/src/api/check-params/video-channel-syncs.ts319
1 files changed, 319 insertions, 0 deletions
diff --git a/packages/tests/src/api/check-params/video-channel-syncs.ts b/packages/tests/src/api/check-params/video-channel-syncs.ts
new file mode 100644
index 000000000..d95f3319a
--- /dev/null
+++ b/packages/tests/src/api/check-params/video-channel-syncs.ts
@@ -0,0 +1,319 @@
1import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@tests/shared/checks.js'
2import { FIXTURE_URLS } from '@tests/shared/tests.js'
3import { HttpStatusCode, VideoChannelSyncCreate } from '@peertube/peertube-models'
4import {
5 ChannelSyncsCommand,
6 createSingleServer,
7 makePostBodyRequest,
8 PeerTubeServer,
9 setAccessTokensToServers,
10 setDefaultVideoChannel
11} from '@peertube/peertube-server-commands'
12
13describe('Test video channel sync API validator', () => {
14 const path = '/api/v1/video-channel-syncs'
15 let server: PeerTubeServer
16 let command: ChannelSyncsCommand
17 let rootChannelId: number
18 let rootChannelSyncId: number
19 const userInfo = {
20 accessToken: '',
21 username: 'user1',
22 id: -1,
23 channelId: -1,
24 syncId: -1
25 }
26
27 async function withChannelSyncDisabled<T> (callback: () => Promise<T>): Promise<void> {
28 try {
29 await server.config.disableChannelSync()
30 await callback()
31 } finally {
32 await server.config.enableChannelSync()
33 }
34 }
35
36 async function withMaxSyncsPerUser<T> (maxSync: number, callback: () => Promise<T>): Promise<void> {
37 const origConfig = await server.config.getCustomConfig()
38
39 await server.config.updateExistingSubConfig({
40 newConfig: {
41 import: {
42 videoChannelSynchronization: {
43 maxPerUser: maxSync
44 }
45 }
46 }
47 })
48
49 try {
50 await callback()
51 } finally {
52 await server.config.updateCustomConfig({ newCustomConfig: origConfig })
53 }
54 }
55
56 before(async function () {
57 this.timeout(30_000)
58
59 server = await createSingleServer(1)
60
61 await setAccessTokensToServers([ server ])
62 await setDefaultVideoChannel([ server ])
63
64 command = server.channelSyncs
65
66 rootChannelId = server.store.channel.id
67
68 {
69 userInfo.accessToken = await server.users.generateUserAndToken(userInfo.username)
70
71 const { videoChannels, id: userId } = await server.users.getMyInfo({ token: userInfo.accessToken })
72 userInfo.id = userId
73 userInfo.channelId = videoChannels[0].id
74 }
75
76 await server.config.enableChannelSync()
77 })
78
79 describe('When creating a sync', function () {
80 let baseCorrectParams: VideoChannelSyncCreate
81
82 before(function () {
83 baseCorrectParams = {
84 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
85 videoChannelId: rootChannelId
86 }
87 })
88
89 it('Should fail when sync is disabled', async function () {
90 await withChannelSyncDisabled(async () => {
91 await command.create({
92 token: server.accessToken,
93 attributes: baseCorrectParams,
94 expectedStatus: HttpStatusCode.FORBIDDEN_403
95 })
96 })
97 })
98
99 it('Should fail with nothing', async function () {
100 const fields = {}
101 await makePostBodyRequest({
102 url: server.url,
103 path,
104 token: server.accessToken,
105 fields,
106 expectedStatus: HttpStatusCode.BAD_REQUEST_400
107 })
108 })
109
110 it('Should fail with no authentication', async function () {
111 await command.create({
112 token: null,
113 attributes: baseCorrectParams,
114 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
115 })
116 })
117
118 it('Should fail without a target url', async function () {
119 const attributes: VideoChannelSyncCreate = {
120 ...baseCorrectParams,
121 externalChannelUrl: null
122 }
123 await command.create({
124 token: server.accessToken,
125 attributes,
126 expectedStatus: HttpStatusCode.BAD_REQUEST_400
127 })
128 })
129
130 it('Should fail without a channelId', async function () {
131 const attributes: VideoChannelSyncCreate = {
132 ...baseCorrectParams,
133 videoChannelId: null
134 }
135 await command.create({
136 token: server.accessToken,
137 attributes,
138 expectedStatus: HttpStatusCode.BAD_REQUEST_400
139 })
140 })
141
142 it('Should fail with a channelId refering nothing', async function () {
143 const attributes: VideoChannelSyncCreate = {
144 ...baseCorrectParams,
145 videoChannelId: 42
146 }
147 await command.create({
148 token: server.accessToken,
149 attributes,
150 expectedStatus: HttpStatusCode.NOT_FOUND_404
151 })
152 })
153
154 it('Should fail to create a sync when the user does not own the channel', async function () {
155 await command.create({
156 token: userInfo.accessToken,
157 attributes: baseCorrectParams,
158 expectedStatus: HttpStatusCode.FORBIDDEN_403
159 })
160 })
161
162 it('Should succeed to create a sync with root and for another user\'s channel', async function () {
163 const { videoChannelSync } = await command.create({
164 token: server.accessToken,
165 attributes: {
166 ...baseCorrectParams,
167 videoChannelId: userInfo.channelId
168 },
169 expectedStatus: HttpStatusCode.OK_200
170 })
171 userInfo.syncId = videoChannelSync.id
172 })
173
174 it('Should succeed with the correct parameters', async function () {
175 const { videoChannelSync } = await command.create({
176 token: server.accessToken,
177 attributes: baseCorrectParams,
178 expectedStatus: HttpStatusCode.OK_200
179 })
180 rootChannelSyncId = videoChannelSync.id
181 })
182
183 it('Should fail when the user exceeds allowed number of synchronizations', async function () {
184 await withMaxSyncsPerUser(1, async () => {
185 await command.create({
186 token: server.accessToken,
187 attributes: {
188 ...baseCorrectParams,
189 videoChannelId: userInfo.channelId
190 },
191 expectedStatus: HttpStatusCode.BAD_REQUEST_400
192 })
193 })
194 })
195 })
196
197 describe('When listing my channel syncs', function () {
198 const myPath = '/api/v1/accounts/root/video-channel-syncs'
199
200 it('Should fail with a bad start pagination', async function () {
201 await checkBadStartPagination(server.url, myPath, server.accessToken)
202 })
203
204 it('Should fail with a bad count pagination', async function () {
205 await checkBadCountPagination(server.url, myPath, server.accessToken)
206 })
207
208 it('Should fail with an incorrect sort', async function () {
209 await checkBadSortPagination(server.url, myPath, server.accessToken)
210 })
211
212 it('Should succeed with the correct parameters', async function () {
213 await command.listByAccount({
214 accountName: 'root',
215 token: server.accessToken,
216 expectedStatus: HttpStatusCode.OK_200
217 })
218 })
219
220 it('Should fail with no authentication', async function () {
221 await command.listByAccount({
222 accountName: 'root',
223 token: null,
224 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
225 })
226 })
227
228 it('Should fail when a simple user lists another user\'s synchronizations', async function () {
229 await command.listByAccount({
230 accountName: 'root',
231 token: userInfo.accessToken,
232 expectedStatus: HttpStatusCode.FORBIDDEN_403
233 })
234 })
235
236 it('Should succeed when root lists another user\'s synchronizations', async function () {
237 await command.listByAccount({
238 accountName: userInfo.username,
239 token: server.accessToken,
240 expectedStatus: HttpStatusCode.OK_200
241 })
242 })
243
244 it('Should succeed even with synchronization disabled', async function () {
245 await withChannelSyncDisabled(async function () {
246 await command.listByAccount({
247 accountName: 'root',
248 token: server.accessToken,
249 expectedStatus: HttpStatusCode.OK_200
250 })
251 })
252 })
253 })
254
255 describe('When triggering deletion', function () {
256 it('should fail with no authentication', async function () {
257 await command.delete({
258 channelSyncId: userInfo.syncId,
259 token: null,
260 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
261 })
262 })
263
264 it('Should fail when channelSyncId does not refer to any sync', async function () {
265 await command.delete({
266 channelSyncId: 42,
267 token: server.accessToken,
268 expectedStatus: HttpStatusCode.NOT_FOUND_404
269 })
270 })
271
272 it('Should fail when sync is not owned by the user', async function () {
273 await command.delete({
274 channelSyncId: rootChannelSyncId,
275 token: userInfo.accessToken,
276 expectedStatus: HttpStatusCode.FORBIDDEN_403
277 })
278 })
279
280 it('Should succeed when root delete a sync they do not own', async function () {
281 await command.delete({
282 channelSyncId: userInfo.syncId,
283 token: server.accessToken,
284 expectedStatus: HttpStatusCode.NO_CONTENT_204
285 })
286 })
287
288 it('should succeed when user delete a sync they own', async function () {
289 const { videoChannelSync } = await command.create({
290 attributes: {
291 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
292 videoChannelId: userInfo.channelId
293 },
294 token: server.accessToken,
295 expectedStatus: HttpStatusCode.OK_200
296 })
297
298 await command.delete({
299 channelSyncId: videoChannelSync.id,
300 token: server.accessToken,
301 expectedStatus: HttpStatusCode.NO_CONTENT_204
302 })
303 })
304
305 it('Should succeed even when synchronization is disabled', async function () {
306 await withChannelSyncDisabled(async function () {
307 await command.delete({
308 channelSyncId: rootChannelSyncId,
309 token: server.accessToken,
310 expectedStatus: HttpStatusCode.NO_CONTENT_204
311 })
312 })
313 })
314 })
315
316 after(async function () {
317 await server?.kill()
318 })
319})