]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/tests/api/videos/videos-common-filters.ts
Fix s3 mock cleanup
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / videos-common-filters.ts
index eb2d2ab509192fc5eba78b27f14e8af56614e967..30251706b6d74b27b3c4142f78de2b60ad083ced 100644 (file)
@@ -1,8 +1,8 @@
 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
 
-import 'mocha'
 import { expect } from 'chai'
 import { pick } from '@shared/core-utils'
+import { HttpStatusCode, UserRole, Video, VideoDetails, VideoInclude, VideoPrivacy } from '@shared/models'
 import {
   cleanupTests,
   createMultipleServers,
@@ -10,25 +10,30 @@ import {
   makeGetRequest,
   PeerTubeServer,
   setAccessTokensToServers,
+  setDefaultAccountAvatar,
   setDefaultVideoChannel,
   waitJobs
-} from '@shared/extra-utils'
-import { HttpStatusCode, UserRole, Video, VideoInclude, VideoPrivacy } from '@shared/models'
+} from '@shared/server-commands'
 
 describe('Test videos filter', function () {
   let servers: PeerTubeServer[]
   let paths: string[]
   let remotePaths: string[]
 
+  const subscriptionVideosPath = '/api/v1/users/me/subscriptions/videos'
+
   // ---------------------------------------------------------------
 
   before(async function () {
-    this.timeout(160000)
+    this.timeout(240000)
 
     servers = await createMultipleServers(2)
 
     await setAccessTokensToServers(servers)
     await setDefaultVideoChannel(servers)
+    await setDefaultAccountAvatar(servers)
+
+    await servers[1].config.enableMinimumTranscoding()
 
     for (const server of servers) {
       const moderator = { username: 'moderator', password: 'my super password' }
@@ -46,6 +51,9 @@ describe('Test videos filter', function () {
         const attributes = { name: 'private ' + server.serverNumber, privacy: VideoPrivacy.PRIVATE }
         await server.videos.upload({ attributes })
       }
+
+      // Subscribing to itself
+      await server.subscriptions.add({ targetUri: 'root_channel@' + server.host })
     }
 
     await doubleFollow(servers[0], servers[1])
@@ -54,7 +62,8 @@ describe('Test videos filter', function () {
       `/api/v1/video-channels/root_channel/videos`,
       `/api/v1/accounts/root/videos`,
       '/api/v1/videos',
-      '/api/v1/search/videos'
+      '/api/v1/search/videos',
+      subscriptionVideosPath
     ]
 
     remotePaths = [
@@ -67,10 +76,20 @@ describe('Test videos filter', function () {
 
   describe('Check deprecated videos filter', function () {
 
-    async function getVideosNames (server: PeerTubeServer, token: string, filter: string, expectedStatus = HttpStatusCode.OK_200) {
+    async function getVideosNames (options: {
+      server: PeerTubeServer
+      token: string
+      filter: string
+      skipSubscription?: boolean
+      expectedStatus?: HttpStatusCode
+    }) {
+      const { server, token, filter, skipSubscription = false, expectedStatus = HttpStatusCode.OK_200 } = options
+
       const videosResults: Video[][] = []
 
       for (const path of paths) {
+        if (skipSubscription && path === subscriptionVideosPath) continue
+
         const res = await makeGetRequest({
           url: server.url,
           path,
@@ -90,7 +109,7 @@ describe('Test videos filter', function () {
 
     it('Should display local videos', async function () {
       for (const server of servers) {
-        const namesResults = await getVideosNames(server, server.accessToken, 'local')
+        const namesResults = await getVideosNames({ server, token: server.accessToken, filter: 'local' })
         for (const names of namesResults) {
           expect(names).to.have.lengthOf(1)
           expect(names[0]).to.equal('public ' + server.serverNumber)
@@ -102,7 +121,7 @@ describe('Test videos filter', function () {
       for (const server of servers) {
         for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
 
-          const namesResults = await getVideosNames(server, token, 'all-local')
+          const namesResults = await getVideosNames({ server, token, filter: 'all-local', skipSubscription: true })
           for (const names of namesResults) {
             expect(names).to.have.lengthOf(3)
 
@@ -118,7 +137,7 @@ describe('Test videos filter', function () {
       for (const server of servers) {
         for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
 
-          const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames(server, token, 'all')
+          const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames({ server, token, filter: 'all' })
           expect(channelVideos).to.have.lengthOf(3)
           expect(accountVideos).to.have.lengthOf(3)
 
@@ -135,18 +154,31 @@ describe('Test videos filter', function () {
       server: PeerTubeServer
       path: string
       isLocal?: boolean
+      hasWebtorrentFiles?: boolean
+      hasHLSFiles?: boolean
       include?: VideoInclude
+      privacyOneOf?: VideoPrivacy[]
       category?: number
       tagsAllOf?: string[]
       token?: string
       expectedStatus?: HttpStatusCode
+      excludeAlreadyWatched?: boolean
     }) {
       const res = await makeGetRequest({
         url: options.server.url,
         path: options.path,
         token: options.token ?? options.server.accessToken,
         query: {
-          ...pick(options, [ 'isLocal', 'include', 'category', 'tagsAllOf' ]),
+          ...pick(options, [
+            'isLocal',
+            'include',
+            'category',
+            'tagsAllOf',
+            'hasWebtorrentFiles',
+            'hasHLSFiles',
+            'privacyOneOf',
+            'excludeAlreadyWatched'
+          ]),
 
           sort: 'createdAt'
         },
@@ -156,16 +188,24 @@ describe('Test videos filter', function () {
       return res.body.data as Video[]
     }
 
-    async function getVideosNames (options: {
-      server: PeerTubeServer
-      isLocal?: boolean
-      include?: VideoInclude
-      token?: string
-      expectedStatus?: HttpStatusCode
-    }) {
+    async function getVideosNames (
+      options: {
+        server: PeerTubeServer
+        isLocal?: boolean
+        include?: VideoInclude
+        privacyOneOf?: VideoPrivacy[]
+        token?: string
+        expectedStatus?: HttpStatusCode
+        skipSubscription?: boolean
+        excludeAlreadyWatched?: boolean
+      }
+    ) {
+      const { skipSubscription = false } = options
       const videosResults: string[][] = []
 
       for (const path of paths) {
+        if (skipSubscription && path === subscriptionVideosPath) continue
+
         const videos = await listVideos({ ...options, path })
 
         videosResults.push(videos.map(v => v.name))
@@ -189,12 +229,15 @@ describe('Test videos filter', function () {
       for (const server of servers) {
         for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
 
-          const namesResults = await getVideosNames({
-            server,
-            token,
-            isLocal: true,
-            include: VideoInclude.HIDDEN_PRIVACY
-          })
+          const namesResults = await getVideosNames(
+            {
+              server,
+              token,
+              isLocal: true,
+              privacyOneOf: [ VideoPrivacy.UNLISTED, VideoPrivacy.PUBLIC, VideoPrivacy.PRIVATE ],
+              skipSubscription: true
+            }
+          )
 
           for (const names of namesResults) {
             expect(names).to.have.lengthOf(3)
@@ -214,7 +257,7 @@ describe('Test videos filter', function () {
           const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames({
             server,
             token,
-            include: VideoInclude.HIDDEN_PRIVACY
+            privacyOneOf: [ VideoPrivacy.UNLISTED, VideoPrivacy.PUBLIC, VideoPrivacy.PRIVATE ]
           })
 
           expect(channelVideos).to.have.lengthOf(3)
@@ -227,7 +270,7 @@ describe('Test videos filter', function () {
     })
 
     it('Should display only remote videos', async function () {
-      this.timeout(40000)
+      this.timeout(120000)
 
       await servers[1].videos.upload({ attributes: { name: 'remote video' } })
 
@@ -365,17 +408,41 @@ describe('Test videos filter', function () {
       await servers[0].blocklist.removeFromServerBlocklist({ server: servers[1].host })
     })
 
+    it('Should include video files', async function () {
+      for (const path of paths) {
+        {
+          const videos = await listVideos({ server: servers[0], path })
+
+          for (const video of videos) {
+            const videoWithFiles = video as VideoDetails
+
+            expect(videoWithFiles.files).to.not.exist
+            expect(videoWithFiles.streamingPlaylists).to.not.exist
+          }
+        }
+
+        {
+          const videos = await listVideos({ server: servers[0], path, include: VideoInclude.FILES })
+
+          for (const video of videos) {
+            const videoWithFiles = video as VideoDetails
+
+            expect(videoWithFiles.files).to.exist
+            expect(videoWithFiles.files).to.have.length.at.least(1)
+          }
+        }
+      }
+    })
+
     it('Should filter by tags and category', async function () {
       await servers[0].videos.upload({ attributes: { name: 'tag filter', tags: [ 'tag1', 'tag2' ] } })
       await servers[0].videos.upload({ attributes: { name: 'tag filter with category', tags: [ 'tag3' ], category: 4 } })
 
       for (const path of paths) {
         {
-
           const videos = await listVideos({ server: servers[0], path, tagsAllOf: [ 'tag1', 'tag2' ] })
           expect(videos).to.have.lengthOf(1)
           expect(videos[0].name).to.equal('tag filter')
-
         }
 
         {
@@ -395,6 +462,99 @@ describe('Test videos filter', function () {
         }
       }
     })
+
+    it('Should filter by HLS or WebTorrent files', async function () {
+      this.timeout(360000)
+
+      const finderFactory = (name: string) => (videos: Video[]) => videos.some(v => v.name === name)
+
+      await servers[0].config.enableTranscoding(true, false)
+      await servers[0].videos.upload({ attributes: { name: 'webtorrent video' } })
+      const hasWebtorrent = finderFactory('webtorrent video')
+
+      await waitJobs(servers)
+
+      await servers[0].config.enableTranscoding(false, true)
+      await servers[0].videos.upload({ attributes: { name: 'hls video' } })
+      const hasHLS = finderFactory('hls video')
+
+      await waitJobs(servers)
+
+      await servers[0].config.enableTranscoding(true, true)
+      await servers[0].videos.upload({ attributes: { name: 'hls and webtorrent video' } })
+      const hasBoth = finderFactory('hls and webtorrent video')
+
+      await waitJobs(servers)
+
+      for (const path of paths) {
+        {
+          const videos = await listVideos({ server: servers[0], path, hasWebtorrentFiles: true })
+
+          expect(hasWebtorrent(videos)).to.be.true
+          expect(hasHLS(videos)).to.be.false
+          expect(hasBoth(videos)).to.be.true
+        }
+
+        {
+          const videos = await listVideos({ server: servers[0], path, hasWebtorrentFiles: false })
+
+          expect(hasWebtorrent(videos)).to.be.false
+          expect(hasHLS(videos)).to.be.true
+          expect(hasBoth(videos)).to.be.false
+        }
+
+        {
+          const videos = await listVideos({ server: servers[0], path, hasHLSFiles: true })
+
+          expect(hasWebtorrent(videos)).to.be.false
+          expect(hasHLS(videos)).to.be.true
+          expect(hasBoth(videos)).to.be.true
+        }
+
+        {
+          const videos = await listVideos({ server: servers[0], path, hasHLSFiles: false })
+
+          expect(hasWebtorrent(videos)).to.be.true
+          expect(hasHLS(videos)).to.be.false
+          expect(hasBoth(videos)).to.be.false
+        }
+
+        {
+          const videos = await listVideos({ server: servers[0], path, hasHLSFiles: false, hasWebtorrentFiles: false })
+
+          expect(hasWebtorrent(videos)).to.be.false
+          expect(hasHLS(videos)).to.be.false
+          expect(hasBoth(videos)).to.be.false
+        }
+
+        {
+          const videos = await listVideos({ server: servers[0], path, hasHLSFiles: true, hasWebtorrentFiles: true })
+
+          expect(hasWebtorrent(videos)).to.be.false
+          expect(hasHLS(videos)).to.be.false
+          expect(hasBoth(videos)).to.be.true
+        }
+      }
+    })
+
+    it('Should filter already watched videos by the user', async function () {
+      const { id } = await servers[0].videos.upload({ attributes: { name: 'video for history' } })
+
+      for (const path of paths) {
+        const videos = await listVideos({ server: servers[0], path, isLocal: true, excludeAlreadyWatched: true })
+        const foundVideo = videos.find(video => video.id === id)
+
+        expect(foundVideo).to.not.be.undefined
+      }
+      await servers[0].views.view({ id, token: servers[0].accessToken })
+
+      for (const path of paths) {
+        const videos = await listVideos({ server: servers[0], path, excludeAlreadyWatched: true })
+        const foundVideo = videos.find(video => video.id === id)
+
+        expect(foundVideo).to.be.undefined
+      }
+    })
   })
 
   after(async function () {