packages feed

bloodhound-1.0.0.0: tests/Test/TermVectorsOptionsSpec.hs

{-# LANGUAGE OverloadedStrings #-}

module Test.TermVectorsOptionsSpec (spec) where

import Data.List (sort)
import Data.Text qualified as T
import Database.Bloodhound.Common.Types
import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy)

-- | Stable ordering for equality. The renderer preserves field-declaration
-- order but tests should compare the set of params, not the order.
normalize :: [(T.Text, Maybe T.Text)] -> [(T.Text, Maybe T.Text)]
normalize = sort

-- | Boolean helpers rendered as @true@/@false@ strings.
boolTrue :: Maybe T.Text
boolTrue = Just "true"

boolFalse :: Maybe T.Text
boolFalse = Just "false"

spec :: Spec
spec =
  describe "TermVectorsOptions URI param rendering" $ do
    it "defaultTermVectorsOptions emits no params" $
      termVectorsOptionsParams defaultTermVectorsOptions
        `shouldBe` []

    it "preference renders verbatim" $ do
      let opts = defaultTermVectorsOptions {tvoPreference = Just "_local"}
      termVectorsOptionsParams opts `shouldBe` [("preference", Just "_local")]

    describe "realtime" $ do
      it "Just True renders as realtime=true" $ do
        let opts = defaultTermVectorsOptions {tvoRealtime = Just True}
        termVectorsOptionsParams opts `shouldBe` [("realtime", boolTrue)]
      it "Just False renders as realtime=false" $ do
        let opts = defaultTermVectorsOptions {tvoRealtime = Just False}
        termVectorsOptionsParams opts `shouldBe` [("realtime", boolFalse)]

    it "routing renders verbatim" $ do
      let opts = defaultTermVectorsOptions {tvoRouting = Just "user-42"}
      termVectorsOptionsParams opts `shouldBe` [("routing", Just "user-42")]

    it "version renders as integer text" $ do
      let opts = defaultTermVectorsOptions {tvoVersion = Just 7}
      termVectorsOptionsParams opts `shouldBe` [("version", Just "7")]

    it "version renders 0 verbatim (no non-positive filtering)" $ do
      -- The renderer must not validate; the server does. Pin this so a
      -- future "drop non-positive versions" change is caught here.
      let opts = defaultTermVectorsOptions {tvoVersion = Just 0}
      termVectorsOptionsParams opts `shouldBe` [("version", Just "0")]

    describe "version_type" $ do
      it "internal renders as version_type=internal" $ do
        let opts = defaultTermVectorsOptions {tvoVersionType = Just VersionTypeInternal}
        termVectorsOptionsParams opts `shouldBe` [("version_type", Just "internal")]
      it "external renders as version_type=external" $ do
        let opts = defaultTermVectorsOptions {tvoVersionType = Just VersionTypeExternal}
        termVectorsOptionsParams opts `shouldBe` [("version_type", Just "external")]
      it "external_gte renders as version_type=external_gte" $ do
        let opts = defaultTermVectorsOptions {tvoVersionType = Just VersionTypeExternalGTE}
        termVectorsOptionsParams opts `shouldBe` [("version_type", Just "external_gte")]

    it "renders every field together when all are populated" $ do
      let opts =
            defaultTermVectorsOptions
              { tvoPreference = Just "_local",
                tvoRealtime = Just False,
                tvoRouting = Just "user-42",
                tvoVersion = Just 7,
                tvoVersionType = Just VersionTypeExternalGTE
              }
      let rendered = termVectorsOptionsParams opts
      -- Exactly the 5 documented termvectors URI parameters.
      length rendered `shouldBe` 5
      rendered `shouldSatisfy` all (isJust . snd)
      normalize rendered
        `shouldBe` sort
          [ ("preference", Just "_local"),
            ("realtime", Just "false"),
            ("routing", Just "user-42"),
            ("version", Just "7"),
            ("version_type", Just "external_gte")
          ]
  where
    isJust (Just _) = True
    isJust Nothing = False