From e6346d59e63135cf012ed18c102d3b0179ef565f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 15:54:39 +0200 Subject: [PATCH] Introduce playlist command --- server/controllers/api/video-playlist.ts | 7 +- server/tests/api/activitypub/client.ts | 6 +- server/tests/api/activitypub/refresher.ts | 22 +- server/tests/api/check-params/services.ts | 18 +- .../tests/api/check-params/video-playlists.ts | 347 ++++++----- .../search-activitypub-video-playlists.ts | 45 +- server/tests/api/search/search-playlists.ts | 26 +- server/tests/api/server/services.ts | 18 +- server/tests/api/server/stats.ts | 7 +- .../api/videos/video-playlist-thumbnails.ts | 123 ++-- server/tests/api/videos/video-playlists.ts | 564 ++++++++---------- server/tests/cli/prune-storage.ts | 7 +- server/tests/client.ts | 14 +- server/tests/plugins/action-hooks.ts | 17 +- server/tests/plugins/filter-hooks.ts | 10 +- server/tests/plugins/video-constants.ts | 17 +- shared/extra-utils/server/servers.ts | 4 +- shared/extra-utils/videos/index.ts | 3 +- .../extra-utils/videos/playlists-command.ts | 280 +++++++++ shared/extra-utils/videos/playlists.ts | 25 + shared/extra-utils/videos/video-playlists.ts | 320 ---------- shared/extra-utils/videos/videos.ts | 23 - shared/models/videos/playlist/index.ts | 1 + ...eo-playlist-element-create-result.model.ts | 3 + 24 files changed, 853 insertions(+), 1054 deletions(-) create mode 100644 shared/extra-utils/videos/playlists-command.ts create mode 100644 shared/extra-utils/videos/playlists.ts delete mode 100644 shared/extra-utils/videos/video-playlists.ts create mode 100644 shared/models/videos/playlist/video-playlist-element-create-result.model.ts diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index 87a6f6bbe..78cbd9cff 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts @@ -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) { diff --git a/server/tests/api/activitypub/client.ts b/server/tests/api/activitypub/client.ts index be94e219c..e8536a214 100644 --- a/server/tests/api/activitypub/client.ts +++ b/server/tests/api/activitypub/client.ts @@ -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]) diff --git a/server/tests/api/activitypub/refresher.ts b/server/tests/api/activitypub/refresher.ts index 0d5452ea4..f295dfab7 100644 --- a/server/tests/api/activitypub/refresher.ts +++ b/server/tests/api/activitypub/refresher.ts @@ -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 }) }) }) diff --git a/server/tests/api/check-params/services.ts b/server/tests/api/check-params/services.ts index 514e3da70..595fab70d 100644 --- a/server/tests/api/check-params/services.ts +++ b/server/tests/api/check-params/services.ts @@ -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 } }) diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts index 18253d11a..1c507a047 100644 --- a/server/tests/api/check-params/video-playlists.ts +++ b/server/tests/api/check-params/video-playlists.ts @@ -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, + wrapper?: Partial[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, + wrapper?: Partial[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, + wrapper?: Partial[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, + wrapper?: Partial[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[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 }) }) }) diff --git a/server/tests/api/search/search-activitypub-video-playlists.ts b/server/tests/api/search/search-activitypub-video-playlists.ts index 1df18173a..cb7582d29 100644 --- a/server/tests/api/search/search-activitypub-video-playlists.ts +++ b/server/tests/api/search/search-activitypub-video-playlists.ts @@ -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 - - await addVideoInPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, - playlistId: playlistServer2UUID, - elementAttrs: { videoId } - }) + const created = await servers[1].playlistsCommand.create({ attributes }) + playlistServer2UUID = created.uuid + + 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 diff --git a/server/tests/api/search/search-playlists.ts b/server/tests/api/search/search-playlists.ts index 1862ecd31..517884503 100644 --- a/server/tests/api/search/search-playlists.ts +++ b/server/tests/api/search/search-playlists.ts @@ -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 }) - - await addVideoInPlaylist({ - url: server.url, - token: server.accessToken, - playlistId: res.body.videoPlaylist.id, - elementAttrs: { videoId } - }) + const created = await server.playlistsCommand.create({ attributes }) + + 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 }) - - await addVideoInPlaylist({ - url: server.url, - token: server.accessToken, - playlistId: res.body.videoPlaylist.id, - elementAttrs: { videoId } - }) + const created = await server.playlistsCommand.create({ attributes }) + + 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 diff --git a/server/tests/api/server/services.ts b/server/tests/api/server/services.ts index 0adf6b667..77b95de10 100644 --- a/server/tests/api/server/services.ts +++ b/server/tests/api/server/services.ts @@ -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 } }) diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts index f01188d67..c877a65eb 100644 --- a/server/tests/api/server/stats.ts +++ b/server/tests/api/server/stats.ts @@ -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 diff --git a/server/tests/api/videos/video-playlist-thumbnails.ts b/server/tests/api/videos/video-playlist-thumbnails.ts index a93a0b7de..af5df8d90 100644 --- a/server/tests/api/videos/video-playlist-thumbnails.ts +++ b/server/tests/api/videos/video-playlist-thumbnails.ts @@ -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) diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts index 069450453..4de6b3abf 100644 --- a/server/tests/api/videos/video-playlists.ts +++ b/server/tests/api/videos/video-playlists.ts @@ -5,37 +5,22 @@ import * as chai from 'chai' import { HttpStatusCode } from '@shared/core-utils' import { addVideoChannel, - addVideoInPlaylist, checkPlaylistFilesWereRemoved, cleanupTests, createUser, - createVideoPlaylist, deleteVideoChannel, - deleteVideoPlaylist, doubleFollow, - doVideosExistInMyPlaylist, flushAndRunMultipleServers, generateUserAccessToken, getAccessToken, - getAccountPlaylistsList, - getAccountPlaylistsListWithToken, getMyUserInformation, - getPlaylistVideos, - getVideoChannelPlaylistsList, - getVideoPlaylist, - getVideoPlaylistPrivacies, - getVideoPlaylistsList, - getVideoPlaylistWithToken, + PlaylistsCommand, removeUser, - removeVideoFromPlaylist, - reorderVideosPlaylist, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, testImage, updateVideo, - updateVideoPlaylist, - updateVideoPlaylistElement, uploadVideo, uploadVideoAndGetId, userLogin, @@ -44,10 +29,8 @@ import { } from '@shared/extra-utils' import { User, - VideoExistInPlaylist, VideoPlaylist, VideoPlaylistCreateResult, - VideoPlaylistElement, VideoPlaylistElementType, VideoPlaylistPrivacy, VideoPlaylistType, @@ -65,10 +48,10 @@ async function checkPlaylistElementType ( total: number ) { for (const server of servers) { - const res = await getPlaylistVideos(server.url, server.accessToken, playlistId, 0, 10) - expect(res.body.total).to.equal(total) + const body = await server.playlistsCommand.listVideos({ token: server.accessToken, playlistId, start: 0, count: 10 }) + expect(body.total).to.equal(total) - const videoElement: VideoPlaylistElement = res.body.data.find((e: VideoPlaylistElement) => e.position === position) + const videoElement = body.data.find(e => e.position === position) expect(videoElement.type).to.equal(type, 'On server ' + server.url) if (type === VideoPlaylistElementType.REGULAR) { @@ -85,7 +68,7 @@ describe('Test video playlists', function () { let playlistServer2Id1: number let playlistServer2Id2: number - let playlistServer2UUID2: number + let playlistServer2UUID2: string let playlistServer1Id: number let playlistServer1UUID: string @@ -97,7 +80,9 @@ describe('Test video playlists', function () { let nsfwVideoServer1: number - let userAccessTokenServer1: string + let userTokenServer1: string + + let commands: PlaylistsCommand[] before(async function () { this.timeout(120000) @@ -113,6 +98,8 @@ describe('Test video playlists', function () { // Server 1 and server 3 follow each other await doubleFollow(servers[0], servers[2]) + commands = servers.map(s => s.playlistsCommand) + { servers[0].videos = [] servers[1].videos = [] @@ -137,62 +124,60 @@ describe('Test video playlists', function () { username: 'user1', password: 'password' }) - userAccessTokenServer1 = await getAccessToken(servers[0].url, 'user1', 'password') + userTokenServer1 = await getAccessToken(servers[0].url, 'user1', 'password') } await waitJobs(servers) }) describe('Get default playlists', function () { + it('Should list video playlist privacies', async function () { - const res = await getVideoPlaylistPrivacies(servers[0].url) + const privacies = await commands[0].getPrivacies() - const privacies = res.body expect(Object.keys(privacies)).to.have.length.at.least(3) - expect(privacies[3]).to.equal('Private') }) it('Should list watch later playlist', async function () { - const url = servers[0].url - const accessToken = servers[0].accessToken + const token = servers[0].accessToken { - const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER) + const body = await commands[0].listByAccount({ token, handle: 'root', playlistType: VideoPlaylistType.WATCH_LATER }) - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) + expect(body.total).to.equal(1) + expect(body.data).to.have.lengthOf(1) - const playlist: VideoPlaylist = res.body.data[0] + const playlist = body.data[0] expect(playlist.displayName).to.equal('Watch later') expect(playlist.type.id).to.equal(VideoPlaylistType.WATCH_LATER) expect(playlist.type.label).to.equal('Watch later') } { - const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.REGULAR) + const body = await commands[0].listByAccount({ token, handle: 'root', playlistType: VideoPlaylistType.REGULAR }) - expect(res.body.total).to.equal(0) - expect(res.body.data).to.have.lengthOf(0) + expect(body.total).to.equal(0) + expect(body.data).to.have.lengthOf(0) } { - const res = await getAccountPlaylistsList(url, 'root', 0, 5) - expect(res.body.total).to.equal(0) - expect(res.body.data).to.have.lengthOf(0) + const body = await commands[0].listByAccount({ handle: 'root' }) + expect(body.total).to.equal(0) + expect(body.data).to.have.lengthOf(0) } }) it('Should get private playlist for a classic user', async function () { const token = await generateUserAccessToken(servers[0], 'toto') - const res = await getAccountPlaylistsListWithToken(servers[0].url, token, 'toto', 0, 5) + const body = await commands[0].listByAccount({ token, handle: 'toto' }) - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) + expect(body.total).to.equal(1) + expect(body.data).to.have.lengthOf(1) - const playlistId = res.body.data[0].id - await getPlaylistVideos(servers[0].url, token, playlistId, 0, 5) + const playlistId = body.data[0].id + await commands[0].listVideos({ token, playlistId }) }) }) @@ -201,10 +186,8 @@ describe('Test video playlists', function () { it('Should create a playlist on server 1 and have the playlist on server 2 and 3', async function () { this.timeout(30000) - await createVideoPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, - playlistAttrs: { + await commands[0].create({ + attributes: { displayName: 'my super playlist', privacy: VideoPlaylistPrivacy.PUBLIC, description: 'my super description', @@ -218,14 +201,13 @@ describe('Test video playlists', function () { await wait(3000) for (const server of servers) { - const res = await getVideoPlaylistsList(server.url, 0, 5) - expect(res.body.total).to.equal(1) - expect(res.body.data).to.have.lengthOf(1) + const body = await server.playlistsCommand.list({ start: 0, count: 5 }) + expect(body.total).to.equal(1) + expect(body.data).to.have.lengthOf(1) - const playlistFromList = res.body.data[0] as VideoPlaylist + const playlistFromList = body.data[0] - const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid) - const playlistFromGet = res2.body as VideoPlaylist + const playlistFromGet = await server.playlistsCommand.get({ playlistId: playlistFromList.uuid }) for (const playlist of [ playlistFromGet, playlistFromList ]) { expect(playlist.id).to.be.a('number') @@ -255,23 +237,19 @@ describe('Test video playlists', function () { this.timeout(30000) { - const res = await createVideoPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, - playlistAttrs: { + const playlist = await servers[1].playlistsCommand.create({ + attributes: { displayName: 'playlist 2', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[1].videoChannel.id } }) - playlistServer2Id1 = res.body.videoPlaylist.id + playlistServer2Id1 = playlist.id } { - const res = await createVideoPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, - playlistAttrs: { + const playlist = await servers[1].playlistsCommand.create({ + attributes: { displayName: 'playlist 3', privacy: VideoPlaylistPrivacy.PUBLIC, thumbnailfile: 'thumbnail.jpg', @@ -279,22 +257,18 @@ describe('Test video playlists', function () { } }) - playlistServer2Id2 = res.body.videoPlaylist.id - playlistServer2UUID2 = res.body.videoPlaylist.uuid + playlistServer2Id2 = playlist.id + playlistServer2UUID2 = playlist.uuid } for (const id of [ playlistServer2Id1, playlistServer2Id2 ]) { - await addVideoInPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, + await servers[1].playlistsCommand.addElement({ playlistId: id, - elementAttrs: { videoId: servers[1].videos[0].id, startTimestamp: 1, stopTimestamp: 2 } + attributes: { videoId: servers[1].videos[0].id, startTimestamp: 1, stopTimestamp: 2 } }) - await addVideoInPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, + await servers[1].playlistsCommand.addElement({ playlistId: id, - elementAttrs: { videoId: servers[1].videos[1].id } + attributes: { videoId: servers[1].videos[1].id } }) } @@ -302,20 +276,20 @@ describe('Test video playlists', function () { await wait(3000) for (const server of [ servers[0], servers[1] ]) { - const res = await getVideoPlaylistsList(server.url, 0, 5) + const body = await server.playlistsCommand.list({ start: 0, count: 5 }) - const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2') + const playlist2 = body.data.find(p => p.displayName === 'playlist 2') expect(playlist2).to.not.be.undefined await testImage(server.url, 'thumbnail-playlist', playlist2.thumbnailPath) - const playlist3 = res.body.data.find(p => p.displayName === 'playlist 3') + const playlist3 = body.data.find(p => p.displayName === 'playlist 3') expect(playlist3).to.not.be.undefined await testImage(server.url, 'thumbnail', playlist3.thumbnailPath) } - const res = await getVideoPlaylistsList(servers[2].url, 0, 5) - expect(res.body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined - expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined + const body = await servers[2].playlistsCommand.list({ start: 0, count: 5 }) + expect(body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined + expect(body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined }) it('Should have the playlist on server 3 after a new follow', async function () { @@ -324,13 +298,13 @@ describe('Test video playlists', function () { // Server 2 and server 3 follow each other await doubleFollow(servers[1], servers[2]) - const res = await getVideoPlaylistsList(servers[2].url, 0, 5) + const body = await servers[2].playlistsCommand.list({ start: 0, count: 5 }) - const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2') + const playlist2 = body.data.find(p => p.displayName === 'playlist 2') expect(playlist2).to.not.be.undefined await testImage(servers[2].url, 'thumbnail-playlist', playlist2.thumbnailPath) - expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined + expect(body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined }) }) @@ -340,22 +314,20 @@ describe('Test video playlists', function () { this.timeout(30000) { - const res = await getVideoPlaylistsList(servers[2].url, 1, 2, 'createdAt') + const body = await servers[2].playlistsCommand.list({ start: 1, count: 2, sort: 'createdAt' }) + expect(body.total).to.equal(3) - expect(res.body.total).to.equal(3) - - const data: VideoPlaylist[] = res.body.data + const data = body.data expect(data).to.have.lengthOf(2) expect(data[0].displayName).to.equal('playlist 2') expect(data[1].displayName).to.equal('playlist 3') } { - const res = await getVideoPlaylistsList(servers[2].url, 1, 2, '-createdAt') - - expect(res.body.total).to.equal(3) + const body = await servers[2].playlistsCommand.list({ start: 1, count: 2, sort: '-createdAt' }) + expect(body.total).to.equal(3) - const data: VideoPlaylist[] = res.body.data + const data = body.data expect(data).to.have.lengthOf(2) expect(data[0].displayName).to.equal('playlist 2') expect(data[1].displayName).to.equal('my super playlist') @@ -366,11 +338,10 @@ describe('Test video playlists', function () { this.timeout(30000) { - const res = await getVideoChannelPlaylistsList(servers[0].url, 'root_channel', 0, 2, '-createdAt') + const body = await commands[0].listByChannel({ handle: 'root_channel', start: 0, count: 2, sort: '-createdAt' }) + expect(body.total).to.equal(1) - expect(res.body.total).to.equal(1) - - const data: VideoPlaylist[] = res.body.data + const data = body.data expect(data).to.have.lengthOf(1) expect(data[0].displayName).to.equal('my super playlist') } @@ -380,41 +351,37 @@ describe('Test video playlists', function () { this.timeout(30000) { - const res = await getAccountPlaylistsList(servers[1].url, 'root', 1, 2, '-createdAt') - - expect(res.body.total).to.equal(2) + const body = await servers[1].playlistsCommand.listByAccount({ handle: 'root', start: 1, count: 2, sort: '-createdAt' }) + expect(body.total).to.equal(2) - const data: VideoPlaylist[] = res.body.data + const data = body.data expect(data).to.have.lengthOf(1) expect(data[0].displayName).to.equal('playlist 2') } { - const res = await getAccountPlaylistsList(servers[1].url, 'root', 1, 2, 'createdAt') + const body = await servers[1].playlistsCommand.listByAccount({ handle: 'root', start: 1, count: 2, sort: 'createdAt' }) + expect(body.total).to.equal(2) - expect(res.body.total).to.equal(2) - - const data: VideoPlaylist[] = res.body.data + const data = body.data expect(data).to.have.lengthOf(1) expect(data[0].displayName).to.equal('playlist 3') } { - const res = await getAccountPlaylistsList(servers[1].url, 'root', 0, 10, 'createdAt', '3') - - expect(res.body.total).to.equal(1) + const body = await servers[1].playlistsCommand.listByAccount({ handle: 'root', sort: 'createdAt', search: '3' }) + expect(body.total).to.equal(1) - const data: VideoPlaylist[] = res.body.data + const data = body.data expect(data).to.have.lengthOf(1) expect(data[0].displayName).to.equal('playlist 3') } { - const res = await getAccountPlaylistsList(servers[1].url, 'root', 0, 10, 'createdAt', '4') - - expect(res.body.total).to.equal(0) + const body = await servers[1].playlistsCommand.listByAccount({ handle: 'root', sort: 'createdAt', search: '4' }) + expect(body.total).to.equal(0) - const data: VideoPlaylist[] = res.body.data + const data = body.data expect(data).to.have.lengthOf(0) } }) @@ -428,28 +395,22 @@ describe('Test video playlists', function () { this.timeout(30000) { - const res = await createVideoPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, - playlistAttrs: { + unlistedPlaylist = await servers[1].playlistsCommand.create({ + attributes: { displayName: 'playlist unlisted', privacy: VideoPlaylistPrivacy.UNLISTED, videoChannelId: servers[1].videoChannel.id } }) - unlistedPlaylist = res.body.videoPlaylist } { - const res = await createVideoPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, - playlistAttrs: { + privatePlaylist = await servers[1].playlistsCommand.create({ + attributes: { displayName: 'playlist private', privacy: VideoPlaylistPrivacy.PRIVATE } }) - privatePlaylist = res.body.videoPlaylist } await waitJobs(servers) @@ -459,15 +420,15 @@ describe('Test video playlists', function () { it('Should not list unlisted or private playlists', async function () { for (const server of servers) { const results = [ - await getAccountPlaylistsList(server.url, 'root@localhost:' + servers[1].port, 0, 5, '-createdAt'), - await getVideoPlaylistsList(server.url, 0, 2, '-createdAt') + await server.playlistsCommand.listByAccount({ handle: 'root@localhost:' + servers[1].port, sort: '-createdAt' }), + await server.playlistsCommand.list({ start: 0, count: 2, sort: '-createdAt' }) ] - expect(results[0].body.total).to.equal(2) - expect(results[1].body.total).to.equal(3) + expect(results[0].total).to.equal(2) + expect(results[1].total).to.equal(3) - for (const res of results) { - const data: VideoPlaylist[] = res.body.data + for (const body of results) { + const data = body.data expect(data).to.have.lengthOf(2) expect(data[0].displayName).to.equal('playlist 3') expect(data[1].displayName).to.equal('playlist 2') @@ -476,23 +437,23 @@ describe('Test video playlists', function () { }) it('Should not get unlisted playlist using only the id', async function () { - await getVideoPlaylist(servers[1].url, unlistedPlaylist.id, 404) + await servers[1].playlistsCommand.get({ playlistId: unlistedPlaylist.id, expectedStatus: 404 }) }) it('Should get unlisted plyaylist using uuid or shortUUID', async function () { - await getVideoPlaylist(servers[1].url, unlistedPlaylist.uuid) - await getVideoPlaylist(servers[1].url, unlistedPlaylist.shortUUID) + await servers[1].playlistsCommand.get({ playlistId: unlistedPlaylist.uuid }) + await servers[1].playlistsCommand.get({ playlistId: unlistedPlaylist.shortUUID }) }) it('Should not get private playlist without token', async function () { for (const id of [ privatePlaylist.id, privatePlaylist.uuid, privatePlaylist.shortUUID ]) { - await getVideoPlaylist(servers[1].url, id, 401) + await servers[1].playlistsCommand.get({ playlistId: id, expectedStatus: 401 }) } }) it('Should get private playlist with a token', async function () { for (const id of [ privatePlaylist.id, privatePlaylist.uuid, privatePlaylist.shortUUID ]) { - await getVideoPlaylistWithToken(servers[1].url, servers[1].accessToken, id) + await servers[1].playlistsCommand.get({ token: servers[1].accessToken, playlistId: id }) } }) }) @@ -502,10 +463,8 @@ describe('Test video playlists', function () { it('Should update a playlist', async function () { this.timeout(30000) - await updateVideoPlaylist({ - url: servers[1].url, - token: servers[1].accessToken, - playlistAttrs: { + await servers[1].playlistsCommand.update({ + attributes: { displayName: 'playlist 3 updated', description: 'description updated', privacy: VideoPlaylistPrivacy.UNLISTED, @@ -518,8 +477,7 @@ describe('Test video playlists', function () { await waitJobs(servers) for (const server of servers) { - const res = await getVideoPlaylist(server.url, playlistServer2UUID2) - const playlist: VideoPlaylist = res.body + const playlist = await server.playlistsCommand.get({ playlistId: playlistServer2UUID2 }) expect(playlist.displayName).to.equal('playlist 3 updated') expect(playlist.description).to.equal('description updated') @@ -545,39 +503,37 @@ describe('Test video playlists', function () { it('Should create a playlist containing different startTimestamp/endTimestamp videos', async function () { this.timeout(30000) - const addVideo = (elementAttrs: any) => { - return addVideoInPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: playlistServer1Id, elementAttrs }) + const addVideo = (attributes: any) => { + return commands[0].addElement({ playlistId: playlistServer1Id, attributes }) } - const res = await createVideoPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, - playlistAttrs: { + const playlist = await commands[0].create({ + attributes: { displayName: 'playlist 4', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[0].videoChannel.id } }) - playlistServer1Id = res.body.videoPlaylist.id - playlistServer1UUID = res.body.videoPlaylist.uuid + playlistServer1Id = playlist.id + playlistServer1UUID = playlist.uuid await addVideo({ videoId: servers[0].videos[0].uuid, startTimestamp: 15, stopTimestamp: 28 }) await addVideo({ videoId: servers[2].videos[1].uuid, startTimestamp: 35 }) await addVideo({ videoId: servers[2].videos[2].uuid }) { - const res = await addVideo({ videoId: servers[0].videos[3].uuid, stopTimestamp: 35 }) - playlistElementServer1Video4 = res.body.videoPlaylistElement.id + const element = await addVideo({ videoId: servers[0].videos[3].uuid, stopTimestamp: 35 }) + playlistElementServer1Video4 = element.id } { - const res = await addVideo({ videoId: servers[0].videos[4].uuid, startTimestamp: 45, stopTimestamp: 60 }) - playlistElementServer1Video5 = res.body.videoPlaylistElement.id + const element = await addVideo({ videoId: servers[0].videos[4].uuid, startTimestamp: 45, stopTimestamp: 60 }) + playlistElementServer1Video5 = element.id } { - const res = await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 5 }) - playlistElementNSFW = res.body.videoPlaylistElement.id + const element = await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 5 }) + playlistElementNSFW = element.id await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 4 }) await addVideo({ videoId: nsfwVideoServer1 }) @@ -590,55 +546,59 @@ describe('Test video playlists', function () { this.timeout(30000) for (const server of servers) { - const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) - - expect(res.body.total).to.equal(8) - - const videoElements: VideoPlaylistElement[] = res.body.data - expect(videoElements).to.have.lengthOf(8) - - expect(videoElements[0].video.name).to.equal('video 0 server 1') - expect(videoElements[0].position).to.equal(1) - expect(videoElements[0].startTimestamp).to.equal(15) - expect(videoElements[0].stopTimestamp).to.equal(28) - - expect(videoElements[1].video.name).to.equal('video 1 server 3') - expect(videoElements[1].position).to.equal(2) - expect(videoElements[1].startTimestamp).to.equal(35) - expect(videoElements[1].stopTimestamp).to.be.null - - expect(videoElements[2].video.name).to.equal('video 2 server 3') - expect(videoElements[2].position).to.equal(3) - expect(videoElements[2].startTimestamp).to.be.null - expect(videoElements[2].stopTimestamp).to.be.null - - expect(videoElements[3].video.name).to.equal('video 3 server 1') - expect(videoElements[3].position).to.equal(4) - expect(videoElements[3].startTimestamp).to.be.null - expect(videoElements[3].stopTimestamp).to.equal(35) - - expect(videoElements[4].video.name).to.equal('video 4 server 1') - expect(videoElements[4].position).to.equal(5) - expect(videoElements[4].startTimestamp).to.equal(45) - expect(videoElements[4].stopTimestamp).to.equal(60) - - expect(videoElements[5].video.name).to.equal('NSFW video') - expect(videoElements[5].position).to.equal(6) - expect(videoElements[5].startTimestamp).to.equal(5) - expect(videoElements[5].stopTimestamp).to.be.null - - expect(videoElements[6].video.name).to.equal('NSFW video') - expect(videoElements[6].position).to.equal(7) - expect(videoElements[6].startTimestamp).to.equal(4) - expect(videoElements[6].stopTimestamp).to.be.null - - expect(videoElements[7].video.name).to.equal('NSFW video') - expect(videoElements[7].position).to.equal(8) - expect(videoElements[7].startTimestamp).to.be.null - expect(videoElements[7].stopTimestamp).to.be.null - - const res3 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 2) - expect(res3.body.data).to.have.lengthOf(2) + { + const body = await server.playlistsCommand.listVideos({ playlistId: playlistServer1UUID, start: 0, count: 10 }) + + expect(body.total).to.equal(8) + + const videoElements = body.data + expect(videoElements).to.have.lengthOf(8) + + expect(videoElements[0].video.name).to.equal('video 0 server 1') + expect(videoElements[0].position).to.equal(1) + expect(videoElements[0].startTimestamp).to.equal(15) + expect(videoElements[0].stopTimestamp).to.equal(28) + + expect(videoElements[1].video.name).to.equal('video 1 server 3') + expect(videoElements[1].position).to.equal(2) + expect(videoElements[1].startTimestamp).to.equal(35) + expect(videoElements[1].stopTimestamp).to.be.null + + expect(videoElements[2].video.name).to.equal('video 2 server 3') + expect(videoElements[2].position).to.equal(3) + expect(videoElements[2].startTimestamp).to.be.null + expect(videoElements[2].stopTimestamp).to.be.null + + expect(videoElements[3].video.name).to.equal('video 3 server 1') + expect(videoElements[3].position).to.equal(4) + expect(videoElements[3].startTimestamp).to.be.null + expect(videoElements[3].stopTimestamp).to.equal(35) + + expect(videoElements[4].video.name).to.equal('video 4 server 1') + expect(videoElements[4].position).to.equal(5) + expect(videoElements[4].startTimestamp).to.equal(45) + expect(videoElements[4].stopTimestamp).to.equal(60) + + expect(videoElements[5].video.name).to.equal('NSFW video') + expect(videoElements[5].position).to.equal(6) + expect(videoElements[5].startTimestamp).to.equal(5) + expect(videoElements[5].stopTimestamp).to.be.null + + expect(videoElements[6].video.name).to.equal('NSFW video') + expect(videoElements[6].position).to.equal(7) + expect(videoElements[6].startTimestamp).to.equal(4) + expect(videoElements[6].stopTimestamp).to.be.null + + expect(videoElements[7].video.name).to.equal('NSFW video') + expect(videoElements[7].position).to.equal(8) + expect(videoElements[7].startTimestamp).to.be.null + expect(videoElements[7].stopTimestamp).to.be.null + } + + { + const body = await server.playlistsCommand.listVideos({ playlistId: playlistServer1UUID, start: 0, count: 2 }) + expect(body.data).to.have.lengthOf(2) + } } }) }) @@ -656,29 +616,28 @@ describe('Test video playlists', function () { before(async function () { this.timeout(60000) - groupUser1 = [ Object.assign({}, servers[0], { accessToken: userAccessTokenServer1 }) ] + groupUser1 = [ Object.assign({}, servers[0], { accessToken: userTokenServer1 }) ] groupWithoutToken1 = [ Object.assign({}, servers[0], { accessToken: undefined }) ] group1 = [ servers[0] ] group2 = [ servers[1], servers[2] ] - const res = await createVideoPlaylist({ - url: servers[0].url, - token: userAccessTokenServer1, - playlistAttrs: { + const playlist = await commands[0].create({ + token: userTokenServer1, + attributes: { displayName: 'playlist 56', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[0].videoChannel.id } }) - const playlistServer1Id2 = res.body.videoPlaylist.id - playlistServer1UUID2 = res.body.videoPlaylist.uuid + const playlistServer1Id2 = playlist.id + playlistServer1UUID2 = playlist.uuid - const addVideo = (elementAttrs: any) => { - return addVideoInPlaylist({ url: servers[0].url, token: userAccessTokenServer1, playlistId: playlistServer1Id2, elementAttrs }) + const addVideo = (attributes: any) => { + return commands[0].addElement({ token: userTokenServer1, playlistId: playlistServer1Id2, attributes }) } - video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 89', token: userAccessTokenServer1 })).uuid + video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 89', token: userTokenServer1 })).uuid video2 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 90' })).uuid video3 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 91', nsfw: true })).uuid @@ -756,26 +715,26 @@ describe('Test video playlists', function () { const position = 2 { - await command.addToMyBlocklist({ token: userAccessTokenServer1, account: 'root@localhost:' + servers[1].port }) + await command.addToMyBlocklist({ token: userTokenServer1, account: 'root@localhost:' + servers[1].port }) await waitJobs(servers) await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3) await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) - await command.removeFromMyBlocklist({ token: userAccessTokenServer1, account: 'root@localhost:' + servers[1].port }) + await command.removeFromMyBlocklist({ token: userTokenServer1, account: 'root@localhost:' + servers[1].port }) await waitJobs(servers) await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) } { - await command.addToMyBlocklist({ token: userAccessTokenServer1, server: 'localhost:' + servers[1].port }) + await command.addToMyBlocklist({ token: userTokenServer1, server: 'localhost:' + servers[1].port }) await waitJobs(servers) await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3) await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) - await command.removeFromMyBlocklist({ token: userAccessTokenServer1, server: 'localhost:' + servers[1].port }) + await command.removeFromMyBlocklist({ token: userTokenServer1, server: 'localhost:' + servers[1].port }) await waitJobs(servers) await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3) @@ -809,10 +768,10 @@ describe('Test video playlists', function () { }) it('Should hide the video if it is NSFW', async function () { - const res = await getPlaylistVideos(servers[0].url, userAccessTokenServer1, playlistServer1UUID2, 0, 10, { nsfw: false }) - expect(res.body.total).to.equal(3) + const body = await commands[0].listVideos({ token: userTokenServer1, playlistId: playlistServer1UUID2, query: { nsfw: 'false' } }) + expect(body.total).to.equal(3) - const elements: VideoPlaylistElement[] = res.body.data + const elements = body.data const element = elements.find(e => e.position === 3) expect(element).to.exist @@ -828,11 +787,9 @@ describe('Test video playlists', function () { this.timeout(30000) { - await reorderVideosPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, + await commands[0].reorderElements({ playlistId: playlistServer1Id, - elementAttrs: { + attributes: { startPosition: 2, insertAfterPosition: 3 } @@ -841,8 +798,8 @@ describe('Test video playlists', function () { await waitJobs(servers) for (const server of servers) { - const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) - const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name) + const body = await server.playlistsCommand.listVideos({ playlistId: playlistServer1UUID, start: 0, count: 10 }) + const names = body.data.map(v => v.video.name) expect(names).to.deep.equal([ 'video 0 server 1', @@ -858,11 +815,9 @@ describe('Test video playlists', function () { } { - await reorderVideosPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, + await commands[0].reorderElements({ playlistId: playlistServer1Id, - elementAttrs: { + attributes: { startPosition: 1, reorderLength: 3, insertAfterPosition: 4 @@ -872,8 +827,8 @@ describe('Test video playlists', function () { await waitJobs(servers) for (const server of servers) { - const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) - const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name) + const body = await server.playlistsCommand.listVideos({ playlistId: playlistServer1UUID, start: 0, count: 10 }) + const names = body.data.map(v => v.video.name) expect(names).to.deep.equal([ 'video 3 server 1', @@ -889,11 +844,9 @@ describe('Test video playlists', function () { } { - await reorderVideosPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, + await commands[0].reorderElements({ playlistId: playlistServer1Id, - elementAttrs: { + attributes: { startPosition: 6, insertAfterPosition: 3 } @@ -902,8 +855,7 @@ describe('Test video playlists', function () { await waitJobs(servers) for (const server of servers) { - const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) - const elements: VideoPlaylistElement[] = res.body.data + const { data: elements } = await server.playlistsCommand.listVideos({ playlistId: playlistServer1UUID, start: 0, count: 10 }) const names = elements.map(v => v.video.name) expect(names).to.deep.equal([ @@ -927,22 +879,18 @@ describe('Test video playlists', function () { it('Should update startTimestamp/endTimestamp of some elements', async function () { this.timeout(30000) - await updateVideoPlaylistElement({ - url: servers[0].url, - token: servers[0].accessToken, + await commands[0].updateElement({ playlistId: playlistServer1Id, - playlistElementId: playlistElementServer1Video4, - elementAttrs: { + elementId: playlistElementServer1Video4, + attributes: { startTimestamp: 1 } }) - await updateVideoPlaylistElement({ - url: servers[0].url, - token: servers[0].accessToken, + await commands[0].updateElement({ playlistId: playlistServer1Id, - playlistElementId: playlistElementServer1Video5, - elementAttrs: { + elementId: playlistElementServer1Video5, + attributes: { stopTimestamp: null } }) @@ -950,8 +898,7 @@ describe('Test video playlists', function () { await waitJobs(servers) for (const server of servers) { - const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) - const elements: VideoPlaylistElement[] = res.body.data + const { data: elements } = await server.playlistsCommand.listVideos({ playlistId: playlistServer1UUID, start: 0, count: 10 }) expect(elements[0].video.name).to.equal('video 3 server 1') expect(elements[0].position).to.equal(1) @@ -973,8 +920,7 @@ describe('Test video playlists', function () { 43000, servers[0].videos[4].id ] - const res = await doVideosExistInMyPlaylist(servers[0].url, servers[0].accessToken, videoIds) - const obj = res.body as VideoExistInPlaylist + const obj = await commands[0].videosExist({ videoIds }) { const elem = obj[servers[0].videos[0].id] @@ -1011,39 +957,26 @@ describe('Test video playlists', function () { const videoId = servers[1].videos[5].id async function getPlaylistNames () { - const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, undefined, '-updatedAt') + const { data } = await server.playlistsCommand.listByAccount({ token: server.accessToken, handle: 'root', sort: '-updatedAt' }) - return (res.body.data as VideoPlaylist[]).map(p => p.displayName) + return data.map(p => p.displayName) } - const elementAttrs = { videoId } - const res1 = await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id1, elementAttrs }) - const res2 = await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id2, elementAttrs }) - - const element1 = res1.body.videoPlaylistElement.id - const element2 = res2.body.videoPlaylistElement.id + const attributes = { videoId } + const element1 = await server.playlistsCommand.addElement({ playlistId: playlistServer2Id1, attributes }) + const element2 = await server.playlistsCommand.addElement({ playlistId: playlistServer2Id2, attributes }) const names1 = await getPlaylistNames() expect(names1[0]).to.equal('playlist 3 updated') expect(names1[1]).to.equal('playlist 2') - await removeVideoFromPlaylist({ - url: server.url, - token: server.accessToken, - playlistId: playlistServer2Id1, - playlistElementId: element1 - }) + await server.playlistsCommand.removeElement({ playlistId: playlistServer2Id1, elementId: element1.id }) const names2 = await getPlaylistNames() expect(names2[0]).to.equal('playlist 2') expect(names2[1]).to.equal('playlist 3 updated') - await removeVideoFromPlaylist({ - url: server.url, - token: server.accessToken, - playlistId: playlistServer2Id2, - playlistElementId: element2 - }) + await server.playlistsCommand.removeElement({ playlistId: playlistServer2Id2, elementId: element2.id }) const names3 = await getPlaylistNames() expect(names3[0]).to.equal('playlist 3 updated') @@ -1053,28 +986,16 @@ describe('Test video playlists', function () { it('Should delete some elements', async function () { this.timeout(30000) - await removeVideoFromPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, - playlistId: playlistServer1Id, - playlistElementId: playlistElementServer1Video4 - }) - - await removeVideoFromPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, - playlistId: playlistServer1Id, - playlistElementId: playlistElementNSFW - }) + await commands[0].removeElement({ playlistId: playlistServer1Id, elementId: playlistElementServer1Video4 }) + await commands[0].removeElement({ playlistId: playlistServer1Id, elementId: playlistElementNSFW }) await waitJobs(servers) for (const server of servers) { - const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) - - expect(res.body.total).to.equal(6) + const body = await server.playlistsCommand.listVideos({ playlistId: playlistServer1UUID, start: 0, count: 10 }) + expect(body.total).to.equal(6) - const elements: VideoPlaylistElement[] = res.body.data + const elements = body.data expect(elements).to.have.lengthOf(6) expect(elements[0].video.name).to.equal('video 0 server 1') @@ -1100,34 +1021,31 @@ describe('Test video playlists', function () { it('Should be able to create a public playlist, and set it to private', async function () { this.timeout(30000) - const res = await createVideoPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, - playlistAttrs: { + const videoPlaylistIds = await commands[0].create({ + attributes: { displayName: 'my super public playlist', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: servers[0].videoChannel.id } }) - const videoPlaylistIds = res.body.videoPlaylist await waitJobs(servers) for (const server of servers) { - await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.OK_200) + await server.playlistsCommand.get({ playlistId: videoPlaylistIds.uuid, expectedStatus: HttpStatusCode.OK_200 }) } - const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE } - await updateVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: videoPlaylistIds.id, playlistAttrs }) + const attributes = { privacy: VideoPlaylistPrivacy.PRIVATE } + await commands[0].update({ playlistId: videoPlaylistIds.id, attributes }) await waitJobs(servers) for (const server of [ servers[1], servers[2] ]) { - await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.NOT_FOUND_404) + await server.playlistsCommand.get({ playlistId: videoPlaylistIds.uuid, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) } - await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, HttpStatusCode.UNAUTHORIZED_401) - await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, HttpStatusCode.OK_200) + await commands[0].get({ playlistId: videoPlaylistIds.uuid, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) + await commands[0].get({ token: servers[0].accessToken, playlistId: videoPlaylistIds.uuid, expectedStatus: HttpStatusCode.OK_200 }) }) }) @@ -1136,12 +1054,12 @@ describe('Test video playlists', function () { it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () { this.timeout(30000) - await deleteVideoPlaylist(servers[0].url, servers[0].accessToken, playlistServer1Id) + await commands[0].delete({ playlistId: playlistServer1Id }) await waitJobs(servers) for (const server of servers) { - await getVideoPlaylist(server.url, playlistServer1UUID, HttpStatusCode.NOT_FOUND_404) + await server.playlistsCommand.get({ playlistId: playlistServer1UUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) } }) @@ -1156,21 +1074,22 @@ describe('Test video playlists', function () { it('Should unfollow servers 1 and 2 and hide their playlists', async function () { this.timeout(30000) - const finder = data => data.find(p => p.displayName === 'my super playlist') + const finder = (data: VideoPlaylist[]) => data.find(p => p.displayName === 'my super playlist') { - const res = await getVideoPlaylistsList(servers[2].url, 0, 5) - expect(res.body.total).to.equal(3) - expect(finder(res.body.data)).to.not.be.undefined + const body = await servers[2].playlistsCommand.list({ start: 0, count: 5 }) + expect(body.total).to.equal(3) + + expect(finder(body.data)).to.not.be.undefined } await servers[2].followsCommand.unfollow({ target: servers[0] }) { - const res = await getVideoPlaylistsList(servers[2].url, 0, 5) - expect(res.body.total).to.equal(1) + const body = await servers[2].playlistsCommand.list({ start: 0, count: 5 }) + expect(body.total).to.equal(1) - expect(finder(res.body.data)).to.be.undefined + expect(finder(body.data)).to.be.undefined } }) @@ -1180,16 +1099,13 @@ describe('Test video playlists', function () { const res = await addVideoChannel(servers[0].url, servers[0].accessToken, { name: 'super_channel', displayName: 'super channel' }) const videoChannelId = res.body.videoChannel.id - const res2 = await createVideoPlaylist({ - url: servers[0].url, - token: servers[0].accessToken, - playlistAttrs: { + const playlistCreated = await commands[0].create({ + attributes: { displayName: 'channel playlist', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId } }) - const videoPlaylistUUID = res2.body.videoPlaylist.uuid await waitJobs(servers) @@ -1197,11 +1113,11 @@ describe('Test video playlists', function () { await waitJobs(servers) - const res3 = await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistUUID) - expect(res3.body.displayName).to.equal('channel playlist') - expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE) + const body = await commands[0].get({ token: servers[0].accessToken, playlistId: playlistCreated.uuid }) + expect(body.displayName).to.equal('channel playlist') + expect(body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE) - await getVideoPlaylist(servers[1].url, videoPlaylistUUID, HttpStatusCode.NOT_FOUND_404) + await servers[1].playlistsCommand.get({ playlistId: playlistCreated.uuid, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) }) it('Should delete an account and delete its playlists', async function () { @@ -1221,10 +1137,8 @@ describe('Test video playlists', function () { const resChannel = await getMyUserInformation(servers[0].url, userAccessToken) const userChannel = (resChannel.body as User).videoChannels[0] - await createVideoPlaylist({ - url: servers[0].url, - token: userAccessToken, - playlistAttrs: { + await commands[0].create({ + attributes: { displayName: 'playlist to be deleted', privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: userChannel.id @@ -1233,12 +1147,13 @@ describe('Test video playlists', function () { await waitJobs(servers) - const finder = data => data.find(p => p.displayName === 'playlist to be deleted') + const finder = (data: VideoPlaylist[]) => data.find(p => p.displayName === 'playlist to be deleted') { for (const server of [ servers[0], servers[1] ]) { - const res = await getVideoPlaylistsList(server.url, 0, 15) - expect(finder(res.body.data)).to.not.be.undefined + const body = await server.playlistsCommand.list({ start: 0, count: 15 }) + + expect(finder(body.data)).to.not.be.undefined } } @@ -1247,8 +1162,9 @@ describe('Test video playlists', function () { { for (const server of [ servers[0], servers[1] ]) { - const res = await getVideoPlaylistsList(server.url, 0, 15) - expect(finder(res.body.data)).to.be.undefined + const body = await server.playlistsCommand.list({ start: 0, count: 15 }) + + expect(finder(body.data)).to.be.undefined } } }) diff --git a/server/tests/cli/prune-storage.ts b/server/tests/cli/prune-storage.ts index 95f573e50..fa1df65a9 100644 --- a/server/tests/cli/prune-storage.ts +++ b/server/tests/cli/prune-storage.ts @@ -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, diff --git a/server/tests/client.ts b/server/tests/client.ts index 60df878d7..129f1e1c0 100644 --- a/server/tests/client.ts +++ b/server/tests/client.ts @@ -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 diff --git a/server/tests/plugins/action-hooks.ts b/server/tests/plugins/action-hooks.ts index 5e9dc3515..fd83bf2ac 100644 --- a/server/tests/plugins/action-hooks.ts +++ b/server/tests/plugins/action-hooks.ts @@ -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') }) diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index e938663da..203642d8d 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts @@ -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) } } }) diff --git a/server/tests/plugins/video-constants.ts b/server/tests/plugins/video-constants.ts index 4124e8a52..4a05af042 100644 --- a/server/tests/plugins/video-constants.ts +++ b/server/tests/plugins/video-constants.ts @@ -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 diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts index 33f558414..78b3be9c7 100644 --- a/shared/extra-utils/server/servers.ts +++ b/shared/extra-utils/server/servers.ts @@ -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) }) diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts index 815c7f944..1f6241d7e 100644 --- a/shared/extra-utils/videos/index.ts +++ b/shared/extra-utils/videos/index.ts @@ -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' diff --git a/shared/extra-utils/videos/playlists-command.ts b/shared/extra-utils/videos/playlists-command.ts new file mode 100644 index 000000000..f77decc1a --- /dev/null +++ b/shared/extra-utils/videos/playlists-command.ts @@ -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>({ + ...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>({ + ...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>({ + ...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({ + ...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>({ + ...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({ + ...options, + + path, + query: { videoIds }, + implicitToken: true, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } +} diff --git a/shared/extra-utils/videos/playlists.ts b/shared/extra-utils/videos/playlists.ts new file mode 100644 index 000000000..023333c87 --- /dev/null +++ b/shared/extra-utils/videos/playlists.ts @@ -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 +} diff --git a/shared/extra-utils/videos/video-playlists.ts b/shared/extra-utils/videos/video-playlists.ts deleted file mode 100644 index c6f799e5d..000000000 --- a/shared/extra-utils/videos/video-playlists.ts +++ /dev/null @@ -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 -} diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index a45c0402a..920c93072 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -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, diff --git a/shared/models/videos/playlist/index.ts b/shared/models/videos/playlist/index.ts index f11a4bd28..a9e8ce496 100644 --- a/shared/models/videos/playlist/index.ts +++ b/shared/models/videos/playlist/index.ts @@ -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' diff --git a/shared/models/videos/playlist/video-playlist-element-create-result.model.ts b/shared/models/videos/playlist/video-playlist-element-create-result.model.ts new file mode 100644 index 000000000..dc475e7d8 --- /dev/null +++ b/shared/models/videos/playlist/video-playlist-element-create-result.model.ts @@ -0,0 +1,3 @@ +export interface VideoPlaylistElementCreateResult { + id: number +} -- 2.41.0