tower-hs-0.2.0.0: test/Tower/Middleware/TransformSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Tower.Middleware.TransformSpec (spec) where
import Data.IORef
import Test.Hspec
import Tower.Service
import Tower.Error
import Tower.Error.Testing ()
import Data.Function ((&))
import Tower.Middleware.Transform
spec :: Spec
spec = describe "Transform middleware (generic)" $ do
describe "withMapRequestPure" $ do
it "transforms the request before passing to inner service" $ do
let svc :: Service String String
svc = Service $ \req -> pure (Right req)
transformed = svc & withMapRequestPure (++ "!")
result <- runService transformed "hello"
result `shouldBe` Right "hello!"
it "does not alter the response" $ do
let svc :: Service String String
svc = Service $ \_ -> pure (Right "response")
transformed = svc & withMapRequestPure (++ "!")
result <- runService transformed "request"
result `shouldBe` Right "response"
it "composes multiple transforms (right-to-left)" $ do
let svc :: Service String String
svc = Service $ \req -> pure (Right req)
transformed = svc
& withMapRequestPure (++ "1")
& withMapRequestPure (++ "2")
& withMapRequestPure (++ "3")
result <- runService transformed "base"
-- Middleware applies left-to-right: 1 applied first, then 2, then 3
result `shouldBe` Right "base321"
describe "withMapRequest" $ do
it "transforms the request with IO" $ do
counter <- newIORef (0 :: Int)
let svc :: Service String String
svc = Service $ \req -> pure (Right req)
transformed = svc & withMapRequest (\req -> do
n <- atomicModifyIORef' counter (\c -> (c + 1, c))
pure (req ++ "-" ++ show n))
r1 <- runService transformed "req"
r2 <- runService transformed "req"
r1 `shouldBe` Right "req-0"
r2 `shouldBe` Right "req-1"
it "passes through errors from inner service" $ do
let svc :: Service String String
svc = Service $ \_ -> pure (Left (CustomError "fail"))
transformed = svc & withMapRequest (\req -> pure (req ++ "!"))
result <- runService transformed "hello"
result `shouldBe` Left (CustomError "fail")