packages feed

bloodhound-1.0.0.0: tests/Test/NeuralSearchSpec.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}

module Test.NeuralSearchSpec (spec) where

import Data.Aeson (Value)
import Database.Bloodhound.Common.Requests qualified as Common
import Database.Bloodhound.OpenSearch3.Requests qualified as OS3Requests
import Database.Bloodhound.OpenSearch3.Types
import TestsUtils.Import
import Prelude

-- | Pure endpoint-shape tests for the Neural Search wrapper. Neural
-- search is /not/ a dedicated route: it targets the standard
-- @POST \/{indices}\/_search@ endpoint (or @POST /_search@ when no
-- indices are supplied), with a @neural@ clause carried in the 'Search'
-- body. The supplied index list is therefore rendered as a comma-joined
-- path segment, exactly as in 'searchByIndices', rather than as a query
-- parameter. These tests pin down the path composition for both the
-- empty and non-empty branches so that a regression is caught here.
spec :: Spec
spec = describe "Neural Search API (OS3 wrapper)" $ do
  describe "neuralSearch endpoint shape" $ do
    it "POSTs to /_search with no query when indices is empty" $ do
      let req = OS3Requests.neuralSearch @Value [] (Common.mkSearch Nothing Nothing)
      bhRequestMethod req `shouldBe` "POST"
      getRawEndpoint (bhRequestEndpoint req)
        `shouldBe` ["_search"]
      getRawEndpointQueries (bhRequestEndpoint req) `shouldBe` []

    it "attaches the serialized Search body" $ do
      let search = Common.mkSearch Nothing Nothing
      let req = OS3Requests.neuralSearch @Value [] search
      bhRequestBody req `shouldBe` Just (encode search)

    it "puts the single index in the path (/index/_search) with no query" $ do
      let req = OS3Requests.neuralSearch @Value [[qqIndexName|my-index|]] (Common.mkSearch Nothing Nothing)
      getRawEndpoint (bhRequestEndpoint req)
        `shouldBe` ["my-index", "_search"]
      getRawEndpointQueries (bhRequestEndpoint req) `shouldBe` []

    it "comma-joins multiple index names as a single path segment" $ do
      let req =
            OS3Requests.neuralSearch
              @Value
              [[qqIndexName|idx-a|], [qqIndexName|idx-b|], [qqIndexName|idx-c|]]
              (Common.mkSearch Nothing Nothing)
      getRawEndpoint (bhRequestEndpoint req)
        `shouldBe` ["idx-a,idx-b,idx-c", "_search"]
      getRawEndpointQueries (bhRequestEndpoint req) `shouldBe` []

    it "uses the POST method regardless of the index list" $ do
      let req = OS3Requests.neuralSearch @Value [[qqIndexName|foo|]] (Common.mkSearch Nothing Nothing)
      bhRequestMethod req `shouldBe` "POST"