319 lines
9.3 KiB
TypeScript
319 lines
9.3 KiB
TypeScript
|
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination, FIXTURE_URLS } from '@server/tests/shared'
|
||
|
import { HttpStatusCode, VideoChannelSyncCreate } from '@shared/models'
|
||
|
import {
|
||
|
ChannelSyncsCommand,
|
||
|
createSingleServer,
|
||
|
makePostBodyRequest,
|
||
|
PeerTubeServer,
|
||
|
setAccessTokensToServers,
|
||
|
setDefaultVideoChannel
|
||
|
} from '@shared/server-commands'
|
||
|
|
||
|
describe('Test video channel sync API validator', () => {
|
||
|
const path = '/api/v1/video-channel-syncs'
|
||
|
let server: PeerTubeServer
|
||
|
let command: ChannelSyncsCommand
|
||
|
let rootChannelId: number
|
||
|
let rootChannelSyncId: number
|
||
|
const userInfo = {
|
||
|
accessToken: '',
|
||
|
username: 'user1',
|
||
|
id: -1,
|
||
|
channelId: -1,
|
||
|
syncId: -1
|
||
|
}
|
||
|
|
||
|
async function withChannelSyncDisabled<T> (callback: () => Promise<T>): Promise<void> {
|
||
|
try {
|
||
|
await server.config.disableChannelSync()
|
||
|
await callback()
|
||
|
} finally {
|
||
|
await server.config.enableChannelSync()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async function withMaxSyncsPerUser<T> (maxSync: number, callback: () => Promise<T>): Promise<void> {
|
||
|
const origConfig = await server.config.getCustomConfig()
|
||
|
|
||
|
await server.config.updateExistingSubConfig({
|
||
|
newConfig: {
|
||
|
import: {
|
||
|
videoChannelSynchronization: {
|
||
|
maxPerUser: maxSync
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
try {
|
||
|
await callback()
|
||
|
} finally {
|
||
|
await server.config.updateCustomConfig({ newCustomConfig: origConfig })
|
||
|
}
|
||
|
}
|
||
|
|
||
|
before(async function () {
|
||
|
this.timeout(30_000)
|
||
|
|
||
|
server = await createSingleServer(1)
|
||
|
|
||
|
await setAccessTokensToServers([ server ])
|
||
|
await setDefaultVideoChannel([ server ])
|
||
|
|
||
|
command = server.channelSyncs
|
||
|
|
||
|
rootChannelId = server.store.channel.id
|
||
|
|
||
|
{
|
||
|
userInfo.accessToken = await server.users.generateUserAndToken(userInfo.username)
|
||
|
|
||
|
const { videoChannels, id: userId } = await server.users.getMyInfo({ token: userInfo.accessToken })
|
||
|
userInfo.id = userId
|
||
|
userInfo.channelId = videoChannels[0].id
|
||
|
}
|
||
|
|
||
|
await server.config.enableChannelSync()
|
||
|
})
|
||
|
|
||
|
describe('When creating a sync', function () {
|
||
|
let baseCorrectParams: VideoChannelSyncCreate
|
||
|
|
||
|
before(function () {
|
||
|
baseCorrectParams = {
|
||
|
externalChannelUrl: FIXTURE_URLS.youtubeChannel,
|
||
|
videoChannelId: rootChannelId
|
||
|
}
|
||
|
})
|
||
|
|
||
|
it('Should fail when sync is disabled', async function () {
|
||
|
await withChannelSyncDisabled(async () => {
|
||
|
await command.create({
|
||
|
token: server.accessToken,
|
||
|
attributes: baseCorrectParams,
|
||
|
expectedStatus: HttpStatusCode.FORBIDDEN_403
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail with nothing', async function () {
|
||
|
const fields = {}
|
||
|
await makePostBodyRequest({
|
||
|
url: server.url,
|
||
|
path,
|
||
|
token: server.accessToken,
|
||
|
fields,
|
||
|
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail with no authentication', async function () {
|
||
|
await command.create({
|
||
|
token: null,
|
||
|
attributes: baseCorrectParams,
|
||
|
expectedStatus: HttpStatusCode.UNAUTHORIZED_401
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail without a target url', async function () {
|
||
|
const attributes: VideoChannelSyncCreate = {
|
||
|
...baseCorrectParams,
|
||
|
externalChannelUrl: null
|
||
|
}
|
||
|
await command.create({
|
||
|
token: server.accessToken,
|
||
|
attributes,
|
||
|
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail without a channelId', async function () {
|
||
|
const attributes: VideoChannelSyncCreate = {
|
||
|
...baseCorrectParams,
|
||
|
videoChannelId: null
|
||
|
}
|
||
|
await command.create({
|
||
|
token: server.accessToken,
|
||
|
attributes,
|
||
|
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail with a channelId refering nothing', async function () {
|
||
|
const attributes: VideoChannelSyncCreate = {
|
||
|
...baseCorrectParams,
|
||
|
videoChannelId: 42
|
||
|
}
|
||
|
await command.create({
|
||
|
token: server.accessToken,
|
||
|
attributes,
|
||
|
expectedStatus: HttpStatusCode.NOT_FOUND_404
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail to create a sync when the user does not own the channel', async function () {
|
||
|
await command.create({
|
||
|
token: userInfo.accessToken,
|
||
|
attributes: baseCorrectParams,
|
||
|
expectedStatus: HttpStatusCode.FORBIDDEN_403
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should succeed to create a sync with root and for another user\'s channel', async function () {
|
||
|
const { videoChannelSync } = await command.create({
|
||
|
token: server.accessToken,
|
||
|
attributes: {
|
||
|
...baseCorrectParams,
|
||
|
videoChannelId: userInfo.channelId
|
||
|
},
|
||
|
expectedStatus: HttpStatusCode.OK_200
|
||
|
})
|
||
|
userInfo.syncId = videoChannelSync.id
|
||
|
})
|
||
|
|
||
|
it('Should succeed with the correct parameters', async function () {
|
||
|
const { videoChannelSync } = await command.create({
|
||
|
token: server.accessToken,
|
||
|
attributes: baseCorrectParams,
|
||
|
expectedStatus: HttpStatusCode.OK_200
|
||
|
})
|
||
|
rootChannelSyncId = videoChannelSync.id
|
||
|
})
|
||
|
|
||
|
it('Should fail when the user exceeds allowed number of synchronizations', async function () {
|
||
|
await withMaxSyncsPerUser(1, async () => {
|
||
|
await command.create({
|
||
|
token: server.accessToken,
|
||
|
attributes: {
|
||
|
...baseCorrectParams,
|
||
|
videoChannelId: userInfo.channelId
|
||
|
},
|
||
|
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
|
||
|
describe('When listing my channel syncs', function () {
|
||
|
const myPath = '/api/v1/accounts/root/video-channel-syncs'
|
||
|
|
||
|
it('Should fail with a bad start pagination', async function () {
|
||
|
await checkBadStartPagination(server.url, myPath, server.accessToken)
|
||
|
})
|
||
|
|
||
|
it('Should fail with a bad count pagination', async function () {
|
||
|
await checkBadCountPagination(server.url, myPath, server.accessToken)
|
||
|
})
|
||
|
|
||
|
it('Should fail with an incorrect sort', async function () {
|
||
|
await checkBadSortPagination(server.url, myPath, server.accessToken)
|
||
|
})
|
||
|
|
||
|
it('Should succeed with the correct parameters', async function () {
|
||
|
await command.listByAccount({
|
||
|
accountName: 'root',
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.OK_200
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail with no authentication', async function () {
|
||
|
await command.listByAccount({
|
||
|
accountName: 'root',
|
||
|
token: null,
|
||
|
expectedStatus: HttpStatusCode.UNAUTHORIZED_401
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail when a simple user lists another user\'s synchronizations', async function () {
|
||
|
await command.listByAccount({
|
||
|
accountName: 'root',
|
||
|
token: userInfo.accessToken,
|
||
|
expectedStatus: HttpStatusCode.FORBIDDEN_403
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should succeed when root lists another user\'s synchronizations', async function () {
|
||
|
await command.listByAccount({
|
||
|
accountName: userInfo.username,
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.OK_200
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should succeed even with synchronization disabled', async function () {
|
||
|
await withChannelSyncDisabled(async function () {
|
||
|
await command.listByAccount({
|
||
|
accountName: 'root',
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.OK_200
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
|
||
|
describe('When triggering deletion', function () {
|
||
|
it('should fail with no authentication', async function () {
|
||
|
await command.delete({
|
||
|
channelSyncId: userInfo.syncId,
|
||
|
token: null,
|
||
|
expectedStatus: HttpStatusCode.UNAUTHORIZED_401
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail when channelSyncId does not refer to any sync', async function () {
|
||
|
await command.delete({
|
||
|
channelSyncId: 42,
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.NOT_FOUND_404
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should fail when sync is not owned by the user', async function () {
|
||
|
await command.delete({
|
||
|
channelSyncId: rootChannelSyncId,
|
||
|
token: userInfo.accessToken,
|
||
|
expectedStatus: HttpStatusCode.FORBIDDEN_403
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should succeed when root delete a sync they do not own', async function () {
|
||
|
await command.delete({
|
||
|
channelSyncId: userInfo.syncId,
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.NO_CONTENT_204
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('should succeed when user delete a sync they own', async function () {
|
||
|
const { videoChannelSync } = await command.create({
|
||
|
attributes: {
|
||
|
externalChannelUrl: FIXTURE_URLS.youtubeChannel,
|
||
|
videoChannelId: userInfo.channelId
|
||
|
},
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.OK_200
|
||
|
})
|
||
|
|
||
|
await command.delete({
|
||
|
channelSyncId: videoChannelSync.id,
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.NO_CONTENT_204
|
||
|
})
|
||
|
})
|
||
|
|
||
|
it('Should succeed even when synchronization is disabled', async function () {
|
||
|
await withChannelSyncDisabled(async function () {
|
||
|
await command.delete({
|
||
|
channelSyncId: rootChannelSyncId,
|
||
|
token: server.accessToken,
|
||
|
expectedStatus: HttpStatusCode.NO_CONTENT_204
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
|
||
|
after(async function () {
|
||
|
await server?.kill()
|
||
|
})
|
||
|
})
|