Add videos playlist exist tests
This commit is contained in:
parent
e2f01c47e0
commit
0b16f5f220
|
@ -49,7 +49,7 @@ storage:
|
||||||
tmp: '/var/www/peertube/storage/tmp/' # Used to download data (imports etc), store uploaded files before processing...
|
tmp: '/var/www/peertube/storage/tmp/' # Used to download data (imports etc), store uploaded files before processing...
|
||||||
avatars: '/var/www/peertube/storage/avatars/'
|
avatars: '/var/www/peertube/storage/avatars/'
|
||||||
videos: '/var/www/peertube/storage/videos/'
|
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/'
|
redundancy: '/var/www/peertube/storage/videos/'
|
||||||
logs: '/var/www/peertube/storage/logs/'
|
logs: '/var/www/peertube/storage/logs/'
|
||||||
previews: '/var/www/peertube/storage/previews/'
|
previews: '/var/www/peertube/storage/previews/'
|
||||||
|
|
|
@ -13,7 +13,7 @@ storage:
|
||||||
tmp: 'test1/tmp/'
|
tmp: 'test1/tmp/'
|
||||||
avatars: 'test1/avatars/'
|
avatars: 'test1/avatars/'
|
||||||
videos: 'test1/videos/'
|
videos: 'test1/videos/'
|
||||||
playlists: 'test1/playlists/'
|
streaming_playlists: 'test1/streaming-playlists/'
|
||||||
redundancy: 'test1/redundancy/'
|
redundancy: 'test1/redundancy/'
|
||||||
logs: 'test1/logs/'
|
logs: 'test1/logs/'
|
||||||
previews: 'test1/previews/'
|
previews: 'test1/previews/'
|
||||||
|
|
|
@ -13,7 +13,7 @@ storage:
|
||||||
tmp: 'test2/tmp/'
|
tmp: 'test2/tmp/'
|
||||||
avatars: 'test2/avatars/'
|
avatars: 'test2/avatars/'
|
||||||
videos: 'test2/videos/'
|
videos: 'test2/videos/'
|
||||||
playlists: 'test2/playlists/'
|
streaming_playlists: 'test2/streaming-playlists/'
|
||||||
redundancy: 'test2/redundancy/'
|
redundancy: 'test2/redundancy/'
|
||||||
logs: 'test2/logs/'
|
logs: 'test2/logs/'
|
||||||
previews: 'test2/previews/'
|
previews: 'test2/previews/'
|
||||||
|
|
|
@ -13,7 +13,7 @@ storage:
|
||||||
tmp: 'test3/tmp/'
|
tmp: 'test3/tmp/'
|
||||||
avatars: 'test3/avatars/'
|
avatars: 'test3/avatars/'
|
||||||
videos: 'test3/videos/'
|
videos: 'test3/videos/'
|
||||||
playlists: 'test3/playlists/'
|
streaming_playlists: 'test3/streaming-playlists/'
|
||||||
redundancy: 'test3/redundancy/'
|
redundancy: 'test3/redundancy/'
|
||||||
logs: 'test3/logs/'
|
logs: 'test3/logs/'
|
||||||
previews: 'test3/previews/'
|
previews: 'test3/previews/'
|
||||||
|
|
|
@ -13,7 +13,7 @@ storage:
|
||||||
tmp: 'test4/tmp/'
|
tmp: 'test4/tmp/'
|
||||||
avatars: 'test4/avatars/'
|
avatars: 'test4/avatars/'
|
||||||
videos: 'test4/videos/'
|
videos: 'test4/videos/'
|
||||||
playlists: 'test4/playlists/'
|
streaming_playlists: 'test4/streaming-playlists/'
|
||||||
redundancy: 'test4/redundancy/'
|
redundancy: 'test4/redundancy/'
|
||||||
logs: 'test4/logs/'
|
logs: 'test4/logs/'
|
||||||
previews: 'test4/previews/'
|
previews: 'test4/previews/'
|
||||||
|
|
|
@ -13,7 +13,7 @@ storage:
|
||||||
tmp: 'test5/tmp/'
|
tmp: 'test5/tmp/'
|
||||||
avatars: 'test5/avatars/'
|
avatars: 'test5/avatars/'
|
||||||
videos: 'test5/videos/'
|
videos: 'test5/videos/'
|
||||||
playlists: 'test5/playlists/'
|
streaming_playlists: 'test5/streaming-playlists/'
|
||||||
redundancy: 'test5/redundancy/'
|
redundancy: 'test5/redundancy/'
|
||||||
logs: 'test5/logs/'
|
logs: 'test5/logs/'
|
||||||
previews: 'test5/previews/'
|
previews: 'test5/previews/'
|
||||||
|
|
|
@ -13,7 +13,7 @@ storage:
|
||||||
tmp: 'test6/tmp/'
|
tmp: 'test6/tmp/'
|
||||||
avatars: 'test6/avatars/'
|
avatars: 'test6/avatars/'
|
||||||
videos: 'test6/videos/'
|
videos: 'test6/videos/'
|
||||||
playlists: 'test6/playlists/'
|
streaming_playlists: 'test6/streaming-playlists/'
|
||||||
redundancy: 'test6/redundancy/'
|
redundancy: 'test6/redundancy/'
|
||||||
logs: 'test6/logs/'
|
logs: 'test6/logs/'
|
||||||
previews: 'test6/previews/'
|
previews: 'test6/previews/'
|
||||||
|
|
|
@ -357,7 +357,7 @@ async function actorFollowers (req: express.Request, actor: ActorModel) {
|
||||||
|
|
||||||
async function actorPlaylists (req: express.Request, account: AccountModel) {
|
async function actorPlaylists (req: express.Request, account: AccountModel) {
|
||||||
const handler = (start: number, count: number) => {
|
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)
|
return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page)
|
||||||
|
|
|
@ -22,7 +22,7 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async function doVideosInPlaylistExist (req: express.Request, res: express.Response) {
|
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 user = res.locals.oauth.token.User as UserModel
|
||||||
|
|
||||||
const results = await VideoPlaylistModel.listPlaylistIdsOf(user.Account.id, videoIds)
|
const results = await VideoPlaylistModel.listPlaylistIdsOf(user.Account.id, videoIds)
|
||||||
|
|
|
@ -4,9 +4,9 @@ import { UserRight } from '../../../../shared'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { UserModel } from '../../../models/account/user'
|
import { UserModel } from '../../../models/account/user'
|
||||||
import { areValidationErrors } from '../utils'
|
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 { 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 {
|
import {
|
||||||
isVideoPlaylistDescriptionValid,
|
isVideoPlaylistDescriptionValid,
|
||||||
isVideoPlaylistExist,
|
isVideoPlaylistExist,
|
||||||
|
@ -23,7 +23,6 @@ import { VideoModel } from '../../../models/video/video'
|
||||||
import { authenticatePromiseIfNeeded } from '../../oauth'
|
import { authenticatePromiseIfNeeded } from '../../oauth'
|
||||||
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
||||||
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
|
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
|
||||||
import { areValidActorHandles } from '../../../helpers/custom-validators/activitypub/actor'
|
|
||||||
|
|
||||||
const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
|
const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
|
||||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
|
|
|
@ -301,13 +301,14 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static listUrlsOfForAP (accountId: number, start: number, count: number) {
|
static listPublicUrlsOfForAP (accountId: number, start: number, count: number) {
|
||||||
const query = {
|
const query = {
|
||||||
attributes: [ 'url' ],
|
attributes: [ 'url' ],
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
where: {
|
where: {
|
||||||
ownerAccountId: accountId
|
ownerAccountId: accountId,
|
||||||
|
privacy: VideoPlaylistPrivacy.PUBLIC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 () {
|
describe('When deleting an element in a playlist', function () {
|
||||||
const getBase = (wrapper: any = {}) => {
|
const getBase = (wrapper: any = {}) => {
|
||||||
return Object.assign({
|
return Object.assign({
|
||||||
|
|
|
@ -184,7 +184,7 @@ async function check1PlaylistRedundancies (videoUUID?: string) {
|
||||||
expect(redundancy.baseUrl).to.equal(servers[0].url + '/static/redundancy/hls/' + videoUUID)
|
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 baseUrlSegment = servers[0].url + '/static/redundancy/hls'
|
||||||
|
|
||||||
const res = await getVideo(servers[0].url, videoUUID)
|
const res = await getVideo(servers[0].url, videoUUID)
|
||||||
|
@ -194,7 +194,7 @@ async function check1PlaylistRedundancies (videoUUID?: string) {
|
||||||
await checkSegmentHash(baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist)
|
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))
|
const files = await readdir(join(root(), directory, videoUUID))
|
||||||
expect(files).to.have.length.at.least(4)
|
expect(files).to.have.length.at.least(4)
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string) {
|
||||||
|
|
||||||
{
|
{
|
||||||
for (const resolution of resolutions) {
|
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
|
const subPlaylist = res2.text
|
||||||
expect(subPlaylist).to.contain(`${videoUUID}-${resolution}-fragmented.mp4`)
|
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) {
|
for (const resolution of resolutions) {
|
||||||
await checkSegmentHash(baseUrl, baseUrl, videoUUID, resolution, hlsPlaylist)
|
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 () {
|
it('Should have the playlists/segment deleted from the disk', async function () {
|
||||||
for (const server of servers) {
|
for (const server of servers) {
|
||||||
await checkDirectoryIsEmpty(server, 'videos')
|
await checkDirectoryIsEmpty(server, 'videos')
|
||||||
await checkDirectoryIsEmpty(server, join('playlists', 'hls'))
|
await checkDirectoryIsEmpty(server, join('streaming-playlists', 'hls'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
createVideoPlaylist,
|
createVideoPlaylist,
|
||||||
deleteVideoChannel,
|
deleteVideoChannel,
|
||||||
deleteVideoPlaylist,
|
deleteVideoPlaylist,
|
||||||
doubleFollow,
|
doubleFollow, doVideosExistInMyPlaylist,
|
||||||
flushAndRunMultipleServers,
|
flushAndRunMultipleServers,
|
||||||
flushTests,
|
flushTests,
|
||||||
getAccountPlaylistsList,
|
getAccountPlaylistsList,
|
||||||
|
@ -41,6 +41,7 @@ import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/
|
||||||
import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model'
|
import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model'
|
||||||
import { Video } from '../../../../shared/models/videos'
|
import { Video } from '../../../../shared/models/videos'
|
||||||
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
|
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
|
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 () {
|
it('Should delete some elements', async function () {
|
||||||
this.timeout(30000)
|
this.timeout(30000)
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
export {
|
||||||
|
@ -298,5 +310,7 @@ export {
|
||||||
|
|
||||||
reorderVideosPlaylist,
|
reorderVideosPlaylist,
|
||||||
|
|
||||||
checkPlaylistFilesWereRemoved
|
checkPlaylistFilesWereRemoved,
|
||||||
|
|
||||||
|
doVideosExistInMyPlaylist
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue