bloodhound-1.0.0.0: tests/Test/StreamsSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Test.StreamsSpec (spec) where
import Data.Aeson
import Data.ByteString.Lazy.Char8 qualified as LBS
import Database.Bloodhound.ElasticSearch9.Requests qualified as RequestsES9
import Database.Bloodhound.ElasticSearch9.Types qualified as Types
import TestsUtils.Import
spec :: Spec
spec = describe "Streams API (/_streams/*)" $ do
describe "StreamName JSON" $ do
it "round-trips a StreamName" $ do
let n = Types.StreamName "logs.otel"
decode (encode n) `shouldBe` Just n
it "unStreamName extracts the underlying Text" $
Types.unStreamName (Types.StreamName "logs")
`shouldBe` ("logs" :: Text)
describe "StreamStatus JSON" $ do
it "encodes as {enabled: bool}" $ do
encode (Types.StreamStatus True)
`shouldBe` "{\"enabled\":true}"
encode (Types.StreamStatus False)
`shouldBe` "{\"enabled\":false}"
it "decodes {enabled: true}" $
decode (LBS.pack "{\"enabled\":true}")
`shouldBe` Just (Types.StreamStatus True)
describe "StreamsStatusResponse JSON" $ do
it "decodes a map of named streams (keys contain dots)" $ do
let raw =
LBS.pack
"{\"logs\":{\"enabled\":true},\"logs.otel\":{\"enabled\":false},\"logs.ecs\":{\"enabled\":true}}"
case decode raw :: Maybe Types.StreamsStatusResponse of
Just resp -> do
Types.streamStatusFor "logs" resp
`shouldBe` Just (Types.StreamStatus True)
Types.streamStatusFor "logs.otel" resp
`shouldBe` Just (Types.StreamStatus False)
Types.streamStatusFor "logs.ecs" resp
`shouldBe` Just (Types.StreamStatus True)
Types.streamStatusFor "missing" resp
`shouldBe` (Nothing :: Maybe Types.StreamStatus)
Nothing ->
expectationFailure "failed to decode StreamsStatusResponse"
it "decodes an empty object to an empty map" $
case decode (LBS.pack "{}") :: Maybe Types.StreamsStatusResponse of
Just resp ->
Types.streamStatusFor "anything" resp
`shouldBe` (Nothing :: Maybe Types.StreamStatus)
Nothing ->
expectationFailure "failed to decode empty StreamsStatusResponse"
it "round-trips a populated response" $ do
let raw =
LBS.pack
"{\"logs\":{\"enabled\":true},\"logs.ecs\":{\"enabled\":false}}"
case decode raw :: Maybe Types.StreamsStatusResponse of
Just resp -> decode (encode resp) `shouldBe` Just resp
Nothing -> expectationFailure "failed to decode StreamsStatusResponse"
describe "streamsActionOptionsParams URI rendering" $ do
it "defaultStreamsActionOptions emits no params" $
Types.streamsActionOptionsParams Types.defaultStreamsActionOptions
`shouldBe` []
it "renders master_timeout and timeout" $ do
let opts =
Types.defaultStreamsActionOptions
{ Types.saoMasterTimeout = Just "30s",
Types.saoTimeout = Just "1m"
}
Types.streamsActionOptionsParams opts
`shouldBe` [("master_timeout", Just "30s"), ("timeout", Just "1m")]
it "renders only the set field" $ do
let opts =
Types.defaultStreamsActionOptions
{ Types.saoTimeout = Just "1m"
}
Types.streamsActionOptionsParams opts
`shouldBe` [("timeout", Just "1m")]
describe "getStreamsStatusOptionsParams URI rendering" $ do
it "defaultGetStreamsStatusOptions emits no params" $
Types.getStreamsStatusOptionsParams Types.defaultGetStreamsStatusOptions
`shouldBe` []
it "renders master_timeout" $ do
let opts =
Types.defaultGetStreamsStatusOptions
{ Types.gssoMasterTimeout = Just (TimeUnitSeconds, 30)
}
Types.getStreamsStatusOptionsParams opts
`shouldBe` [("master_timeout", Just "30s")]
it "renders a minute duration with the m suffix" $ do
let opts =
Types.defaultGetStreamsStatusOptions
{ Types.gssoMasterTimeout = Just (TimeUnitMinutes, 1)
}
Types.getStreamsStatusOptionsParams opts
`shouldBe` [("master_timeout", Just "1m")]
describe "endpoint shape" $ do
it "GETs /_streams/status with no body" $ do
let req = RequestsES9.getStreamsStatus
getRawEndpoint (bhRequestEndpoint req)
`shouldBe` ["_streams", "status"]
bhRequestBody req `shouldSatisfy` isNothing
it "getStreamsStatusWith appends master_timeout query param" $ do
let opts =
Types.defaultGetStreamsStatusOptions
{ Types.gssoMasterTimeout = Just (TimeUnitSeconds, 30)
}
req = RequestsES9.getStreamsStatusWith opts
getRawEndpoint (bhRequestEndpoint req)
`shouldBe` ["_streams", "status"]
getRawEndpointQueries (bhRequestEndpoint req)
`shouldBe` [("master_timeout", Just "30s")]
it "POSTs /_streams/<name>/_enable with an empty body" $ do
let req = RequestsES9.enableStream "logs"
getRawEndpoint (bhRequestEndpoint req)
`shouldBe` ["_streams", "logs", "_enable"]
bhRequestBody req `shouldSatisfy` isJust
it "enableStreamWith appends timeout query params" $ do
let opts =
Types.defaultStreamsActionOptions
{ Types.saoMasterTimeout = Just "10s"
}
req = RequestsES9.enableStreamWith "logs.otel" opts
getRawEndpoint (bhRequestEndpoint req)
`shouldBe` ["_streams", "logs.otel", "_enable"]
getRawEndpointQueries (bhRequestEndpoint req)
`shouldBe` [("master_timeout", Just "10s")]
it "POSTs /_streams/<name>/_disable with an empty body" $ do
let req = RequestsES9.disableStream "logs.ecs"
getRawEndpoint (bhRequestEndpoint req)
`shouldBe` ["_streams", "logs.ecs", "_disable"]
bhRequestBody req `shouldSatisfy` isJust
it "disableStreamWith appends timeout query params" $ do
let opts =
Types.defaultStreamsActionOptions
{ Types.saoTimeout = Just "5s"
}
req = RequestsES9.disableStreamWith "logs" opts
getRawEndpoint (bhRequestEndpoint req)
`shouldBe` ["_streams", "logs", "_disable"]
getRawEndpointQueries (bhRequestEndpoint req)
`shouldBe` [("timeout", Just "5s")]