1 import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination, FIXTURE_URLS } from '@server/tests/shared'
2 import { HttpStatusCode, VideoChannelSyncCreate } from '@shared/models'
8 setAccessTokensToServers,
10 } from '@shared/server-commands'
12 describe('Test video channel sync API validator', () => {
13 const path = '/api/v1/video-channel-syncs'
14 let server: PeerTubeServer
15 let command: ChannelSyncsCommand
16 let rootChannelId: number
17 let rootChannelSyncId: number
26 async function withChannelSyncDisabled<T> (callback: () => Promise<T>): Promise<void> {
28 await server.config.disableChannelSync()
31 await server.config.enableChannelSync()
35 async function withMaxSyncsPerUser<T> (maxSync: number, callback: () => Promise<T>): Promise<void> {
36 const origConfig = await server.config.getCustomConfig()
38 await server.config.updateExistingSubConfig({
41 videoChannelSynchronization: {
51 await server.config.updateCustomConfig({ newCustomConfig: origConfig })
55 before(async function () {
58 server = await createSingleServer(1)
60 await setAccessTokensToServers([ server ])
61 await setDefaultVideoChannel([ server ])
63 command = server.channelSyncs
65 rootChannelId = server.store.channel.id
68 userInfo.accessToken = await server.users.generateUserAndToken(userInfo.username)
70 const { videoChannels, id: userId } = await server.users.getMyInfo({ token: userInfo.accessToken })
72 userInfo.channelId = videoChannels[0].id
75 await server.config.enableChannelSync()
78 describe('When creating a sync', function () {
79 let baseCorrectParams: VideoChannelSyncCreate
83 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
84 videoChannelId: rootChannelId
88 it('Should fail when sync is disabled', async function () {
89 await withChannelSyncDisabled(async () => {
90 await command.create({
91 token: server.accessToken,
92 attributes: baseCorrectParams,
93 expectedStatus: HttpStatusCode.FORBIDDEN_403
98 it('Should fail with nothing', async function () {
100 await makePostBodyRequest({
103 token: server.accessToken,
105 expectedStatus: HttpStatusCode.BAD_REQUEST_400
109 it('Should fail with no authentication', async function () {
110 await command.create({
112 attributes: baseCorrectParams,
113 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
117 it('Should fail without a target url', async function () {
118 const attributes: VideoChannelSyncCreate = {
119 ...baseCorrectParams,
120 externalChannelUrl: null
122 await command.create({
123 token: server.accessToken,
125 expectedStatus: HttpStatusCode.BAD_REQUEST_400
129 it('Should fail without a channelId', async function () {
130 const attributes: VideoChannelSyncCreate = {
131 ...baseCorrectParams,
134 await command.create({
135 token: server.accessToken,
137 expectedStatus: HttpStatusCode.BAD_REQUEST_400
141 it('Should fail with a channelId refering nothing', async function () {
142 const attributes: VideoChannelSyncCreate = {
143 ...baseCorrectParams,
146 await command.create({
147 token: server.accessToken,
149 expectedStatus: HttpStatusCode.NOT_FOUND_404
153 it('Should fail to create a sync when the user does not own the channel', async function () {
154 await command.create({
155 token: userInfo.accessToken,
156 attributes: baseCorrectParams,
157 expectedStatus: HttpStatusCode.FORBIDDEN_403
161 it('Should succeed to create a sync with root and for another user\'s channel', async function () {
162 const { videoChannelSync } = await command.create({
163 token: server.accessToken,
165 ...baseCorrectParams,
166 videoChannelId: userInfo.channelId
168 expectedStatus: HttpStatusCode.OK_200
170 userInfo.syncId = videoChannelSync.id
173 it('Should succeed with the correct parameters', async function () {
174 const { videoChannelSync } = await command.create({
175 token: server.accessToken,
176 attributes: baseCorrectParams,
177 expectedStatus: HttpStatusCode.OK_200
179 rootChannelSyncId = videoChannelSync.id
182 it('Should fail when the user exceeds allowed number of synchronizations', async function () {
183 await withMaxSyncsPerUser(1, async () => {
184 await command.create({
185 token: server.accessToken,
187 ...baseCorrectParams,
188 videoChannelId: userInfo.channelId
190 expectedStatus: HttpStatusCode.BAD_REQUEST_400
196 describe('When listing my channel syncs', function () {
197 const myPath = '/api/v1/accounts/root/video-channel-syncs'
199 it('Should fail with a bad start pagination', async function () {
200 await checkBadStartPagination(server.url, myPath, server.accessToken)
203 it('Should fail with a bad count pagination', async function () {
204 await checkBadCountPagination(server.url, myPath, server.accessToken)
207 it('Should fail with an incorrect sort', async function () {
208 await checkBadSortPagination(server.url, myPath, server.accessToken)
211 it('Should succeed with the correct parameters', async function () {
212 await command.listByAccount({
214 token: server.accessToken,
215 expectedStatus: HttpStatusCode.OK_200
219 it('Should fail with no authentication', async function () {
220 await command.listByAccount({
223 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
227 it('Should fail when a simple user lists another user\'s synchronizations', async function () {
228 await command.listByAccount({
230 token: userInfo.accessToken,
231 expectedStatus: HttpStatusCode.FORBIDDEN_403
235 it('Should succeed when root lists another user\'s synchronizations', async function () {
236 await command.listByAccount({
237 accountName: userInfo.username,
238 token: server.accessToken,
239 expectedStatus: HttpStatusCode.OK_200
243 it('Should succeed even with synchronization disabled', async function () {
244 await withChannelSyncDisabled(async function () {
245 await command.listByAccount({
247 token: server.accessToken,
248 expectedStatus: HttpStatusCode.OK_200
254 describe('When triggering deletion', function () {
255 it('should fail with no authentication', async function () {
256 await command.delete({
257 channelSyncId: userInfo.syncId,
259 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
263 it('Should fail when channelSyncId does not refer to any sync', async function () {
264 await command.delete({
266 token: server.accessToken,
267 expectedStatus: HttpStatusCode.NOT_FOUND_404
271 it('Should fail when sync is not owned by the user', async function () {
272 await command.delete({
273 channelSyncId: rootChannelSyncId,
274 token: userInfo.accessToken,
275 expectedStatus: HttpStatusCode.FORBIDDEN_403
279 it('Should succeed when root delete a sync they do not own', async function () {
280 await command.delete({
281 channelSyncId: userInfo.syncId,
282 token: server.accessToken,
283 expectedStatus: HttpStatusCode.NO_CONTENT_204
287 it('should succeed when user delete a sync they own', async function () {
288 const { videoChannelSync } = await command.create({
290 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
291 videoChannelId: userInfo.channelId
293 token: server.accessToken,
294 expectedStatus: HttpStatusCode.OK_200
297 await command.delete({
298 channelSyncId: videoChannelSync.id,
299 token: server.accessToken,
300 expectedStatus: HttpStatusCode.NO_CONTENT_204
304 it('Should succeed even when synchronization is disabled', async function () {
305 await withChannelSyncDisabled(async function () {
306 await command.delete({
307 channelSyncId: rootChannelSyncId,
308 token: server.accessToken,
309 expectedStatus: HttpStatusCode.NO_CONTENT_204
315 after(async function () {