Add search index tests
authorChocobozzz <me@florianbigard.com>
Wed, 10 Jun 2020 08:58:44 +0000 (10:58 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Wed, 10 Jun 2020 12:02:41 +0000 (14:02 +0200)
server/controllers/api/config.ts
server/controllers/api/search.ts
server/tests/api/search/index.ts
server/tests/api/search/search-channels.ts [new file with mode: 0644]
server/tests/api/search/search-index.ts [new file with mode: 0644]
shared/extra-utils/search/video-channels.ts

index 1d48b4b26711623b01af26ac8cdc5457dd68e9b9..b80ea49027b3bd9de783ceaa3fde3efa1ca98d72 100644 (file)
@@ -463,7 +463,7 @@ function customConfig (): CustomConfig {
         disableLocalSearch: CONFIG.SEARCH.SEARCH_INDEX.DISABLE_LOCAL_SEARCH,
         isDefaultSearch: CONFIG.SEARCH.SEARCH_INDEX.IS_DEFAULT_SEARCH
       }
-    },
+    }
   }
 }
 
index e08e1d79fa15baea1ec64193c49e30e9e6d31cdc..1dea77d2925fed81f351316295090571afa6d606 100644 (file)
@@ -76,7 +76,7 @@ function searchVideoChannels (req: express.Request, res: express.Response) {
   // @username -> username to search in DB
   if (query.search.startsWith('@')) query.search = query.search.replace(/^@/, '')
 
-  if (isSearchIndexEnabled(query)) {
+  if (isSearchIndexSearch(query)) {
     return searchVideoChannelsIndex(query, res)
   }
 
@@ -157,7 +157,7 @@ function searchVideos (req: express.Request, res: express.Response) {
     return searchVideoURI(search, res)
   }
 
-  if (isSearchIndexEnabled(query)) {
+  if (isSearchIndexSearch(query)) {
     return searchVideosIndex(query, res)
   }
 
@@ -226,7 +226,7 @@ async function searchVideoURI (url: string, res: express.Response) {
   })
 }
 
-function isSearchIndexEnabled (query: SearchTargetQuery) {
+function isSearchIndexSearch (query: SearchTargetQuery) {
   if (query.searchTarget === 'search-index') return true
 
   const searchIndexConfig = CONFIG.SEARCH.SEARCH_INDEX
index d573c8a9e612b00c29600f2835b82ff31889f90a..232c1f2a47d23f7bd0a4a44c3375a404324ec5c5 100644 (file)
@@ -1,3 +1,5 @@
 import './search-activitypub-video-channels'
 import './search-activitypub-videos'
+import './search-index'
 import './search-videos'
+import './search-channels'
diff --git a/server/tests/api/search/search-channels.ts b/server/tests/api/search/search-channels.ts
new file mode 100644 (file)
index 0000000..daca2ae
--- /dev/null
@@ -0,0 +1,79 @@
+/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
+
+import 'mocha'
+import * as chai from 'chai'
+import { searchVideoChannel, advancedVideoChannelSearch } from '@shared/extra-utils/search/video-channels'
+import {
+  addVideoChannel,
+  cleanupTests,
+  createUser,
+  flushAndRunServer,
+  ServerInfo,
+  setAccessTokensToServers
+} from '../../../../shared/extra-utils'
+import { VideoChannel } from '@shared/models'
+
+const expect = chai.expect
+
+describe('Test channels search', function () {
+  let server: ServerInfo = null
+
+  before(async function () {
+    this.timeout(30000)
+
+    server = await flushAndRunServer(1)
+
+    await setAccessTokensToServers([ server ])
+
+    {
+      await createUser({ url: server.url, accessToken: server.accessToken, username: 'user1', password: 'password' })
+      const channel = {
+        name: 'squall_channel',
+        displayName: 'Squall channel'
+      }
+      await addVideoChannel(server.url, server.accessToken, channel)
+    }
+  })
+
+  it('Should make a simple search and not have results', async function () {
+    const res = await searchVideoChannel(server.url, 'abc')
+
+    expect(res.body.total).to.equal(0)
+    expect(res.body.data).to.have.lengthOf(0)
+  })
+
+  it('Should make a search and have results', async function () {
+    {
+      const search = {
+        search: 'Squall',
+        start: 0,
+        count: 1
+      }
+      const res = await advancedVideoChannelSearch(server.url, search)
+      expect(res.body.total).to.equal(1)
+      expect(res.body.data).to.have.lengthOf(1)
+
+      const channel: VideoChannel = res.body.data[0]
+      expect(channel.name).to.equal('squall_channel')
+      expect(channel.displayName).to.equal('Squall channel')
+    }
+
+    {
+      const search = {
+        search: 'Squall',
+        start: 1,
+        count: 1
+      }
+
+      const res = await advancedVideoChannelSearch(server.url, search)
+
+      expect(res.body.total).to.equal(1)
+
+      expect(res.body.data).to.have.lengthOf(0)
+    }
+  })
+
+  after(async function () {
+    await cleanupTests([ server ])
+  })
+})
diff --git a/server/tests/api/search/search-index.ts b/server/tests/api/search/search-index.ts
new file mode 100644 (file)
index 0000000..2354aaa
--- /dev/null
@@ -0,0 +1,252 @@
+/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
+
+import 'mocha'
+import * as chai from 'chai'
+import {
+  cleanupTests,
+  flushAndRunServer,
+  searchVideo,
+  ServerInfo,
+  setAccessTokensToServers,
+  updateCustomSubConfig,
+  uploadVideo,
+  advancedVideosSearch,
+  immutableAssign
+} from '../../../../shared/extra-utils'
+import { searchVideoChannel, advancedVideoChannelSearch } from '@shared/extra-utils/search/video-channels'
+import { VideosSearchQuery, Video, VideoChannel } from '@shared/models'
+
+const expect = chai.expect
+
+describe('Test videos search', function () {
+  let server: ServerInfo = null
+  const localVideoName = 'local video' + new Date().toISOString()
+
+  before(async function () {
+    this.timeout(30000)
+
+    server = await flushAndRunServer(1)
+
+    await setAccessTokensToServers([ server ])
+
+    await uploadVideo(server.url, server.accessToken, { name: localVideoName })
+  })
+
+  describe('Default search', async function () {
+
+    it('Should make a local videos search by default', async function () {
+      this.timeout(10000)
+
+      await updateCustomSubConfig(server.url, server.accessToken, {
+        search: {
+          searchIndex: {
+            enabled: true,
+            isDefaultSearch: false,
+            disableLocalSearch: false
+          }
+        }
+      })
+
+      const res = await searchVideo(server.url, 'local video')
+
+      expect(res.body.total).to.equal(1)
+      expect(res.body.data[0].name).to.equal(localVideoName)
+    })
+
+    it('Should make a local channels search by default', async function () {
+      const res = await searchVideoChannel(server.url, 'root')
+
+      expect(res.body.total).to.equal(1)
+      expect(res.body.data[0].name).to.equal('root_channel')
+      expect(res.body.data[0].host).to.equal('localhost:' + server.port)
+    })
+
+    it('Should make an index videos search by default', async function () {
+      await updateCustomSubConfig(server.url, server.accessToken, {
+        search: {
+          searchIndex: {
+            enabled: true,
+            isDefaultSearch: true,
+            disableLocalSearch: false
+          }
+        }
+      })
+
+      const res = await searchVideo(server.url, 'local video')
+      expect(res.body.total).to.be.greaterThan(2)
+    })
+
+    it('Should make an index channels search by default', async function () {
+      const res = await searchVideoChannel(server.url, 'root')
+      expect(res.body.total).to.be.greaterThan(2)
+    })
+
+    it('Should make an index videos search if local search is disabled', async function () {
+      await updateCustomSubConfig(server.url, server.accessToken, {
+        search: {
+          searchIndex: {
+            enabled: true,
+            isDefaultSearch: false,
+            disableLocalSearch: true
+          }
+        }
+      })
+
+      const res = await searchVideo(server.url, 'local video')
+      expect(res.body.total).to.be.greaterThan(2)
+    })
+
+    it('Should make an index channels search if local search is disabled', async function () {
+      const res = await searchVideoChannel(server.url, 'root')
+      expect(res.body.total).to.be.greaterThan(2)
+    })
+  })
+
+  describe('Videos search', async function () {
+
+    it('Should make a simple search and not have results', async function () {
+      const res = await searchVideo(server.url, 'a'.repeat(500))
+
+      expect(res.body.total).to.equal(0)
+      expect(res.body.data).to.have.lengthOf(0)
+    })
+
+    it('Should make a simple search and have results', async function () {
+      const res = await searchVideo(server.url, 'What is PeerTube')
+
+      expect(res.body.total).to.be.greaterThan(1)
+    })
+
+    it('Should make a complex search', async function () {
+
+      async function check (search: VideosSearchQuery, exists = true) {
+        const res = await advancedVideosSearch(server.url, search)
+
+        if (exists === false) {
+          expect(res.body.total).to.equal(0)
+          expect(res.body.data).to.have.lengthOf(0)
+          return
+        }
+
+        expect(res.body.total).to.equal(1)
+        expect(res.body.data).to.have.lengthOf(1)
+
+        const video: Video = res.body.data[0]
+
+        expect(video.name).to.equal('What is PeerTube?')
+        expect(video.category.label).to.equal('Science & Technology')
+        expect(video.licence.label).to.equal('Attribution - Share Alike')
+        expect(video.privacy.label).to.equal('Public')
+        expect(video.duration).to.equal(113)
+        expect(video.thumbnailUrl.startsWith('https://framatube.org/static/thumbnails')).to.be.true
+
+        expect(video.account.host).to.equal('framatube.org')
+        expect(video.account.name).to.equal('framasoft')
+        expect(video.account.url).to.equal('https://framatube.org/accounts/framasoft')
+        expect(video.account.avatar).to.exist
+
+        expect(video.channel.host).to.equal('framatube.org')
+        expect(video.channel.name).to.equal('bf54d359-cfad-4935-9d45-9d6be93f63e8')
+        expect(video.channel.url).to.equal('https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8')
+        expect(video.channel.avatar).to.exist
+      }
+
+      const baseSearch: VideosSearchQuery = {
+        search: 'what is peertube',
+        start: 0,
+        count: 2,
+        categoryOneOf: [ 15 ],
+        licenceOneOf: [ 2 ],
+        tagsAllOf: [ 'framasoft', 'peertube' ],
+        startDate: '2018-10-01T10:50:46.396Z',
+        endDate: '2018-10-01T10:55:46.396Z'
+      }
+
+      {
+        await check(baseSearch)
+      }
+
+      {
+        const search = immutableAssign(baseSearch, { startDate: '2018-10-01T10:54:46.396Z' })
+        await check(search, false)
+      }
+
+      {
+        const search = immutableAssign(baseSearch, { tagsAllOf: [ 'toto', 'framasoft' ] })
+        await check(search, false)
+      }
+
+      {
+        const search = immutableAssign(baseSearch, { durationMin: 2000 })
+        await check(search, false)
+      }
+
+      {
+        const search = immutableAssign(baseSearch, { nsfw: 'true' })
+        await check(search, false)
+      }
+
+      {
+        const search = immutableAssign(baseSearch, { nsfw: 'false' })
+        await check(search, true)
+      }
+
+      {
+        const search = immutableAssign(baseSearch, { nsfw: 'both' })
+        await check(search, true)
+      }
+    })
+
+    it('Should have a correct pagination', async function () {
+      const search = {
+        search: 'video',
+        start: 0,
+        count: 5
+      }
+
+      const res = await advancedVideosSearch(server.url, search)
+
+      expect(res.body.total).to.be.greaterThan(5)
+      expect(res.body.data).to.have.lengthOf(5)
+    })
+  })
+
+  describe('Channels search', async function () {
+
+    it('Should make a simple search and not have results', async function () {
+      const res = await searchVideoChannel(server.url, 'a'.repeat(500))
+
+      expect(res.body.total).to.equal(0)
+      expect(res.body.data).to.have.lengthOf(0)
+    })
+
+    it('Should make a search and have results', async function () {
+      const res = await advancedVideoChannelSearch(server.url, { search: 'Framasoft', sort: 'createdAt' })
+
+      expect(res.body.total).to.be.greaterThan(0)
+      expect(res.body.data).to.have.length.greaterThan(0)
+
+      const videoChannel: VideoChannel = res.body.data[0]
+      expect(videoChannel.url).to.equal('https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8')
+      expect(videoChannel.host).to.equal('framatube.org')
+      expect(videoChannel.avatar).to.exist
+      expect(videoChannel.displayName).to.exist
+
+      expect(videoChannel.ownerAccount.url).to.equal('https://framatube.org/accounts/framasoft')
+      expect(videoChannel.ownerAccount.name).to.equal('framasoft')
+      expect(videoChannel.ownerAccount.host).to.equal('framatube.org')
+      expect(videoChannel.ownerAccount.avatar).to.exist
+    })
+
+    it('Should have a correct pagination', async function () {
+      const res = await advancedVideoChannelSearch(server.url, { search: 'root', start: 0, count: 2 })
+
+      expect(res.body.total).to.be.greaterThan(2)
+      expect(res.body.data).to.have.lengthOf(2)
+    })
+  })
+
+  after(async function () {
+    await cleanupTests([ server ])
+  })
+})
index 0532134aeff6fd0a308228351e995456c0003fa0..d162105301fa4d7cc5d369188f0f95c6c2824bdb 100644 (file)
@@ -1,3 +1,4 @@
+import { VideoChannelsSearchQuery } from '@shared/models'
 import { makeGetRequest } from '../requests/requests'
 
 function searchVideoChannel (url: string, search: string, token?: string, statusCodeExpected = 200) {
@@ -15,8 +16,20 @@ function searchVideoChannel (url: string, search: string, token?: string, status
   })
 }
 
+function advancedVideoChannelSearch (url: string, search: VideoChannelsSearchQuery) {
+  const path = '/api/v1/search/video-channels'
+
+  return makeGetRequest({
+    url,
+    path,
+    query: search,
+    statusCodeExpected: 200
+  })
+}
+
 // ---------------------------------------------------------------------------
 
 export {
-  searchVideoChannel
+  searchVideoChannel,
+  advancedVideoChannelSearch
 }