packages feed

natskell-1.1.0.0: test/Unit/JetStream/StreamSpec.hs

{-# LANGUAGE OverloadedStrings #-}

module JetStream.StreamSpec (spec) where

import           Data.Aeson             (eitherDecode, encode, object, (.=))
import qualified Data.ByteString.Lazy   as LBS
import           Data.Int               (Int32)
import           JetStream.Error        (JetStreamError (JetStreamDecodeError))
import           JetStream.Stream.Types
import           Test.Hspec

spec :: Spec
spec = do
  describe "StreamConfig request JSON" $ do
    it "omits max message size unless configured" $ do
      let request = streamConfigRequest "ORDERS" ["orders.>"] []
      eitherDecode (encode request) `shouldBe` Right (object
        [ "name" .= ("ORDERS" :: String)
        , "subjects" .= ["orders.>" :: String]
        ])

    it "encodes valid max message size boundaries" $ do
      let encodedMaxMessageSize value =
            eitherDecode . encode $
              streamConfigRequest "ORDERS" [] [withMaxMessageSize value]
          validatedMaxMessageSize value =
            validateStreamConfigRequest $
              streamConfigRequest "ORDERS" [] [withMaxMessageSize value]
          expected value = object
            [ "name" .= ("ORDERS" :: String)
            , "subjects" .= ([] :: [String])
            , "max_msg_size" .= value
            ]
      encodedMaxMessageSize (-1) `shouldBe` Right (expected (-1 :: Int32))
      encodedMaxMessageSize 0 `shouldBe` Right (expected (0 :: Int32))
      encodedMaxMessageSize maxBound `shouldBe` Right (expected (maxBound :: Int32))
      validatedMaxMessageSize (-1) `shouldBe` Right ()
      validatedMaxMessageSize 0 `shouldBe` Right ()
      validatedMaxMessageSize maxBound `shouldBe` Right ()

    it "rejects max message sizes below unlimited" $ do
      validateStreamConfigRequest
        (streamConfigRequest "ORDERS" [] [withMaxMessageSize (-2)])
        `shouldBe` Left (JetStreamDecodeError "stream max message size must be -1 or greater")
      validateStreamConfigRequest
        (streamConfigRequest "ORDERS" [] [withMaxMessageSize minBound])
        `shouldBe` Left (JetStreamDecodeError "stream max message size must be -1 or greater")

  describe "StreamConfig response JSON" $ do
    it "normalizes a missing max message size to unlimited" $ do
      fmap streamConfigMaxMessageSize (eitherDecode streamConfigWithoutMaxMessageSizeJSON)
        `shouldBe` Right (-1)

    it "round-trips max message size" $ do
      eitherDecode (encode streamConfigFixture) `shouldBe` Right streamConfigFixture

streamConfigFixture :: StreamConfig
streamConfigFixture =
  StreamConfig
    { streamConfigName = "ORDERS"
    , streamConfigSubjects = Just ["orders.>"]
    , streamConfigRetention = LimitsPolicy
    , streamConfigStorage = MemoryStorage
    , streamConfigDiscard = DiscardOld
    , streamConfigMaxMessages = -1
    , streamConfigMaxBytes = -1
    , streamConfigMaxAge = 0
    , streamConfigMaxMessageSize = maxBound
    , streamConfigReplicas = 1
    , streamConfigDuplicateWindow = Nothing
    , streamConfigAllowDirect = False
    }

streamConfigWithoutMaxMessageSizeJSON :: LBS.ByteString
streamConfigWithoutMaxMessageSizeJSON =
  "{\"name\":\"ORDERS\",\"subjects\":[\"orders.>\"],\"retention\":\"limits\",\"storage\":\"memory\",\"discard\":\"old\",\"max_msgs\":-1,\"max_bytes\":-1,\"max_age\":0,\"num_replicas\":1,\"allow_direct\":false}"