From 0b16f5f2202e0c0832b5e678fadd95c64b8e8789 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 13 Mar 2019 16:03:03 +0100 Subject: [PATCH] Add videos playlist exist tests --- config/production.yaml.example | 2 +- config/test-1.yaml | 2 +- config/test-2.yaml | 2 +- config/test-3.yaml | 2 +- config/test-4.yaml | 2 +- config/test-5.yaml | 2 +- config/test-6.yaml | 2 +- server/controllers/activitypub/client.ts | 2 +- .../api/users/my-video-playlists.ts | 2 +- .../validators/videos/video-playlists.ts | 5 +- server/models/video/video-playlist.ts | 5 +- .../tests/api/check-params/video-playlists.ts | 46 +++++++++++++++++++ server/tests/api/redundancy/redundancy.ts | 4 +- server/tests/api/videos/video-hls.ts | 6 +-- server/tests/api/videos/video-playlists.ts | 42 ++++++++++++++++- shared/utils/videos/video-playlists.ts | 16 ++++++- 16 files changed, 121 insertions(+), 21 deletions(-) diff --git a/config/production.yaml.example b/config/production.yaml.example index c227d5fcc..306e5576d 100644 --- a/config/production.yaml.example +++ b/config/production.yaml.example @@ -49,7 +49,7 @@ storage: tmp: '/var/www/peertube/storage/tmp/' # Used to download data (imports etc), store uploaded files before processing... avatars: '/var/www/peertube/storage/avatars/' videos: '/var/www/peertube/storage/videos/' - playlists: '/var/www/peertube/storage/playlists/' + streaming_playlists: '/var/www/peertube/storage/streaming-playlists/' redundancy: '/var/www/peertube/storage/videos/' logs: '/var/www/peertube/storage/logs/' previews: '/var/www/peertube/storage/previews/' diff --git a/config/test-1.yaml b/config/test-1.yaml index fb69818f3..413390ecd 100644 --- a/config/test-1.yaml +++ b/config/test-1.yaml @@ -13,7 +13,7 @@ storage: tmp: 'test1/tmp/' avatars: 'test1/avatars/' videos: 'test1/videos/' - playlists: 'test1/playlists/' + streaming_playlists: 'test1/streaming-playlists/' redundancy: 'test1/redundancy/' logs: 'test1/logs/' previews: 'test1/previews/' diff --git a/config/test-2.yaml b/config/test-2.yaml index 5caddaaa8..a5515afa4 100644 --- a/config/test-2.yaml +++ b/config/test-2.yaml @@ -13,7 +13,7 @@ storage: tmp: 'test2/tmp/' avatars: 'test2/avatars/' videos: 'test2/videos/' - playlists: 'test2/playlists/' + streaming_playlists: 'test2/streaming-playlists/' redundancy: 'test2/redundancy/' logs: 'test2/logs/' previews: 'test2/previews/' diff --git a/config/test-3.yaml b/config/test-3.yaml index fac7ebee1..ef6780328 100644 --- a/config/test-3.yaml +++ b/config/test-3.yaml @@ -13,7 +13,7 @@ storage: tmp: 'test3/tmp/' avatars: 'test3/avatars/' videos: 'test3/videos/' - playlists: 'test3/playlists/' + streaming_playlists: 'test3/streaming-playlists/' redundancy: 'test3/redundancy/' logs: 'test3/logs/' previews: 'test3/previews/' diff --git a/config/test-4.yaml b/config/test-4.yaml index 33033773a..e84b2d118 100644 --- a/config/test-4.yaml +++ b/config/test-4.yaml @@ -13,7 +13,7 @@ storage: tmp: 'test4/tmp/' avatars: 'test4/avatars/' videos: 'test4/videos/' - playlists: 'test4/playlists/' + streaming_playlists: 'test4/streaming-playlists/' redundancy: 'test4/redundancy/' logs: 'test4/logs/' previews: 'test4/previews/' diff --git a/config/test-5.yaml b/config/test-5.yaml index d365b6f2b..e25d4cfee 100644 --- a/config/test-5.yaml +++ b/config/test-5.yaml @@ -13,7 +13,7 @@ storage: tmp: 'test5/tmp/' avatars: 'test5/avatars/' videos: 'test5/videos/' - playlists: 'test5/playlists/' + streaming_playlists: 'test5/streaming-playlists/' redundancy: 'test5/redundancy/' logs: 'test5/logs/' previews: 'test5/previews/' diff --git a/config/test-6.yaml b/config/test-6.yaml index 44541c003..a020fe869 100644 --- a/config/test-6.yaml +++ b/config/test-6.yaml @@ -13,7 +13,7 @@ storage: tmp: 'test6/tmp/' avatars: 'test6/avatars/' videos: 'test6/videos/' - playlists: 'test6/playlists/' + streaming_playlists: 'test6/streaming-playlists/' redundancy: 'test6/redundancy/' logs: 'test6/logs/' previews: 'test6/previews/' diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 0d1dff96f..f1217f6db 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts @@ -357,7 +357,7 @@ async function actorFollowers (req: express.Request, actor: ActorModel) { async function actorPlaylists (req: express.Request, account: AccountModel) { const handler = (start: number, count: number) => { - return VideoPlaylistModel.listUrlsOfForAP(account.id, start, count) + return VideoPlaylistModel.listPublicUrlsOfForAP(account.id, start, count) } return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page) diff --git a/server/controllers/api/users/my-video-playlists.ts b/server/controllers/api/users/my-video-playlists.ts index 1ec175f64..42da02bff 100644 --- a/server/controllers/api/users/my-video-playlists.ts +++ b/server/controllers/api/users/my-video-playlists.ts @@ -22,7 +22,7 @@ export { // --------------------------------------------------------------------------- async function doVideosInPlaylistExist (req: express.Request, res: express.Response) { - const videoIds = req.query.videoIds as number[] + const videoIds = req.query.videoIds.map(i => parseInt(i + '', 10)) const user = res.locals.oauth.token.User as UserModel const results = await VideoPlaylistModel.listPlaylistIdsOf(user.Account.id, videoIds) diff --git a/server/middlewares/validators/videos/video-playlists.ts b/server/middlewares/validators/videos/video-playlists.ts index 87d2c7b51..3bbf796e4 100644 --- a/server/middlewares/validators/videos/video-playlists.ts +++ b/server/middlewares/validators/videos/video-playlists.ts @@ -4,9 +4,9 @@ import { UserRight } from '../../../../shared' import { logger } from '../../../helpers/logger' import { UserModel } from '../../../models/account/user' import { areValidationErrors } from '../utils' -import { isVideoExist, isVideoFileInfoHashValid, isVideoImage } from '../../../helpers/custom-validators/videos' +import { isVideoExist, isVideoImage } from '../../../helpers/custom-validators/videos' import { CONSTRAINTS_FIELDS } from '../../../initializers' -import { isArrayOf, isIdOrUUIDValid, isIdValid, isUUIDValid, toArray, toValueOrNull, toIntArray } from '../../../helpers/custom-validators/misc' +import { isArrayOf, isIdOrUUIDValid, isIdValid, isUUIDValid, toIntArray, toValueOrNull } from '../../../helpers/custom-validators/misc' import { isVideoPlaylistDescriptionValid, isVideoPlaylistExist, @@ -23,7 +23,6 @@ import { VideoModel } from '../../../models/video/video' import { authenticatePromiseIfNeeded } from '../../oauth' import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model' -import { areValidActorHandles } from '../../../helpers/custom-validators/activitypub/actor' const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([ async (req: express.Request, res: express.Response, next: express.NextFunction) => { diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index aa42687cd..7dbe4ce8d 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts @@ -301,13 +301,14 @@ export class VideoPlaylistModel extends Model { }) } - static listUrlsOfForAP (accountId: number, start: number, count: number) { + static listPublicUrlsOfForAP (accountId: number, start: number, count: number) { const query = { attributes: [ 'url' ], offset: start, limit: count, where: { - ownerAccountId: accountId + ownerAccountId: accountId, + privacy: VideoPlaylistPrivacy.PUBLIC } } diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts index 803e7afb9..4d8000dbf 100644 --- a/server/tests/api/check-params/video-playlists.ts +++ b/server/tests/api/check-params/video-playlists.ts @@ -522,6 +522,52 @@ describe('Test video playlists API validator', function () { }) }) + describe('When checking exists in playlist endpoint', function () { + const path = '/api/v1/users/me/video-playlists/videos-exist' + + it('Should fail with an unauthenticated user', async function () { + await makeGetRequest({ + url: server.url, + path, + query: { videoIds: [ 1, 2 ] }, + statusCodeExpected: 401 + }) + }) + + it('Should fail with invalid video ids', async function () { + await makeGetRequest({ + url: server.url, + token: server.accessToken, + path, + query: { videoIds: 'toto' } + }) + + await makeGetRequest({ + url: server.url, + token: server.accessToken, + path, + query: { videoIds: [ 'toto' ] } + }) + + await makeGetRequest({ + url: server.url, + token: server.accessToken, + path, + query: { videoIds: [ 1, 'toto' ] } + }) + }) + + it('Should succeed with the correct params', async function () { + await makeGetRequest({ + url: server.url, + token: server.accessToken, + path, + query: { videoIds: [ 1, 2 ] }, + statusCodeExpected: 200 + }) + }) + }) + describe('When deleting an element in a playlist', function () { const getBase = (wrapper: any = {}) => { return Object.assign({ diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts index fc5ffbad7..33921763d 100644 --- a/server/tests/api/redundancy/redundancy.ts +++ b/server/tests/api/redundancy/redundancy.ts @@ -184,7 +184,7 @@ async function check1PlaylistRedundancies (videoUUID?: string) { expect(redundancy.baseUrl).to.equal(servers[0].url + '/static/redundancy/hls/' + videoUUID) } - const baseUrlPlaylist = servers[1].url + '/static/playlists/hls' + const baseUrlPlaylist = servers[1].url + '/static/streaming-playlists/hls' const baseUrlSegment = servers[0].url + '/static/redundancy/hls' const res = await getVideo(servers[0].url, videoUUID) @@ -194,7 +194,7 @@ async function check1PlaylistRedundancies (videoUUID?: string) { await checkSegmentHash(baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist) } - for (const directory of [ 'test1/redundancy/hls', 'test2/playlists/hls' ]) { + for (const directory of [ 'test1/redundancy/hls', 'test2/streaming-playlists/hls' ]) { const files = await readdir(join(root(), directory, videoUUID)) expect(files).to.have.length.at.least(4) diff --git a/server/tests/api/videos/video-hls.ts b/server/tests/api/videos/video-hls.ts index a1214bad1..3d04758b1 100644 --- a/server/tests/api/videos/video-hls.ts +++ b/server/tests/api/videos/video-hls.ts @@ -51,7 +51,7 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string) { { for (const resolution of resolutions) { - const res2 = await getPlaylist(`http://localhost:9001/static/playlists/hls/${videoUUID}/${resolution}.m3u8`) + const res2 = await getPlaylist(`http://localhost:9001/static/streaming-playlists/hls/${videoUUID}/${resolution}.m3u8`) const subPlaylist = res2.text expect(subPlaylist).to.contain(`${videoUUID}-${resolution}-fragmented.mp4`) @@ -59,7 +59,7 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string) { } { - const baseUrl = 'http://localhost:9001/static/playlists/hls' + const baseUrl = 'http://localhost:9001/static/streaming-playlists/hls' for (const resolution of resolutions) { await checkSegmentHash(baseUrl, baseUrl, videoUUID, resolution, hlsPlaylist) @@ -118,7 +118,7 @@ describe('Test HLS videos', function () { it('Should have the playlists/segment deleted from the disk', async function () { for (const server of servers) { await checkDirectoryIsEmpty(server, 'videos') - await checkDirectoryIsEmpty(server, join('playlists', 'hls')) + await checkDirectoryIsEmpty(server, join('streaming-playlists', 'hls')) } }) diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts index baa2b3b8c..931491406 100644 --- a/server/tests/api/videos/video-playlists.ts +++ b/server/tests/api/videos/video-playlists.ts @@ -10,7 +10,7 @@ import { createVideoPlaylist, deleteVideoChannel, deleteVideoPlaylist, - doubleFollow, + doubleFollow, doVideosExistInMyPlaylist, flushAndRunMultipleServers, flushTests, getAccountPlaylistsList, @@ -41,6 +41,7 @@ import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/ import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model' import { Video } from '../../../../shared/models/videos' import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model' +import { VideoExistInPlaylist } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model' const expect = chai.expect @@ -624,6 +625,45 @@ describe('Test video playlists', function () { } }) + it('Should check videos existence in my playlist', async function () { + const videoIds = [ + servers[0].videos[0].id, + 42000, + servers[0].videos[3].id, + 43000, + servers[0].videos[4].id + ] + const res = await doVideosExistInMyPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, videoIds) + const obj = res.body as VideoExistInPlaylist + + { + const elem = obj[servers[0].videos[0].id] + expect(elem).to.have.lengthOf(1) + expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) + expect(elem[ 0 ].startTimestamp).to.equal(15) + expect(elem[ 0 ].stopTimestamp).to.equal(28) + } + + { + const elem = obj[servers[0].videos[3].id] + expect(elem).to.have.lengthOf(1) + expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) + expect(elem[ 0 ].startTimestamp).to.equal(1) + expect(elem[ 0 ].stopTimestamp).to.equal(35) + } + + { + const elem = obj[servers[0].videos[4].id] + expect(elem).to.have.lengthOf(1) + expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) + expect(elem[ 0 ].startTimestamp).to.equal(45) + expect(elem[ 0 ].stopTimestamp).to.equal(null) + } + + expect(obj[42000]).to.have.lengthOf(0) + expect(obj[43000]).to.have.lengthOf(0) + }) + it('Should delete some elements', async function () { this.timeout(30000) diff --git a/shared/utils/videos/video-playlists.ts b/shared/utils/videos/video-playlists.ts index b84b21623..ad65bec56 100644 --- a/shared/utils/videos/video-playlists.ts +++ b/shared/utils/videos/video-playlists.ts @@ -275,6 +275,18 @@ function getVideoPlaylistPrivacies (url: string) { }) } +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: 200 + }) +} + // --------------------------------------------------------------------------- export { @@ -298,5 +310,7 @@ export { reorderVideosPlaylist, - checkPlaylistFilesWereRemoved + checkPlaylistFilesWereRemoved, + + doVideosExistInMyPlaylist } -- 2.25.1