wai-handler-hal-0.5.1.0: test/Network/Wai/Handler/HalTest.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
module Network.Wai.Handler.HalTest where
import AWS.Lambda.Events.ApiGateway.ProxyRequest (ProxyRequest)
import AWS.Lambda.Events.ApiGateway.ProxyResponse
( ProxyBody (..),
ProxyResponse (..),
)
import Data.Aeson (eitherDecodeFileStrict')
import Data.ByteString (ByteString)
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Lazy as LBS
import Data.Functor ((<&>))
import qualified Data.Text.Encoding as T
import qualified Data.Text.Lazy.Encoding as TL
import Data.Void (Void)
import Network.HTTP.Types (hContentEncoding, hContentType, ok200)
import Network.Wai (Response, responseLBS)
import Network.Wai.Handler.Hal
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Golden (goldenVsString)
import Test.Tasty.HUnit (Assertion, assertEqual, testCase)
import Text.Pretty.Simple (pShowNoColor)
test_ConvertProxyRequest :: TestTree
test_ConvertProxyRequest =
goldenVsString "API Gateway Proxy Request" "test/golden/WaiRequest.txt" $ do
proxyRequest :: ProxyRequest Void <-
eitherDecodeFileStrict' "test/data/ProxyRequest.json"
>>= either fail pure
waiRequest <- toWaiRequest defaultOptions proxyRequest
pure . TL.encodeUtf8 $ pShowNoColor waiRequest
unit_BinaryResponse :: Assertion
unit_BinaryResponse = do
let options = defaultOptions {binaryMediaTypes = ["*/*"]}
ProxyResponse {body = ProxyBody {..}} <-
fromWaiResponse options helloWorld
assertEqual "response is binary" True isBase64Encoded
assertEqual
"response is base64-encoded"
(Right "Hello, World!")
(B64.decode (T.encodeUtf8 serialized))
unit_TextResponse :: Assertion
unit_TextResponse = do
ProxyResponse {body = ProxyBody {..}} <-
fromWaiResponse defaultOptions helloWorld
assertEqual "response is not binary" False isBase64Encoded
assertEqual "response is unmangled" "Hello, World!" serialized
helloWorld :: Response
helloWorld = responseLBS ok200 [(hContentType, "text/plain")] "Hello, World!"
unit_GzipResponseIsBase64Encoded :: Assertion
unit_GzipResponseIsBase64Encoded = do
let gzipBytes = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xff\xfe"
ProxyResponse {body = ProxyBody {..}} <-
fromWaiResponse defaultOptions $
responseLBS
ok200
[(hContentType, "text/html"), (hContentEncoding, "gzip")]
(LBS.fromStrict gzipBytes)
assertEqual "response is binary" True isBase64Encoded
assertEqual
"response round-trips through base64"
(Right gzipBytes)
(B64.decode (T.encodeUtf8 serialized))
unit_IdentityResponseIsNotBase64Encoded :: Assertion
unit_IdentityResponseIsNotBase64Encoded = do
ProxyResponse {body = ProxyBody {..}} <-
fromWaiResponse defaultOptions $
responseLBS
ok200
[(hContentType, "text/plain"), (hContentEncoding, "identity")]
"Hello, World!"
assertEqual "response is not binary" False isBase64Encoded
assertEqual "response is unmangled" "Hello, World!" serialized
test_ContentEncodingDetection :: [TestTree]
test_ContentEncodingDetection =
[ testGroup "base64-encoded" $
[ ("Gzip", ["Gzip"]),
("br, gzip with whitespace", [" br , gzip"]),
("identity, gzip", ["identity, gzip"]),
("x-gzip", ["x-gzip"]),
("repeated headers", ["identity", "br"])
]
<&> \(title, values) -> testCase title $ do
ProxyResponse {body = ProxyBody {..}} <- mkResponse values
assertEqual "isBase64Encoded" True isBase64Encoded,
testGroup "not base64-encoded" $
[ ("empty value", [""]),
("identity, mixed case", ["identity , Identity"]),
("no header", [])
]
<&> \(title, values) -> testCase title $ do
ProxyResponse {body = ProxyBody {..}} <- mkResponse values
assertEqual "isBase64Encoded" False isBase64Encoded
]
where
mkResponse :: [ByteString] -> IO ProxyResponse
mkResponse values =
fromWaiResponse defaultOptions $
responseLBS
ok200
((hContentType, "text/plain") : ((hContentEncoding,) <$> values))
"x"