Add videos playlist exist tests
authorChocobozzz <me@florianbigard.com>
Wed, 13 Mar 2019 15:03:03 +0000 (16:03 +0100)
committerChocobozzz <chocobozzz@cpy.re>
Mon, 18 Mar 2019 10:17:59 +0000 (11:17 +0100)
16 files changed:
config/production.yaml.example
config/test-1.yaml
config/test-2.yaml
config/test-3.yaml
config/test-4.yaml
config/test-5.yaml
config/test-6.yaml
server/controllers/activitypub/client.ts
server/controllers/api/users/my-video-playlists.ts
server/middlewares/validators/videos/video-playlists.ts
server/models/video/video-playlist.ts
server/tests/api/check-params/video-playlists.ts
server/tests/api/redundancy/redundancy.ts
server/tests/api/videos/video-hls.ts
server/tests/api/videos/video-playlists.ts
shared/utils/videos/video-playlists.ts

index c227d5fcc0e87e8ed60b1d69e37867a77adcf321..306e5576d8b6f9c37a63ab2a1039bf5dd74bd6d5 100644 (file)
@@ -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/'
index fb69818f39d8052373b25a5bf720cdcbca35f6a1..413390ecdfa9063a8e0fb8986123ed1069f892a6 100644 (file)
@@ -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/'
index 5caddaaa8c9a8c5b3e4071e9e89cc870cafb1da7..a5515afa4f23d6acd66c2a8db73b9052c58e24a7 100644 (file)
@@ -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/'
index fac7ebee1d9ebd91af5b1bc26909719b4349367f..ef6780328597b0db30953d141519232069795a03 100644 (file)
@@ -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/'
index 33033773a5901f23800b02579e132c45fae2d1e6..e84b2d118feee9c36a3383d19ed6e33a10fa8686 100644 (file)
@@ -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/'
index d365b6f2ba026bdb6fbb57a894da597e82f94c95..e25d4cfee33d113c84fb4ad7d917fa2f477addd6 100644 (file)
@@ -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/'
index 44541c00378b753490d8d44443e39b35ef4d9844..a020fe869c60628c770161ccf8afa84b0664029f 100644 (file)
@@ -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/'
index 0d1dff96f2e41592f01e0a22557d2ec5901e78b2..f1217f6dbaf09c18181259c21741ea9b50dee35e 100644 (file)
@@ -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)
index 1ec175f6496f4f2b0f83cc7a50b5fff9735d299c..42da02bff975f004190b1b0ec82525d01ec44d10 100644 (file)
@@ -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)
index 87d2c7b5135e15ae2935e8ead06f9c20f49dbf56..3bbf796e4ee34ad9b871ea8fdb34974ad73f73e4 100644 (file)
@@ -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) => {
index aa42687cd131656b90a6340f7f0adf5d4b12a057..7dbe4ce8d3cf61b9b7949619e95290bb9ba09b59 100644 (file)
@@ -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 = {
       attributes: [ 'url' ],
       offset: start,
       limit: count,
       where: {
-        ownerAccountId: accountId
+        ownerAccountId: accountId,
+        privacy: VideoPlaylistPrivacy.PUBLIC
       }
     }
 
index 803e7afb9cfd8945e92ed3a1dd9031004683aae7..4d8000dbf766425214ad3b5aa37396d9ded2cf7d 100644 (file)
@@ -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({
index fc5ffbad7b67f020dedf188b40c18dbf7e6521c7..33921763da2433927f8a1d8eb924ce83729bea34 100644 (file)
@@ -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)
 
index a1214bad165b5d46d9152625bf9b90fa310cc90c..3d04758b16101ded78ba10048c72961ba8a454bd 100644 (file)
@@ -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'))
     }
   })
 
index baa2b3b8cefd9b92000a057910e569ec8bf19a90..931491406e84dede6605ada43734169ef1453663 100644 (file)
@@ -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)
 
index b84b21623521cdea912a98722a03b18e79f95aef..ad65bec5685973f215f7b75d56d44ea9457e1238 100644 (file)
@@ -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
 }