bloodhound-1.0.0.0: tests/Test/MultiGetOptionsSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Test.MultiGetOptionsSpec (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 "MultiGetOptions URI param rendering" $ do
it "defaultMultiGetOptions emits no params" $
multiGetOptionsParams defaultMultiGetOptions
`shouldBe` []
describe "_source" $ do
it "Just True renders as _source=true" $ do
let opts = defaultMultiGetOptions {mgoSource = Just True}
multiGetOptionsParams opts `shouldBe` [("_source", boolTrue)]
it "Just False renders as _source=false" $ do
let opts = defaultMultiGetOptions {mgoSource = Just False}
multiGetOptionsParams opts `shouldBe` [("_source", boolFalse)]
it "_source_includes renders verbatim" $ do
let opts = defaultMultiGetOptions {mgoSourceIncludes = Just "metadata.*,name"}
multiGetOptionsParams opts
`shouldBe` [("_source_includes", Just "metadata.*,name")]
it "_source_excludes renders verbatim" $ do
let opts = defaultMultiGetOptions {mgoSourceExcludes = Just "internal.*"}
multiGetOptionsParams opts
`shouldBe` [("_source_excludes", Just "internal.*")]
it "stored_fields renders verbatim" $ do
let opts = defaultMultiGetOptions {mgoStoredFields = Just "user,location"}
multiGetOptionsParams opts
`shouldBe` [("stored_fields", Just "user,location")]
it "preference renders verbatim" $ do
let opts = defaultMultiGetOptions {mgoPreference = Just "_local"}
multiGetOptionsParams opts
`shouldBe` [("preference", Just "_local")]
describe "realtime" $ do
it "Just True renders as realtime=true" $ do
let opts = defaultMultiGetOptions {mgoRealtime = Just True}
multiGetOptionsParams opts `shouldBe` [("realtime", boolTrue)]
it "Just False renders as realtime=false" $ do
let opts = defaultMultiGetOptions {mgoRealtime = Just False}
multiGetOptionsParams opts `shouldBe` [("realtime", boolFalse)]
describe "refresh" $ do
it "Just True renders as refresh=true" $ do
let opts = defaultMultiGetOptions {mgoRefresh = Just True}
multiGetOptionsParams opts `shouldBe` [("refresh", boolTrue)]
it "Just False renders as refresh=false" $ do
let opts = defaultMultiGetOptions {mgoRefresh = Just False}
multiGetOptionsParams opts `shouldBe` [("refresh", boolFalse)]
it "routing renders verbatim" $ do
let opts = defaultMultiGetOptions {mgoRouting = Just "user-42"}
multiGetOptionsParams opts `shouldBe` [("routing", Just "user-42")]
-- The whole point of the dedicated MultiGetOptions type (vs reusing
-- GetDocumentOptions) is that the multi-get endpoint does NOT accept
-- version/version_type as URI parameters. Pin the absence here so a
-- future refactor cannot silently regress the wire-level bug.
it "never emits version or version_type (not MGET URI params)" $ do
let rendered = multiGetOptionsParams defaultMultiGetOptions
let keys = map fst rendered
keys `shouldSatisfy` not . elem "version"
keys `shouldSatisfy` not . elem "version_type"
it "renders every field together when all are populated" $ do
let opts =
defaultMultiGetOptions
{ mgoSource = Just False,
mgoSourceIncludes = Just "a,b",
mgoSourceExcludes = Just "c",
mgoStoredFields = Just "s",
mgoPreference = Just "_local",
mgoRealtime = Just True,
mgoRefresh = Just False,
mgoRouting = Just "r"
}
let rendered = multiGetOptionsParams opts
-- Exactly the 8 documented MGET URI parameters — no version*, no
-- surprises.
length rendered `shouldBe` 8
rendered `shouldSatisfy` all (isJust . snd)
normalize rendered
`shouldBe` sort
[ ("_source", Just "false"),
("_source_excludes", Just "c"),
("_source_includes", Just "a,b"),
("preference", Just "_local"),
("realtime", Just "true"),
("refresh", Just "false"),
("routing", Just "r"),
("stored_fields", Just "s")
]
where
isJust (Just _) = True
isJust Nothing = False