Introduce playlist command
This commit is contained in:
parent
72cbfc5695
commit
e6346d59e6
|
@ -5,6 +5,7 @@ import { scheduleRefreshIfNeeded } from '@server/lib/activitypub/playlists'
|
|||
import { Hooks } from '@server/lib/plugins/hooks'
|
||||
import { getServerActor } from '@server/models/application/application'
|
||||
import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models'
|
||||
import { VideoPlaylistCreateResult, VideoPlaylistElementCreateResult } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
import { VideoPlaylistCreate } from '../../../shared/models/videos/playlist/video-playlist-create.model'
|
||||
import { VideoPlaylistElementCreate } from '../../../shared/models/videos/playlist/video-playlist-element-create.model'
|
||||
|
@ -202,7 +203,7 @@ async function addVideoPlaylist (req: express.Request, res: express.Response) {
|
|||
id: videoPlaylistCreated.id,
|
||||
shortUUID: uuidToShort(videoPlaylistCreated.uuid),
|
||||
uuid: videoPlaylistCreated.uuid
|
||||
}
|
||||
} as VideoPlaylistCreateResult
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -338,8 +339,8 @@ async function addVideoInPlaylist (req: express.Request, res: express.Response)
|
|||
return res.json({
|
||||
videoPlaylistElement: {
|
||||
id: playlistElement.id
|
||||
}
|
||||
}).end()
|
||||
} as VideoPlaylistElementCreateResult
|
||||
})
|
||||
}
|
||||
|
||||
async function updateVideoPlaylistElement (req: express.Request, res: express.Response) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import { VideoPlaylistPrivacy } from '@shared/models'
|
|||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
makeActivityPubGetRequest,
|
||||
|
@ -74,9 +73,8 @@ describe('Test activitypub', function () {
|
|||
}
|
||||
|
||||
{
|
||||
const playlistAttrs = { displayName: 'playlist', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[0].videoChannel.id }
|
||||
const resCreate = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs })
|
||||
playlist = resCreate.body.videoPlaylist
|
||||
const attributes = { displayName: 'playlist', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[0].videoChannel.id }
|
||||
playlist = await servers[0].playlistsCommand.create({ attributes })
|
||||
}
|
||||
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
|
|
|
@ -5,12 +5,10 @@ import { HttpStatusCode } from '@shared/core-utils'
|
|||
import {
|
||||
cleanupTests,
|
||||
closeAllSequelize,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
generateUserAccessToken,
|
||||
getVideo,
|
||||
getVideoPlaylist,
|
||||
killallServers,
|
||||
reRunServer,
|
||||
ServerInfo,
|
||||
|
@ -58,15 +56,15 @@ describe('Test AP refresher', function () {
|
|||
}
|
||||
|
||||
{
|
||||
const playlistAttrs = { displayName: 'playlist1', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[1].videoChannel.id }
|
||||
const res = await createVideoPlaylist({ url: servers[1].url, token: servers[1].accessToken, playlistAttrs })
|
||||
playlistUUID1 = res.body.videoPlaylist.uuid
|
||||
const attributes = { displayName: 'playlist1', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[1].videoChannel.id }
|
||||
const created = await servers[1].playlistsCommand.create({ attributes })
|
||||
playlistUUID1 = created.uuid
|
||||
}
|
||||
|
||||
{
|
||||
const playlistAttrs = { displayName: 'playlist2', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[1].videoChannel.id }
|
||||
const res = await createVideoPlaylist({ url: servers[1].url, token: servers[1].accessToken, playlistAttrs })
|
||||
playlistUUID2 = res.body.videoPlaylist.uuid
|
||||
const attributes = { displayName: 'playlist2', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[1].videoChannel.id }
|
||||
const created = await servers[1].playlistsCommand.create({ attributes })
|
||||
playlistUUID2 = created.uuid
|
||||
}
|
||||
|
||||
await doubleFollow(servers[0], servers[1])
|
||||
|
@ -144,13 +142,13 @@ describe('Test AP refresher', function () {
|
|||
// Change UUID so the remote server returns a 404
|
||||
await setPlaylistField(servers[1].internalServerNumber, playlistUUID2, 'uuid', '304afe4f-39f9-4d49-8ed7-ac57b86b178e')
|
||||
|
||||
await getVideoPlaylist(servers[0].url, playlistUUID1)
|
||||
await getVideoPlaylist(servers[0].url, playlistUUID2)
|
||||
await servers[0].playlistsCommand.get({ playlistId: playlistUUID1 })
|
||||
await servers[0].playlistsCommand.get({ playlistId: playlistUUID2 })
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
await getVideoPlaylist(servers[0].url, playlistUUID1, HttpStatusCode.OK_200)
|
||||
await getVideoPlaylist(servers[0].url, playlistUUID2, HttpStatusCode.NOT_FOUND_404)
|
||||
await servers[0].playlistsCommand.get({ playlistId: playlistUUID1, expectedStatus: HttpStatusCode.OK_200 })
|
||||
await servers[0].playlistsCommand.get({ playlistId: playlistUUID2, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
|
||||
import { VideoPlaylistPrivacy } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
cleanupTests,
|
||||
flushAndRunServer,
|
||||
makeGetRequest,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers,
|
||||
uploadVideo,
|
||||
createVideoPlaylist,
|
||||
setDefaultVideoChannel
|
||||
setDefaultVideoChannel,
|
||||
uploadVideo
|
||||
} from '../../../../shared/extra-utils'
|
||||
import { VideoPlaylistPrivacy } from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
describe('Test services API validators', function () {
|
||||
let server: ServerInfo
|
||||
|
@ -34,17 +32,15 @@ describe('Test services API validators', function () {
|
|||
}
|
||||
|
||||
{
|
||||
const res = await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
const created = await server.playlistsCommand.create({
|
||||
attributes: {
|
||||
displayName: 'super playlist',
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: server.videoChannel.id
|
||||
}
|
||||
})
|
||||
|
||||
playlistUUID = res.body.videoPlaylist.uuid
|
||||
playlistUUID = created.uuid
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import 'mocha'
|
||||
import { VideoPlaylistCreateResult, VideoPlaylistPrivacy, VideoPlaylistType } from '@shared/models'
|
||||
import {
|
||||
VideoPlaylistCreate,
|
||||
VideoPlaylistCreateResult,
|
||||
VideoPlaylistElementCreate,
|
||||
VideoPlaylistElementUpdate,
|
||||
VideoPlaylistPrivacy,
|
||||
VideoPlaylistReorder,
|
||||
VideoPlaylistType
|
||||
} from '@shared/models'
|
||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
checkBadCountPagination,
|
||||
checkBadSortPagination,
|
||||
checkBadStartPagination,
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
deleteVideoPlaylist,
|
||||
flushAndRunServer,
|
||||
generateUserAccessToken,
|
||||
getAccountPlaylistsListWithToken,
|
||||
getVideoPlaylist,
|
||||
immutableAssign,
|
||||
makeGetRequest,
|
||||
removeVideoFromPlaylist,
|
||||
reorderVideosPlaylist,
|
||||
PlaylistsCommand,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers,
|
||||
setDefaultVideoChannel,
|
||||
updateVideoPlaylist,
|
||||
updateVideoPlaylistElement,
|
||||
uploadVideoAndGetId
|
||||
} from '../../../../shared/extra-utils'
|
||||
|
||||
|
@ -36,7 +36,9 @@ describe('Test video playlists API validator', function () {
|
|||
|
||||
let watchLaterPlaylistId: number
|
||||
let videoId: number
|
||||
let playlistElementId: number
|
||||
let elementId: number
|
||||
|
||||
let command: PlaylistsCommand
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
|
@ -51,34 +53,37 @@ describe('Test video playlists API validator', function () {
|
|||
userAccessToken = await generateUserAccessToken(server, 'user1')
|
||||
videoId = (await uploadVideoAndGetId({ server, videoName: 'video 1' })).id
|
||||
|
||||
command = server.playlistsCommand
|
||||
|
||||
{
|
||||
const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER)
|
||||
watchLaterPlaylistId = res.body.data[0].id
|
||||
const { data } = await command.listByAccount({
|
||||
token: server.accessToken,
|
||||
handle: 'root',
|
||||
start: 0,
|
||||
count: 5,
|
||||
playlistType: VideoPlaylistType.WATCH_LATER
|
||||
})
|
||||
watchLaterPlaylistId = data[0].id
|
||||
}
|
||||
|
||||
{
|
||||
const res = await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
playlist = await command.create({
|
||||
attributes: {
|
||||
displayName: 'super playlist',
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: server.videoChannel.id
|
||||
}
|
||||
})
|
||||
playlist = res.body.videoPlaylist
|
||||
}
|
||||
|
||||
{
|
||||
const res = await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
const created = await command.create({
|
||||
attributes: {
|
||||
displayName: 'private',
|
||||
privacy: VideoPlaylistPrivacy.PRIVATE
|
||||
}
|
||||
})
|
||||
privatePlaylistUUID = res.body.videoPlaylist.uuid
|
||||
privatePlaylistUUID = created.uuid
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -163,47 +168,50 @@ describe('Test video playlists API validator', function () {
|
|||
|
||||
describe('When getting a video playlist', function () {
|
||||
it('Should fail with a bad id or uuid', async function () {
|
||||
await getVideoPlaylist(server.url, 'toto', HttpStatusCode.BAD_REQUEST_400)
|
||||
await command.get({ playlistId: 'toto', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
|
||||
})
|
||||
|
||||
it('Should fail with an unknown playlist', async function () {
|
||||
await getVideoPlaylist(server.url, 42, HttpStatusCode.NOT_FOUND_404)
|
||||
await command.get({ playlistId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
})
|
||||
|
||||
it('Should fail to get an unlisted playlist with the number id', async function () {
|
||||
const res = await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
const playlist = await command.create({
|
||||
attributes: {
|
||||
displayName: 'super playlist',
|
||||
videoChannelId: server.videoChannel.id,
|
||||
privacy: VideoPlaylistPrivacy.UNLISTED
|
||||
}
|
||||
})
|
||||
const playlist = res.body.videoPlaylist
|
||||
|
||||
await getVideoPlaylist(server.url, playlist.id, HttpStatusCode.NOT_FOUND_404)
|
||||
await getVideoPlaylist(server.url, playlist.uuid, HttpStatusCode.OK_200)
|
||||
await command.get({ playlistId: playlist.id, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await command.get({ playlistId: playlist.uuid, expectedStatus: HttpStatusCode.OK_200 })
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
await getVideoPlaylist(server.url, playlist.uuid, HttpStatusCode.OK_200)
|
||||
await command.get({ playlistId: playlist.uuid, expectedStatus: HttpStatusCode.OK_200 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('When creating/updating a video playlist', function () {
|
||||
const getBase = (playlistAttrs: any = {}, wrapper: any = {}) => {
|
||||
return Object.assign({
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: Object.assign({
|
||||
const getBase = (
|
||||
attributes?: Partial<VideoPlaylistCreate>,
|
||||
wrapper?: Partial<Parameters<PlaylistsCommand['create']>[0]>
|
||||
) => {
|
||||
return {
|
||||
attributes: {
|
||||
displayName: 'display name',
|
||||
privacy: VideoPlaylistPrivacy.UNLISTED,
|
||||
thumbnailfile: 'thumbnail.jpg',
|
||||
videoChannelId: server.videoChannel.id
|
||||
}, playlistAttrs)
|
||||
}, wrapper)
|
||||
videoChannelId: server.videoChannel.id,
|
||||
|
||||
...attributes
|
||||
},
|
||||
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
|
||||
...wrapper
|
||||
}
|
||||
}
|
||||
const getUpdate = (params: any, playlistId: number | string) => {
|
||||
return immutableAssign(params, { playlistId: playlistId })
|
||||
|
@ -212,86 +220,86 @@ describe('Test video playlists API validator', function () {
|
|||
it('Should fail with an unauthenticated user', async function () {
|
||||
const params = getBase({}, { token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail without displayName', async function () {
|
||||
const params = getBase({ displayName: undefined })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await command.create(params)
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect display name', async function () {
|
||||
const params = getBase({ displayName: 's'.repeat(300) })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect description', async function () {
|
||||
const params = getBase({ description: 't' })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect privacy', async function () {
|
||||
const params = getBase({ privacy: 45 })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an unknown video channel id', async function () {
|
||||
const params = getBase({ videoChannelId: 42 }, { expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an incorrect thumbnail file', async function () {
|
||||
const params = getBase({ thumbnailfile: 'video_short.mp4' })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with a thumbnail file too big', async function () {
|
||||
const params = getBase({ thumbnailfile: 'preview-big.png' })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail to set "public" a playlist not assigned to a channel', async function () {
|
||||
const params = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: undefined })
|
||||
const params2 = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: 'null' })
|
||||
const params3 = getBase({ privacy: undefined, videoChannelId: 'null' })
|
||||
const params2 = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: 'null' as any })
|
||||
const params3 = getBase({ privacy: undefined, videoChannelId: 'null' as any })
|
||||
|
||||
await createVideoPlaylist(params)
|
||||
await createVideoPlaylist(params2)
|
||||
await updateVideoPlaylist(getUpdate(params, privatePlaylistUUID))
|
||||
await updateVideoPlaylist(getUpdate(params2, playlist.shortUUID))
|
||||
await updateVideoPlaylist(getUpdate(params3, playlist.shortUUID))
|
||||
await command.create(params)
|
||||
await command.create(params2)
|
||||
await command.update(getUpdate(params, privatePlaylistUUID))
|
||||
await command.update(getUpdate(params2, playlist.shortUUID))
|
||||
await command.update(getUpdate(params3, playlist.shortUUID))
|
||||
})
|
||||
|
||||
it('Should fail with an unknown playlist to update', async function () {
|
||||
await updateVideoPlaylist(getUpdate(
|
||||
await command.update(getUpdate(
|
||||
getBase({}, { expectedStatus: HttpStatusCode.NOT_FOUND_404 }),
|
||||
42
|
||||
))
|
||||
})
|
||||
|
||||
it('Should fail to update a playlist of another user', async function () {
|
||||
await updateVideoPlaylist(getUpdate(
|
||||
await command.update(getUpdate(
|
||||
getBase({}, { token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }),
|
||||
playlist.shortUUID
|
||||
))
|
||||
})
|
||||
|
||||
it('Should fail to update the watch later playlist', async function () {
|
||||
await updateVideoPlaylist(getUpdate(
|
||||
await command.update(getUpdate(
|
||||
getBase({}, { expectedStatus: HttpStatusCode.BAD_REQUEST_400 }),
|
||||
watchLaterPlaylistId
|
||||
))
|
||||
|
@ -300,146 +308,158 @@ describe('Test video playlists API validator', function () {
|
|||
it('Should succeed with the correct params', async function () {
|
||||
{
|
||||
const params = getBase({}, { expectedStatus: HttpStatusCode.OK_200 })
|
||||
await createVideoPlaylist(params)
|
||||
await command.create(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({}, { expectedStatus: HttpStatusCode.NO_CONTENT_204 })
|
||||
await updateVideoPlaylist(getUpdate(params, playlist.shortUUID))
|
||||
await command.update(getUpdate(params, playlist.shortUUID))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('When adding an element in a playlist', function () {
|
||||
const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
|
||||
return Object.assign({
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: playlist.id,
|
||||
elementAttrs: Object.assign({
|
||||
const getBase = (
|
||||
attributes?: Partial<VideoPlaylistElementCreate>,
|
||||
wrapper?: Partial<Parameters<PlaylistsCommand['addElement']>[0]>
|
||||
) => {
|
||||
return {
|
||||
attributes: {
|
||||
videoId,
|
||||
startTimestamp: 2,
|
||||
stopTimestamp: 3
|
||||
}, elementAttrs)
|
||||
}, wrapper)
|
||||
stopTimestamp: 3,
|
||||
|
||||
...attributes
|
||||
},
|
||||
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
playlistId: playlist.id,
|
||||
|
||||
...wrapper
|
||||
}
|
||||
}
|
||||
|
||||
it('Should fail with an unauthenticated user', async function () {
|
||||
const params = getBase({}, { token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
await addVideoInPlaylist(params)
|
||||
await command.addElement(params)
|
||||
})
|
||||
|
||||
it('Should fail with the playlist of another user', async function () {
|
||||
const params = getBase({}, { token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
|
||||
await addVideoInPlaylist(params)
|
||||
await command.addElement(params)
|
||||
})
|
||||
|
||||
it('Should fail with an unknown or incorrect playlist id', async function () {
|
||||
{
|
||||
const params = getBase({}, { playlistId: 'toto' })
|
||||
await addVideoInPlaylist(params)
|
||||
await command.addElement(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({}, { playlistId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await addVideoInPlaylist(params)
|
||||
await command.addElement(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an unknown or incorrect video id', async function () {
|
||||
const params = getBase({ videoId: 42 }, { expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await addVideoInPlaylist(params)
|
||||
await command.addElement(params)
|
||||
})
|
||||
|
||||
it('Should fail with a bad start/stop timestamp', async function () {
|
||||
{
|
||||
const params = getBase({ startTimestamp: -42 })
|
||||
await addVideoInPlaylist(params)
|
||||
await command.addElement(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ stopTimestamp: 'toto' as any })
|
||||
await addVideoInPlaylist(params)
|
||||
await command.addElement(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Succeed with the correct params', async function () {
|
||||
const params = getBase({}, { expectedStatus: HttpStatusCode.OK_200 })
|
||||
const res = await addVideoInPlaylist(params)
|
||||
playlistElementId = res.body.videoPlaylistElement.id
|
||||
const created = await command.addElement(params)
|
||||
elementId = created.id
|
||||
})
|
||||
})
|
||||
|
||||
describe('When updating an element in a playlist', function () {
|
||||
const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
|
||||
return Object.assign({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
elementAttrs: Object.assign({
|
||||
const getBase = (
|
||||
attributes?: Partial<VideoPlaylistElementUpdate>,
|
||||
wrapper?: Partial<Parameters<PlaylistsCommand['updateElement']>[0]>
|
||||
) => {
|
||||
return {
|
||||
attributes: {
|
||||
startTimestamp: 1,
|
||||
stopTimestamp: 2
|
||||
}, elementAttrs),
|
||||
playlistElementId,
|
||||
stopTimestamp: 2,
|
||||
|
||||
...attributes
|
||||
},
|
||||
|
||||
elementId,
|
||||
playlistId: playlist.id,
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
}, wrapper)
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
|
||||
...wrapper
|
||||
}
|
||||
}
|
||||
|
||||
it('Should fail with an unauthenticated user', async function () {
|
||||
const params = getBase({}, { token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
await updateVideoPlaylistElement(params)
|
||||
await command.updateElement(params)
|
||||
})
|
||||
|
||||
it('Should fail with the playlist of another user', async function () {
|
||||
const params = getBase({}, { token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
|
||||
await updateVideoPlaylistElement(params)
|
||||
await command.updateElement(params)
|
||||
})
|
||||
|
||||
it('Should fail with an unknown or incorrect playlist id', async function () {
|
||||
{
|
||||
const params = getBase({}, { playlistId: 'toto' })
|
||||
await updateVideoPlaylistElement(params)
|
||||
await command.updateElement(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({}, { playlistId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await updateVideoPlaylistElement(params)
|
||||
await command.updateElement(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an unknown or incorrect playlistElement id', async function () {
|
||||
{
|
||||
const params = getBase({}, { playlistElementId: 'toto' })
|
||||
await updateVideoPlaylistElement(params)
|
||||
const params = getBase({}, { elementId: 'toto' })
|
||||
await command.updateElement(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({}, { playlistElementId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await updateVideoPlaylistElement(params)
|
||||
const params = getBase({}, { elementId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await command.updateElement(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with a bad start/stop timestamp', async function () {
|
||||
{
|
||||
const params = getBase({ startTimestamp: 'toto' as any })
|
||||
await updateVideoPlaylistElement(params)
|
||||
await command.updateElement(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ stopTimestamp: -42 })
|
||||
await updateVideoPlaylistElement(params)
|
||||
await command.updateElement(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an unknown element', async function () {
|
||||
const params = getBase({}, { playlistElementId: 888, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await updateVideoPlaylistElement(params)
|
||||
const params = getBase({}, { elementId: 888, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await command.updateElement(params)
|
||||
})
|
||||
|
||||
it('Succeed with the correct params', async function () {
|
||||
const params = getBase({}, { expectedStatus: HttpStatusCode.NO_CONTENT_204 })
|
||||
await updateVideoPlaylistElement(params)
|
||||
await command.updateElement(params)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -447,18 +467,24 @@ describe('Test video playlists API validator', function () {
|
|||
let videoId3: number
|
||||
let videoId4: number
|
||||
|
||||
const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
|
||||
return Object.assign({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: playlist.shortUUID,
|
||||
elementAttrs: Object.assign({
|
||||
const getBase = (
|
||||
attributes?: Partial<VideoPlaylistReorder>,
|
||||
wrapper?: Partial<Parameters<PlaylistsCommand['reorderElements']>[0]>
|
||||
) => {
|
||||
return {
|
||||
attributes: {
|
||||
startPosition: 1,
|
||||
insertAfterPosition: 2,
|
||||
reorderLength: 3
|
||||
}, elementAttrs),
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
}, wrapper)
|
||||
reorderLength: 3,
|
||||
|
||||
...attributes
|
||||
},
|
||||
|
||||
playlistId: playlist.shortUUID,
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
|
||||
...wrapper
|
||||
}
|
||||
}
|
||||
|
||||
before(async function () {
|
||||
|
@ -466,91 +492,86 @@ describe('Test video playlists API validator', function () {
|
|||
videoId4 = (await uploadVideoAndGetId({ server, videoName: 'video 4' })).id
|
||||
|
||||
for (const id of [ videoId3, videoId4 ]) {
|
||||
await addVideoInPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: playlist.shortUUID,
|
||||
elementAttrs: { videoId: id }
|
||||
})
|
||||
await command.addElement({ playlistId: playlist.shortUUID, attributes: { videoId: id } })
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an unauthenticated user', async function () {
|
||||
const params = getBase({}, { token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
})
|
||||
|
||||
it('Should fail with the playlist of another user', async function () {
|
||||
const params = getBase({}, { token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
})
|
||||
|
||||
it('Should fail with an invalid playlist', async function () {
|
||||
{
|
||||
const params = getBase({}, { playlistId: 'toto' })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({}, { playlistId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an invalid start position', async function () {
|
||||
{
|
||||
const params = getBase({ startPosition: -1 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ startPosition: 'toto' as any })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ startPosition: 42 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an invalid insert after position', async function () {
|
||||
{
|
||||
const params = getBase({ insertAfterPosition: 'toto' as any })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ insertAfterPosition: -2 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ insertAfterPosition: 42 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an invalid reorder length', async function () {
|
||||
{
|
||||
const params = getBase({ reorderLength: 'toto' as any })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ reorderLength: -2 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ reorderLength: 42 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Succeed with the correct params', async function () {
|
||||
const params = getBase({}, { expectedStatus: HttpStatusCode.NO_CONTENT_204 })
|
||||
await reorderVideosPlaylist(params)
|
||||
await command.reorderElements(params)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -601,76 +622,76 @@ describe('Test video playlists API validator', function () {
|
|||
})
|
||||
|
||||
describe('When deleting an element in a playlist', function () {
|
||||
const getBase = (wrapper: any = {}) => {
|
||||
return Object.assign({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistElementId,
|
||||
const getBase = (wrapper: Partial<Parameters<PlaylistsCommand['removeElement']>[0]>) => {
|
||||
return {
|
||||
elementId,
|
||||
playlistId: playlist.uuid,
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
}, wrapper)
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400,
|
||||
|
||||
...wrapper
|
||||
}
|
||||
}
|
||||
|
||||
it('Should fail with an unauthenticated user', async function () {
|
||||
const params = getBase({ token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
|
||||
await removeVideoFromPlaylist(params)
|
||||
await command.removeElement(params)
|
||||
})
|
||||
|
||||
it('Should fail with the playlist of another user', async function () {
|
||||
const params = getBase({ token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
|
||||
await removeVideoFromPlaylist(params)
|
||||
await command.removeElement(params)
|
||||
})
|
||||
|
||||
it('Should fail with an unknown or incorrect playlist id', async function () {
|
||||
{
|
||||
const params = getBase({ playlistId: 'toto' })
|
||||
await removeVideoFromPlaylist(params)
|
||||
await command.removeElement(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ playlistId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await removeVideoFromPlaylist(params)
|
||||
await command.removeElement(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an unknown or incorrect video id', async function () {
|
||||
{
|
||||
const params = getBase({ playlistElementId: 'toto' })
|
||||
await removeVideoFromPlaylist(params)
|
||||
const params = getBase({ elementId: 'toto' as any })
|
||||
await command.removeElement(params)
|
||||
}
|
||||
|
||||
{
|
||||
const params = getBase({ playlistElementId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await removeVideoFromPlaylist(params)
|
||||
const params = getBase({ elementId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await command.removeElement(params)
|
||||
}
|
||||
})
|
||||
|
||||
it('Should fail with an unknown element', async function () {
|
||||
const params = getBase({ playlistElementId: 888, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await removeVideoFromPlaylist(params)
|
||||
const params = getBase({ elementId: 888, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
await command.removeElement(params)
|
||||
})
|
||||
|
||||
it('Succeed with the correct params', async function () {
|
||||
const params = getBase({ expectedStatus: HttpStatusCode.NO_CONTENT_204 })
|
||||
await removeVideoFromPlaylist(params)
|
||||
await command.removeElement(params)
|
||||
})
|
||||
})
|
||||
|
||||
describe('When deleting a playlist', function () {
|
||||
it('Should fail with an unknown playlist', async function () {
|
||||
await deleteVideoPlaylist(server.url, server.accessToken, 42, HttpStatusCode.NOT_FOUND_404)
|
||||
await command.delete({ playlistId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||
})
|
||||
|
||||
it('Should fail with a playlist of another user', async function () {
|
||||
await deleteVideoPlaylist(server.url, userAccessToken, playlist.uuid, HttpStatusCode.FORBIDDEN_403)
|
||||
await command.delete({ token: userAccessToken, playlistId: playlist.uuid, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
|
||||
})
|
||||
|
||||
it('Should fail with the watch later playlist', async function () {
|
||||
await deleteVideoPlaylist(server.url, server.accessToken, watchLaterPlaylistId, HttpStatusCode.BAD_REQUEST_400)
|
||||
await command.delete({ playlistId: watchLaterPlaylistId, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
|
||||
})
|
||||
|
||||
it('Should succeed with the correct params', async function () {
|
||||
await deleteVideoPlaylist(server.url, server.accessToken, playlist.uuid)
|
||||
await command.delete({ playlistId: playlist.uuid })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
deleteVideoPlaylist,
|
||||
flushAndRunMultipleServers,
|
||||
getVideoPlaylistsList,
|
||||
SearchCommand,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers,
|
||||
|
@ -46,16 +42,11 @@ describe('Test ActivityPub playlists search', function () {
|
|||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: servers[0].videoChannel.id
|
||||
}
|
||||
const res = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs: attributes })
|
||||
playlistServer1UUID = res.body.videoPlaylist.uuid
|
||||
const created = await servers[0].playlistsCommand.create({ attributes })
|
||||
playlistServer1UUID = created.uuid
|
||||
|
||||
for (const videoId of [ video1, video2 ]) {
|
||||
await addVideoInPlaylist({
|
||||
url: servers[0].url,
|
||||
token: servers[0].accessToken,
|
||||
playlistId: playlistServer1UUID,
|
||||
elementAttrs: { videoId }
|
||||
})
|
||||
await servers[0].playlistsCommand.addElement({ playlistId: playlistServer1UUID, attributes: { videoId } })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,15 +59,10 @@ describe('Test ActivityPub playlists search', function () {
|
|||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: servers[1].videoChannel.id
|
||||
}
|
||||
const res = await createVideoPlaylist({ url: servers[1].url, token: servers[1].accessToken, playlistAttrs: attributes })
|
||||
playlistServer2UUID = res.body.videoPlaylist.uuid
|
||||
const created = await servers[1].playlistsCommand.create({ attributes })
|
||||
playlistServer2UUID = created.uuid
|
||||
|
||||
await addVideoInPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistServer2UUID,
|
||||
elementAttrs: { videoId }
|
||||
})
|
||||
await servers[1].playlistsCommand.addElement({ playlistId: playlistServer2UUID, attributes: { videoId } })
|
||||
}
|
||||
|
||||
await waitJobs(servers)
|
||||
|
@ -154,21 +140,16 @@ describe('Test ActivityPub playlists search', function () {
|
|||
})
|
||||
|
||||
it('Should not list this remote playlist', async function () {
|
||||
const res = await getVideoPlaylistsList(servers[0].url, 0, 10)
|
||||
expect(res.body.total).to.equal(1)
|
||||
expect(res.body.data).to.have.lengthOf(1)
|
||||
expect(res.body.data[0].displayName).to.equal('playlist 1 on server 1')
|
||||
const body = await servers[0].playlistsCommand.list({ start: 0, count: 10 })
|
||||
expect(body.total).to.equal(1)
|
||||
expect(body.data).to.have.lengthOf(1)
|
||||
expect(body.data[0].displayName).to.equal('playlist 1 on server 1')
|
||||
})
|
||||
|
||||
it('Should update the playlist of server 2, and refresh it on server 1', async function () {
|
||||
this.timeout(60000)
|
||||
|
||||
await addVideoInPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistServer2UUID,
|
||||
elementAttrs: { videoId: video2Server2 }
|
||||
})
|
||||
await servers[1].playlistsCommand.addElement({ playlistId: playlistServer2UUID, attributes: { videoId: video2Server2 } })
|
||||
|
||||
await waitJobs(servers)
|
||||
// Expire playlist
|
||||
|
@ -192,7 +173,7 @@ describe('Test ActivityPub playlists search', function () {
|
|||
it('Should delete playlist of server 2, and delete it on server 1', async function () {
|
||||
this.timeout(60000)
|
||||
|
||||
await deleteVideoPlaylist(servers[1].url, servers[1].accessToken, playlistServer2UUID)
|
||||
await servers[1].playlistsCommand.delete({ playlistId: playlistServer2UUID })
|
||||
|
||||
await waitJobs(servers)
|
||||
// Expiration
|
||||
|
|
|
@ -4,9 +4,7 @@ import 'mocha'
|
|||
import * as chai from 'chai'
|
||||
import { VideoPlaylistPrivacy } from '@shared/models'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
flushAndRunServer,
|
||||
SearchCommand,
|
||||
ServerInfo,
|
||||
|
@ -37,14 +35,9 @@ describe('Test playlists search', function () {
|
|||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: server.videoChannel.id
|
||||
}
|
||||
const res = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes })
|
||||
const created = await server.playlistsCommand.create({ attributes })
|
||||
|
||||
await addVideoInPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: res.body.videoPlaylist.id,
|
||||
elementAttrs: { videoId }
|
||||
})
|
||||
await server.playlistsCommand.addElement({ playlistId: created.id, attributes: { videoId } })
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -53,14 +46,9 @@ describe('Test playlists search', function () {
|
|||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: server.videoChannel.id
|
||||
}
|
||||
const res = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes })
|
||||
const created = await server.playlistsCommand.create({ attributes })
|
||||
|
||||
await addVideoInPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: res.body.videoPlaylist.id,
|
||||
elementAttrs: { videoId }
|
||||
})
|
||||
await server.playlistsCommand.addElement({ playlistId: created.id, attributes: { videoId } })
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -69,7 +57,7 @@ describe('Test playlists search', function () {
|
|||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: server.videoChannel.id
|
||||
}
|
||||
await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes })
|
||||
await server.playlistsCommand.create({ attributes })
|
||||
}
|
||||
|
||||
command = server.searchCommand
|
||||
|
|
|
@ -4,8 +4,6 @@ import 'mocha'
|
|||
import * as chai from 'chai'
|
||||
import { Video, VideoPlaylistPrivacy } from '@shared/models'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
createVideoPlaylist,
|
||||
getVideosList,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers,
|
||||
|
@ -41,24 +39,20 @@ describe('Test services', function () {
|
|||
}
|
||||
|
||||
{
|
||||
const res = await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
const created = await server.playlistsCommand.create({
|
||||
attributes: {
|
||||
displayName: 'The Life and Times of Scrooge McDuck',
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: server.videoChannel.id
|
||||
}
|
||||
})
|
||||
|
||||
playlistUUID = res.body.videoPlaylist.uuid
|
||||
playlistUUID = created.uuid
|
||||
playlistDisplayName = 'The Life and Times of Scrooge McDuck'
|
||||
|
||||
await addVideoInPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistId: res.body.videoPlaylist.id,
|
||||
elementAttrs: {
|
||||
await server.playlistsCommand.addElement({
|
||||
playlistId: created.id,
|
||||
attributes: {
|
||||
videoId: video.id
|
||||
}
|
||||
})
|
||||
|
|
|
@ -7,7 +7,6 @@ import {
|
|||
addVideoCommentThread,
|
||||
cleanupTests,
|
||||
createUser,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
ServerInfo,
|
||||
|
@ -178,10 +177,8 @@ describe('Test stats (excluding redundancy)', function () {
|
|||
}
|
||||
|
||||
{
|
||||
await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
await server.playlistsCommand.create({
|
||||
attributes: {
|
||||
displayName: 'playlist for count',
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: channelId
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
||||
|
||||
import * as chai from 'chai'
|
||||
import 'mocha'
|
||||
import * as chai from 'chai'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
getVideoPlaylistsList,
|
||||
removeVideoFromPlaylist,
|
||||
reorderVideosPlaylist,
|
||||
ServerInfo,
|
||||
setAccessTokensToServers,
|
||||
setDefaultVideoChannel,
|
||||
|
@ -25,8 +20,8 @@ const expect = chai.expect
|
|||
describe('Playlist thumbnail', function () {
|
||||
let servers: ServerInfo[] = []
|
||||
|
||||
let playlistWithoutThumbnail: number
|
||||
let playlistWithThumbnail: number
|
||||
let playlistWithoutThumbnailId: number
|
||||
let playlistWithThumbnailId: number
|
||||
|
||||
let withThumbnailE1: number
|
||||
let withThumbnailE2: number
|
||||
|
@ -37,15 +32,15 @@ describe('Playlist thumbnail', function () {
|
|||
let video2: number
|
||||
|
||||
async function getPlaylistWithoutThumbnail (server: ServerInfo) {
|
||||
const res = await getVideoPlaylistsList(server.url, 0, 10)
|
||||
const body = await server.playlistsCommand.list({ start: 0, count: 10 })
|
||||
|
||||
return res.body.data.find(p => p.displayName === 'playlist without thumbnail')
|
||||
return body.data.find(p => p.displayName === 'playlist without thumbnail')
|
||||
}
|
||||
|
||||
async function getPlaylistWithThumbnail (server: ServerInfo) {
|
||||
const res = await getVideoPlaylistsList(server.url, 0, 10)
|
||||
const body = await server.playlistsCommand.list({ start: 0, count: 10 })
|
||||
|
||||
return res.body.data.find(p => p.displayName === 'playlist with thumbnail')
|
||||
return body.data.find(p => p.displayName === 'playlist with thumbnail')
|
||||
}
|
||||
|
||||
before(async function () {
|
||||
|
@ -69,24 +64,20 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should automatically update the thumbnail when adding an element', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
const res = await createVideoPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistAttrs: {
|
||||
const created = await servers[1].playlistsCommand.create({
|
||||
attributes: {
|
||||
displayName: 'playlist without thumbnail',
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: servers[1].videoChannel.id
|
||||
}
|
||||
})
|
||||
playlistWithoutThumbnail = res.body.videoPlaylist.id
|
||||
playlistWithoutThumbnailId = created.id
|
||||
|
||||
const res2 = await addVideoInPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithoutThumbnail,
|
||||
elementAttrs: { videoId: video1 }
|
||||
const added = await servers[1].playlistsCommand.addElement({
|
||||
playlistId: playlistWithoutThumbnailId,
|
||||
attributes: { videoId: video1 }
|
||||
})
|
||||
withoutThumbnailE1 = res2.body.videoPlaylistElement.id
|
||||
withoutThumbnailE1 = added.id
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
|
@ -99,25 +90,21 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should not update the thumbnail if we explicitly uploaded a thumbnail', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
const res = await createVideoPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistAttrs: {
|
||||
const created = await servers[1].playlistsCommand.create({
|
||||
attributes: {
|
||||
displayName: 'playlist with thumbnail',
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: servers[1].videoChannel.id,
|
||||
thumbnailfile: 'thumbnail.jpg'
|
||||
}
|
||||
})
|
||||
playlistWithThumbnail = res.body.videoPlaylist.id
|
||||
playlistWithThumbnailId = created.id
|
||||
|
||||
const res2 = await addVideoInPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithThumbnail,
|
||||
elementAttrs: { videoId: video1 }
|
||||
const added = await servers[1].playlistsCommand.addElement({
|
||||
playlistId: playlistWithThumbnailId,
|
||||
attributes: { videoId: video1 }
|
||||
})
|
||||
withThumbnailE1 = res2.body.videoPlaylistElement.id
|
||||
withThumbnailE1 = added.id
|
||||
|
||||
await waitJobs(servers)
|
||||
|
||||
|
@ -130,19 +117,15 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should automatically update the thumbnail when moving the first element', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
const res = await addVideoInPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithoutThumbnail,
|
||||
elementAttrs: { videoId: video2 }
|
||||
const added = await servers[1].playlistsCommand.addElement({
|
||||
playlistId: playlistWithoutThumbnailId,
|
||||
attributes: { videoId: video2 }
|
||||
})
|
||||
withoutThumbnailE2 = res.body.videoPlaylistElement.id
|
||||
withoutThumbnailE2 = added.id
|
||||
|
||||
await reorderVideosPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithoutThumbnail,
|
||||
elementAttrs: {
|
||||
await servers[1].playlistsCommand.reorderElements({
|
||||
playlistId: playlistWithoutThumbnailId,
|
||||
attributes: {
|
||||
startPosition: 1,
|
||||
insertAfterPosition: 2
|
||||
}
|
||||
|
@ -159,19 +142,15 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should not update the thumbnail when moving the first element if we explicitly uploaded a thumbnail', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
const res = await addVideoInPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithThumbnail,
|
||||
elementAttrs: { videoId: video2 }
|
||||
const added = await servers[1].playlistsCommand.addElement({
|
||||
playlistId: playlistWithThumbnailId,
|
||||
attributes: { videoId: video2 }
|
||||
})
|
||||
withThumbnailE2 = res.body.videoPlaylistElement.id
|
||||
withThumbnailE2 = added.id
|
||||
|
||||
await reorderVideosPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithThumbnail,
|
||||
elementAttrs: {
|
||||
await servers[1].playlistsCommand.reorderElements({
|
||||
playlistId: playlistWithThumbnailId,
|
||||
attributes: {
|
||||
startPosition: 1,
|
||||
insertAfterPosition: 2
|
||||
}
|
||||
|
@ -188,11 +167,9 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should automatically update the thumbnail when deleting the first element', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
await removeVideoFromPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithoutThumbnail,
|
||||
playlistElementId: withoutThumbnailE1
|
||||
await servers[1].playlistsCommand.removeElement({
|
||||
playlistId: playlistWithoutThumbnailId,
|
||||
elementId: withoutThumbnailE1
|
||||
})
|
||||
|
||||
await waitJobs(servers)
|
||||
|
@ -206,11 +183,9 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should not update the thumbnail when deleting the first element if we explicitly uploaded a thumbnail', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
await removeVideoFromPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithThumbnail,
|
||||
playlistElementId: withThumbnailE1
|
||||
await servers[1].playlistsCommand.removeElement({
|
||||
playlistId: playlistWithThumbnailId,
|
||||
elementId: withThumbnailE1
|
||||
})
|
||||
|
||||
await waitJobs(servers)
|
||||
|
@ -224,11 +199,9 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should the thumbnail when we delete the last element', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
await removeVideoFromPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithoutThumbnail,
|
||||
playlistElementId: withoutThumbnailE2
|
||||
await servers[1].playlistsCommand.removeElement({
|
||||
playlistId: playlistWithoutThumbnailId,
|
||||
elementId: withoutThumbnailE2
|
||||
})
|
||||
|
||||
await waitJobs(servers)
|
||||
|
@ -242,11 +215,9 @@ describe('Playlist thumbnail', function () {
|
|||
it('Should not update the thumbnail when we delete the last element if we explicitly uploaded a thumbnail', async function () {
|
||||
this.timeout(30000)
|
||||
|
||||
await removeVideoFromPlaylist({
|
||||
url: servers[1].url,
|
||||
token: servers[1].accessToken,
|
||||
playlistId: playlistWithThumbnail,
|
||||
playlistElementId: withThumbnailE2
|
||||
await servers[1].playlistsCommand.removeElement({
|
||||
playlistId: playlistWithThumbnailId,
|
||||
elementId: withThumbnailE2
|
||||
})
|
||||
|
||||
await waitJobs(servers)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,6 @@ import {
|
|||
buildServerDirectory,
|
||||
cleanupTests,
|
||||
CLICommand,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
killallServers,
|
||||
|
@ -77,10 +76,8 @@ describe('Test prune storage scripts', function () {
|
|||
|
||||
await updateMyAvatar({ url: server.url, accessToken: server.accessToken, fixture: 'avatar.png' })
|
||||
|
||||
await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: {
|
||||
await server.playlistsCommand.create({
|
||||
attributes: {
|
||||
displayName: 'playlist',
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: server.videoChannel.id,
|
||||
|
|
|
@ -6,9 +6,7 @@ import { omit } from 'lodash'
|
|||
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||
import { Account, HTMLServerConfig, ServerConfig, VideoPlaylistCreateResult, VideoPlaylistPrivacy } from '@shared/models'
|
||||
import {
|
||||
addVideoInPlaylist,
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
getVideosList,
|
||||
|
@ -82,23 +80,17 @@ describe('Test a client controllers', function () {
|
|||
|
||||
// Playlist
|
||||
|
||||
const playlistAttrs = {
|
||||
const attributes = {
|
||||
displayName: playlistName,
|
||||
description: playlistDescription,
|
||||
privacy: VideoPlaylistPrivacy.PUBLIC,
|
||||
videoChannelId: servers[0].videoChannel.id
|
||||
}
|
||||
|
||||
const resVideoPlaylistRequest = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs })
|
||||
playlist = resVideoPlaylistRequest.body.videoPlaylist
|
||||
playlist = await servers[0].playlistsCommand.create({ attributes })
|
||||
playlistIds = [ playlist.id, playlist.shortUUID, playlist.uuid ]
|
||||
|
||||
await addVideoInPlaylist({
|
||||
url: servers[0].url,
|
||||
token: servers[0].accessToken,
|
||||
playlistId: playlist.shortUUID,
|
||||
elementAttrs: { videoId: video.id }
|
||||
})
|
||||
await servers[0].playlistsCommand.addElement({ playlistId: playlist.shortUUID, attributes: { videoId: video.id } })
|
||||
|
||||
// Account
|
||||
|
||||
|
|
|
@ -5,10 +5,8 @@ import { ServerHookName, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/mode
|
|||
import {
|
||||
addVideoCommentReply,
|
||||
addVideoCommentThread,
|
||||
addVideoInPlaylist,
|
||||
blockUser,
|
||||
createUser,
|
||||
createVideoPlaylist,
|
||||
deleteVideoComment,
|
||||
PluginsCommand,
|
||||
registerUser,
|
||||
|
@ -180,15 +178,13 @@ describe('Test plugin action hooks', function () {
|
|||
|
||||
before(async function () {
|
||||
{
|
||||
const res = await createVideoPlaylist({
|
||||
url: servers[0].url,
|
||||
token: servers[0].accessToken,
|
||||
playlistAttrs: {
|
||||
const { id } = await servers[0].playlistsCommand.create({
|
||||
attributes: {
|
||||
displayName: 'My playlist',
|
||||
privacy: VideoPlaylistPrivacy.PRIVATE
|
||||
}
|
||||
})
|
||||
playlistId = res.body.videoPlaylist.id
|
||||
playlistId = id
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -198,12 +194,7 @@ describe('Test plugin action hooks', function () {
|
|||
})
|
||||
|
||||
it('Should run action:api.video-playlist-element.created', async function () {
|
||||
await addVideoInPlaylist({
|
||||
url: servers[0].url,
|
||||
token: servers[0].accessToken,
|
||||
playlistId,
|
||||
elementAttrs: { videoId }
|
||||
})
|
||||
await servers[0].playlistsCommand.addElement({ playlistId, attributes: { videoId } })
|
||||
|
||||
await checkHook('action:api.video-playlist-element.created')
|
||||
})
|
||||
|
|
|
@ -7,7 +7,6 @@ import {
|
|||
addVideoCommentReply,
|
||||
addVideoCommentThread,
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
doubleFollow,
|
||||
flushAndRunMultipleServers,
|
||||
getAccountVideos,
|
||||
|
@ -15,7 +14,6 @@ import {
|
|||
getVideo,
|
||||
getVideoChannelVideos,
|
||||
getVideoCommentThreads,
|
||||
getVideoPlaylist,
|
||||
getVideosList,
|
||||
getVideosListPagination,
|
||||
getVideoThreadComments,
|
||||
|
@ -443,11 +441,11 @@ describe('Test plugin filter hooks', function () {
|
|||
}
|
||||
|
||||
{
|
||||
const playlistAttrs = { displayName: name, videoChannelId: servers[0].videoChannel.id, privacy: VideoPlaylistPrivacy.PUBLIC }
|
||||
const res = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs })
|
||||
const attributes = { displayName: name, videoChannelId: servers[0].videoChannel.id, privacy: VideoPlaylistPrivacy.PUBLIC }
|
||||
const { id } = await servers[0].playlistsCommand.create({ attributes })
|
||||
|
||||
const resPlaylist = await getVideoPlaylist(servers[0].url, res.body.videoPlaylist.id)
|
||||
embedPlaylists.push(resPlaylist.body)
|
||||
const playlist = await servers[0].playlistsCommand.get({ playlistId: id })
|
||||
embedPlaylists.push(playlist)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -5,13 +5,11 @@ import * as chai from 'chai'
|
|||
import { HttpStatusCode } from '@shared/core-utils'
|
||||
import {
|
||||
cleanupTests,
|
||||
createVideoPlaylist,
|
||||
flushAndRunServer,
|
||||
getVideo,
|
||||
getVideoCategories,
|
||||
getVideoLanguages,
|
||||
getVideoLicences,
|
||||
getVideoPlaylistPrivacies,
|
||||
getVideoPrivacies,
|
||||
PluginsCommand,
|
||||
ServerInfo,
|
||||
|
@ -79,8 +77,7 @@ describe('Test plugin altering video constants', function () {
|
|||
})
|
||||
|
||||
it('Should have updated playlist privacies', async function () {
|
||||
const res = await getVideoPlaylistPrivacies(server.url)
|
||||
const playlistPrivacies = res.body
|
||||
const playlistPrivacies = await server.playlistsCommand.getPrivacies()
|
||||
|
||||
expect(playlistPrivacies[1]).to.exist
|
||||
expect(playlistPrivacies[2]).to.exist
|
||||
|
@ -93,13 +90,8 @@ describe('Test plugin altering video constants', function () {
|
|||
})
|
||||
|
||||
it('Should not be able to create a video with this privacy', async function () {
|
||||
const attrs = { displayName: 'video playlist', privacy: VideoPlaylistPrivacy.PRIVATE }
|
||||
await createVideoPlaylist({
|
||||
url: server.url,
|
||||
token: server.accessToken,
|
||||
playlistAttrs: attrs,
|
||||
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||
})
|
||||
const attributes = { displayName: 'video playlist', privacy: VideoPlaylistPrivacy.PRIVATE }
|
||||
await server.playlistsCommand.create({ attributes, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
|
||||
})
|
||||
|
||||
it('Should be able to upload a video with these values', async function () {
|
||||
|
@ -162,8 +154,7 @@ describe('Test plugin altering video constants', function () {
|
|||
}
|
||||
|
||||
{
|
||||
const res = await getVideoPlaylistPrivacies(server.url)
|
||||
const playlistPrivacies = res.body
|
||||
const playlistPrivacies = await server.playlistsCommand.getPrivacies()
|
||||
|
||||
expect(playlistPrivacies[1]).to.exist
|
||||
expect(playlistPrivacies[2]).to.exist
|
||||
|
|
|
@ -18,7 +18,7 @@ import { makeGetRequest } from '../requests/requests'
|
|||
import { SearchCommand } from '../search'
|
||||
import { SocketIOCommand } from '../socket'
|
||||
import { AccountsCommand, BlocklistCommand, SubscriptionsCommand } from '../users'
|
||||
import { BlacklistCommand, CaptionsCommand, ChangeOwnershipCommand, LiveCommand, ServicesCommand } from '../videos'
|
||||
import { BlacklistCommand, CaptionsCommand, ChangeOwnershipCommand, LiveCommand, PlaylistsCommand, ServicesCommand } from '../videos'
|
||||
import { ConfigCommand } from './config-command'
|
||||
import { ContactFormCommand } from './contact-form-command'
|
||||
import { DebugCommand } from './debug-command'
|
||||
|
@ -105,6 +105,7 @@ interface ServerInfo {
|
|||
blacklistCommand?: BlacklistCommand
|
||||
captionsCommand?: CaptionsCommand
|
||||
changeOwnershipCommand?: ChangeOwnershipCommand
|
||||
playlistsCommand?: PlaylistsCommand
|
||||
}
|
||||
|
||||
function parallelTests () {
|
||||
|
@ -335,6 +336,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = []
|
|||
server.blacklistCommand = new BlacklistCommand(server)
|
||||
server.captionsCommand = new CaptionsCommand(server)
|
||||
server.changeOwnershipCommand = new ChangeOwnershipCommand(server)
|
||||
server.playlistsCommand = new PlaylistsCommand(server)
|
||||
|
||||
res(server)
|
||||
})
|
||||
|
|
|
@ -4,11 +4,12 @@ export * from './captions-command'
|
|||
export * from './change-ownership-command'
|
||||
export * from './live-command'
|
||||
export * from './live'
|
||||
export * from './playlists-command'
|
||||
export * from './playlists'
|
||||
export * from './services-command'
|
||||
export * from './video-channels'
|
||||
export * from './video-comments'
|
||||
export * from './video-history'
|
||||
export * from './video-imports'
|
||||
export * from './video-playlists'
|
||||
export * from './video-streaming-playlists'
|
||||
export * from './videos'
|
||||
|
|
|
@ -0,0 +1,280 @@
|
|||
import { omit, pick } from 'lodash'
|
||||
import {
|
||||
BooleanBothQuery,
|
||||
ResultList,
|
||||
VideoExistInPlaylist,
|
||||
VideoPlaylist,
|
||||
VideoPlaylistCreateResult,
|
||||
VideoPlaylistElement,
|
||||
VideoPlaylistElementCreateResult,
|
||||
VideoPlaylistReorder
|
||||
} from '@shared/models'
|
||||
import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes'
|
||||
import { VideoPlaylistCreate } from '../../models/videos/playlist/video-playlist-create.model'
|
||||
import { VideoPlaylistElementCreate } from '../../models/videos/playlist/video-playlist-element-create.model'
|
||||
import { VideoPlaylistElementUpdate } from '../../models/videos/playlist/video-playlist-element-update.model'
|
||||
import { VideoPlaylistType } from '../../models/videos/playlist/video-playlist-type.model'
|
||||
import { VideoPlaylistUpdate } from '../../models/videos/playlist/video-playlist-update.model'
|
||||
import { unwrapBody } from '../requests'
|
||||
import { AbstractCommand, OverrideCommandOptions } from '../shared'
|
||||
import { videoUUIDToId } from './videos'
|
||||
|
||||
export class PlaylistsCommand extends AbstractCommand {
|
||||
|
||||
list (options: OverrideCommandOptions & {
|
||||
start?: number
|
||||
count?: number
|
||||
sort?: string
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists'
|
||||
const query = pick(options, [ 'start', 'count', 'sort' ])
|
||||
|
||||
return this.getRequestBody<ResultList<VideoPlaylist>>({
|
||||
...options,
|
||||
|
||||
path,
|
||||
query,
|
||||
implicitToken: false,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
listByChannel (options: OverrideCommandOptions & {
|
||||
handle: string
|
||||
start?: number
|
||||
count?: number
|
||||
sort?: string
|
||||
}) {
|
||||
const path = '/api/v1/video-channels/' + options.handle + '/video-playlists'
|
||||
const query = pick(options, [ 'start', 'count', 'sort' ])
|
||||
|
||||
return this.getRequestBody<ResultList<VideoPlaylist>>({
|
||||
...options,
|
||||
|
||||
path,
|
||||
query,
|
||||
implicitToken: false,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
listByAccount (options: OverrideCommandOptions & {
|
||||
handle: string
|
||||
start?: number
|
||||
count?: number
|
||||
sort?: string
|
||||
search?: string
|
||||
playlistType?: VideoPlaylistType
|
||||
}) {
|
||||
const path = '/api/v1/accounts/' + options.handle + '/video-playlists'
|
||||
const query = pick(options, [ 'start', 'count', 'sort', 'search', 'playlistType' ])
|
||||
|
||||
return this.getRequestBody<ResultList<VideoPlaylist>>({
|
||||
...options,
|
||||
|
||||
path,
|
||||
query,
|
||||
implicitToken: false,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
get (options: OverrideCommandOptions & {
|
||||
playlistId: number | string
|
||||
}) {
|
||||
const { playlistId } = options
|
||||
const path = '/api/v1/video-playlists/' + playlistId
|
||||
|
||||
return this.getRequestBody<VideoPlaylist>({
|
||||
...options,
|
||||
|
||||
path,
|
||||
implicitToken: false,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
listVideos (options: OverrideCommandOptions & {
|
||||
playlistId: number | string
|
||||
start?: number
|
||||
count?: number
|
||||
query?: { nsfw?: BooleanBothQuery }
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos'
|
||||
const query = options.query ?? {}
|
||||
|
||||
return this.getRequestBody<ResultList<VideoPlaylistElement>>({
|
||||
...options,
|
||||
|
||||
path,
|
||||
query: {
|
||||
...query,
|
||||
start: options.start,
|
||||
count: options.count
|
||||
},
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
delete (options: OverrideCommandOptions & {
|
||||
playlistId: number | string
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId
|
||||
|
||||
return this.deleteRequest({
|
||||
...options,
|
||||
|
||||
path,
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
async create (options: OverrideCommandOptions & {
|
||||
attributes: VideoPlaylistCreate
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists'
|
||||
|
||||
const fields = omit(options.attributes, 'thumbnailfile')
|
||||
|
||||
const attaches = options.attributes.thumbnailfile
|
||||
? { thumbnailfile: options.attributes.thumbnailfile }
|
||||
: {}
|
||||
|
||||
const body = await unwrapBody<{ videoPlaylist: VideoPlaylistCreateResult }>(this.postUploadRequest({
|
||||
...options,
|
||||
|
||||
path,
|
||||
fields,
|
||||
attaches,
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
}))
|
||||
|
||||
return body.videoPlaylist
|
||||
}
|
||||
|
||||
update (options: OverrideCommandOptions & {
|
||||
attributes: VideoPlaylistUpdate
|
||||
playlistId: number | string
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId
|
||||
|
||||
const fields = omit(options.attributes, 'thumbnailfile')
|
||||
|
||||
const attaches = options.attributes.thumbnailfile
|
||||
? { thumbnailfile: options.attributes.thumbnailfile }
|
||||
: {}
|
||||
|
||||
return this.putUploadRequest({
|
||||
...options,
|
||||
|
||||
path,
|
||||
fields,
|
||||
attaches,
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
async addElement (options: OverrideCommandOptions & {
|
||||
playlistId: number | string
|
||||
attributes: VideoPlaylistElementCreate | { videoId: string }
|
||||
}) {
|
||||
const attributes = {
|
||||
...options.attributes,
|
||||
|
||||
videoId: await videoUUIDToId(this.server.url, options.attributes.videoId)
|
||||
}
|
||||
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos'
|
||||
|
||||
const body = await unwrapBody<{ videoPlaylistElement: VideoPlaylistElementCreateResult }>(this.postBodyRequest({
|
||||
...options,
|
||||
|
||||
path,
|
||||
fields: attributes,
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
}))
|
||||
|
||||
return body.videoPlaylistElement
|
||||
}
|
||||
|
||||
updateElement (options: OverrideCommandOptions & {
|
||||
playlistId: number | string
|
||||
elementId: number | string
|
||||
attributes: VideoPlaylistElementUpdate
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.elementId
|
||||
|
||||
return this.putBodyRequest({
|
||||
...options,
|
||||
|
||||
path,
|
||||
fields: options.attributes,
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
removeElement (options: OverrideCommandOptions & {
|
||||
playlistId: number | string
|
||||
elementId: number
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.elementId
|
||||
|
||||
return this.deleteRequest({
|
||||
...options,
|
||||
|
||||
path,
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
reorderElements (options: OverrideCommandOptions & {
|
||||
playlistId: number | string
|
||||
attributes: VideoPlaylistReorder
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/reorder'
|
||||
|
||||
return this.postBodyRequest({
|
||||
...options,
|
||||
|
||||
path,
|
||||
fields: options.attributes,
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
getPrivacies (options: OverrideCommandOptions = {}) {
|
||||
const path = '/api/v1/video-playlists/privacies'
|
||||
|
||||
return this.getRequestBody<{ [ id: number ]: string }>({
|
||||
...options,
|
||||
|
||||
path,
|
||||
implicitToken: false,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
videosExist (options: OverrideCommandOptions & {
|
||||
videoIds: number[]
|
||||
}) {
|
||||
const { videoIds } = options
|
||||
const path = '/api/v1/users/me/video-playlists/videos-exist'
|
||||
|
||||
return this.getRequestBody<VideoExistInPlaylist>({
|
||||
...options,
|
||||
|
||||
path,
|
||||
query: { videoIds },
|
||||
implicitToken: true,
|
||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { expect } from 'chai'
|
||||
import { readdir } from 'fs-extra'
|
||||
import { join } from 'path'
|
||||
import { root } from '../'
|
||||
|
||||
async function checkPlaylistFilesWereRemoved (
|
||||
playlistUUID: string,
|
||||
internalServerNumber: number,
|
||||
directories = [ 'thumbnails' ]
|
||||
) {
|
||||
const testDirectory = 'test' + internalServerNumber
|
||||
|
||||
for (const directory of directories) {
|
||||
const directoryPath = join(root(), testDirectory, directory)
|
||||
|
||||
const files = await readdir(directoryPath)
|
||||
for (const file of files) {
|
||||
expect(file).to.not.contain(playlistUUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
checkPlaylistFilesWereRemoved
|
||||
}
|
|
@ -1,320 +0,0 @@
|
|||
import { makeDeleteRequest, makeGetRequest, makePostBodyRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests'
|
||||
import { VideoPlaylistCreate } from '../../models/videos/playlist/video-playlist-create.model'
|
||||
import { omit } from 'lodash'
|
||||
import { VideoPlaylistUpdate } from '../../models/videos/playlist/video-playlist-update.model'
|
||||
import { VideoPlaylistElementCreate } from '../../models/videos/playlist/video-playlist-element-create.model'
|
||||
import { VideoPlaylistElementUpdate } from '../../models/videos/playlist/video-playlist-element-update.model'
|
||||
import { videoUUIDToId } from './videos'
|
||||
import { join } from 'path'
|
||||
import { root } from '..'
|
||||
import { readdir } from 'fs-extra'
|
||||
import { expect } from 'chai'
|
||||
import { VideoPlaylistType } from '../../models/videos/playlist/video-playlist-type.model'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
||||
function getVideoPlaylistsList (url: string, start: number, count: number, sort?: string) {
|
||||
const path = '/api/v1/video-playlists'
|
||||
|
||||
const query = {
|
||||
start,
|
||||
count,
|
||||
sort
|
||||
}
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
path,
|
||||
query,
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function getVideoChannelPlaylistsList (url: string, videoChannelName: string, start: number, count: number, sort?: string) {
|
||||
const path = '/api/v1/video-channels/' + videoChannelName + '/video-playlists'
|
||||
|
||||
const query = {
|
||||
start,
|
||||
count,
|
||||
sort
|
||||
}
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
path,
|
||||
query,
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function getAccountPlaylistsList (url: string, accountName: string, start: number, count: number, sort?: string, search?: string) {
|
||||
const path = '/api/v1/accounts/' + accountName + '/video-playlists'
|
||||
|
||||
const query = {
|
||||
start,
|
||||
count,
|
||||
sort,
|
||||
search
|
||||
}
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
path,
|
||||
query,
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function getAccountPlaylistsListWithToken (
|
||||
url: string,
|
||||
token: string,
|
||||
accountName: string,
|
||||
start: number,
|
||||
count: number,
|
||||
playlistType?: VideoPlaylistType,
|
||||
sort?: string
|
||||
) {
|
||||
const path = '/api/v1/accounts/' + accountName + '/video-playlists'
|
||||
|
||||
const query = {
|
||||
start,
|
||||
count,
|
||||
playlistType,
|
||||
sort
|
||||
}
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
token,
|
||||
path,
|
||||
query,
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function getVideoPlaylist (url: string, playlistId: number | string, statusCodeExpected = HttpStatusCode.OK_200) {
|
||||
const path = '/api/v1/video-playlists/' + playlistId
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
path,
|
||||
statusCodeExpected
|
||||
})
|
||||
}
|
||||
|
||||
function getVideoPlaylistWithToken (url: string, token: string, playlistId: number | string, statusCodeExpected = HttpStatusCode.OK_200) {
|
||||
const path = '/api/v1/video-playlists/' + playlistId
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
token,
|
||||
path,
|
||||
statusCodeExpected
|
||||
})
|
||||
}
|
||||
|
||||
function deleteVideoPlaylist (url: string, token: string, playlistId: number | string, statusCodeExpected = HttpStatusCode.NO_CONTENT_204) {
|
||||
const path = '/api/v1/video-playlists/' + playlistId
|
||||
|
||||
return makeDeleteRequest({
|
||||
url,
|
||||
path,
|
||||
token,
|
||||
statusCodeExpected
|
||||
})
|
||||
}
|
||||
|
||||
function createVideoPlaylist (options: {
|
||||
url: string
|
||||
token: string
|
||||
playlistAttrs: VideoPlaylistCreate
|
||||
expectedStatus?: number
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists'
|
||||
|
||||
const fields = omit(options.playlistAttrs, 'thumbnailfile')
|
||||
|
||||
const attaches = options.playlistAttrs.thumbnailfile
|
||||
? { thumbnailfile: options.playlistAttrs.thumbnailfile }
|
||||
: {}
|
||||
|
||||
return makeUploadRequest({
|
||||
method: 'POST',
|
||||
url: options.url,
|
||||
path,
|
||||
token: options.token,
|
||||
fields,
|
||||
attaches,
|
||||
statusCodeExpected: options.expectedStatus || HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function updateVideoPlaylist (options: {
|
||||
url: string
|
||||
token: string
|
||||
playlistAttrs: VideoPlaylistUpdate
|
||||
playlistId: number | string
|
||||
expectedStatus?: number
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId
|
||||
|
||||
const fields = omit(options.playlistAttrs, 'thumbnailfile')
|
||||
|
||||
const attaches = options.playlistAttrs.thumbnailfile
|
||||
? { thumbnailfile: options.playlistAttrs.thumbnailfile }
|
||||
: {}
|
||||
|
||||
return makeUploadRequest({
|
||||
method: 'PUT',
|
||||
url: options.url,
|
||||
path,
|
||||
token: options.token,
|
||||
fields,
|
||||
attaches,
|
||||
statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
async function addVideoInPlaylist (options: {
|
||||
url: string
|
||||
token: string
|
||||
playlistId: number | string
|
||||
elementAttrs: VideoPlaylistElementCreate | { videoId: string }
|
||||
expectedStatus?: number
|
||||
}) {
|
||||
options.elementAttrs.videoId = await videoUUIDToId(options.url, options.elementAttrs.videoId)
|
||||
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos'
|
||||
|
||||
return makePostBodyRequest({
|
||||
url: options.url,
|
||||
path,
|
||||
token: options.token,
|
||||
fields: options.elementAttrs,
|
||||
statusCodeExpected: options.expectedStatus || HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function updateVideoPlaylistElement (options: {
|
||||
url: string
|
||||
token: string
|
||||
playlistId: number | string
|
||||
playlistElementId: number | string
|
||||
elementAttrs: VideoPlaylistElementUpdate
|
||||
expectedStatus?: number
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.playlistElementId
|
||||
|
||||
return makePutBodyRequest({
|
||||
url: options.url,
|
||||
path,
|
||||
token: options.token,
|
||||
fields: options.elementAttrs,
|
||||
statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
function removeVideoFromPlaylist (options: {
|
||||
url: string
|
||||
token: string
|
||||
playlistId: number | string
|
||||
playlistElementId: number
|
||||
expectedStatus?: number
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/' + options.playlistElementId
|
||||
|
||||
return makeDeleteRequest({
|
||||
url: options.url,
|
||||
path,
|
||||
token: options.token,
|
||||
statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
function reorderVideosPlaylist (options: {
|
||||
url: string
|
||||
token: string
|
||||
playlistId: number | string
|
||||
elementAttrs: {
|
||||
startPosition: number
|
||||
insertAfterPosition: number
|
||||
reorderLength?: number
|
||||
}
|
||||
expectedStatus?: number
|
||||
}) {
|
||||
const path = '/api/v1/video-playlists/' + options.playlistId + '/videos/reorder'
|
||||
|
||||
return makePostBodyRequest({
|
||||
url: options.url,
|
||||
path,
|
||||
token: options.token,
|
||||
fields: options.elementAttrs,
|
||||
statusCodeExpected: options.expectedStatus || HttpStatusCode.NO_CONTENT_204
|
||||
})
|
||||
}
|
||||
|
||||
async function checkPlaylistFilesWereRemoved (
|
||||
playlistUUID: string,
|
||||
internalServerNumber: number,
|
||||
directories = [ 'thumbnails' ]
|
||||
) {
|
||||
const testDirectory = 'test' + internalServerNumber
|
||||
|
||||
for (const directory of directories) {
|
||||
const directoryPath = join(root(), testDirectory, directory)
|
||||
|
||||
const files = await readdir(directoryPath)
|
||||
for (const file of files) {
|
||||
expect(file).to.not.contain(playlistUUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getVideoPlaylistPrivacies (url: string) {
|
||||
const path = '/api/v1/video-playlists/privacies'
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
path,
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function doVideosExistInMyPlaylist (url: string, token: string, videoIds: number[]) {
|
||||
const path = '/api/v1/users/me/video-playlists/videos-exist'
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
token,
|
||||
path,
|
||||
query: { videoIds },
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
getVideoPlaylistPrivacies,
|
||||
|
||||
getVideoPlaylistsList,
|
||||
getVideoChannelPlaylistsList,
|
||||
getAccountPlaylistsList,
|
||||
getAccountPlaylistsListWithToken,
|
||||
|
||||
getVideoPlaylist,
|
||||
getVideoPlaylistWithToken,
|
||||
|
||||
createVideoPlaylist,
|
||||
updateVideoPlaylist,
|
||||
deleteVideoPlaylist,
|
||||
|
||||
addVideoInPlaylist,
|
||||
updateVideoPlaylistElement,
|
||||
removeVideoFromPlaylist,
|
||||
|
||||
reorderVideosPlaylist,
|
||||
|
||||
checkPlaylistFilesWereRemoved,
|
||||
|
||||
doVideosExistInMyPlaylist
|
||||
}
|
|
@ -262,28 +262,6 @@ function getVideoChannelVideos (
|
|||
})
|
||||
}
|
||||
|
||||
function getPlaylistVideos (
|
||||
url: string,
|
||||
accessToken: string,
|
||||
playlistId: number | string,
|
||||
start: number,
|
||||
count: number,
|
||||
query: { nsfw?: boolean } = {}
|
||||
) {
|
||||
const path = '/api/v1/video-playlists/' + playlistId + '/videos'
|
||||
|
||||
return makeGetRequest({
|
||||
url,
|
||||
path,
|
||||
query: immutableAssign(query, {
|
||||
start,
|
||||
count
|
||||
}),
|
||||
token: accessToken,
|
||||
statusCodeExpected: HttpStatusCode.OK_200
|
||||
})
|
||||
}
|
||||
|
||||
function getVideosListPagination (url: string, start: number, count: number, sort?: string, skipCount?: boolean) {
|
||||
const path = '/api/v1/videos'
|
||||
|
||||
|
@ -871,7 +849,6 @@ export {
|
|||
getLocalVideos,
|
||||
completeVideoCheck,
|
||||
checkVideoFilesWereRemoved,
|
||||
getPlaylistVideos,
|
||||
getMyVideosWithFilter,
|
||||
uploadVideoAndGetId,
|
||||
getLocalIdByUUID,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export * from './video-exist-in-playlist.model'
|
||||
export * from './video-playlist-create-result.model'
|
||||
export * from './video-playlist-create.model'
|
||||
export * from './video-playlist-element-create-result.model'
|
||||
export * from './video-playlist-element-create.model'
|
||||
export * from './video-playlist-element-update.model'
|
||||
export * from './video-playlist-element.model'
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export interface VideoPlaylistElementCreateResult {
|
||||
id: number
|
||||
}
|
Loading…
Reference in New Issue