servant-matrix-param-0.2: test/Servant/MatrixParam/ServerSpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
module Servant.MatrixParam.ServerSpec where
import Control.Monad.IO.Class
import Control.Monad.Trans.Except
import Data.ByteString.Lazy
import Data.Map.Strict
import Data.Proxy
import Data.Text
import Network.HTTP.Types (ok200)
import Network.Wai
import Network.Wai.Test
import Servant.API
import Servant.Server
import Test.Hspec
import Servant.MatrixParam
import Servant.MatrixParam.Server ()
import Servant.MatrixParam.Server.Internal
type Api =
WithMatrixParams "a" '[MatrixParam "name" String] :> Get '[PlainText] String
:<|> WithMatrixParams "b" '[MatrixParam "foo" Int, MatrixParam "bar" Int]
:> Get '[PlainText] String
api :: Proxy Api
api = Proxy
type Handler = ExceptT ServantErr IO
server :: Server Api
server = a :<|> b
where
a :: Maybe String -> Handler String
a p = return $ show p
b :: Maybe Int -> Maybe Int -> Handler String
b foo bar = return $ show (foo, bar)
testWithPath :: [Text] -> ByteString -> IO ()
testWithPath segments expected = do
(flip runSession) (serve api server) $ do
response <- Network.Wai.Test.request defaultRequest{
pathInfo = segments
}
liftIO $ do
simpleStatus response `shouldBe` ok200
simpleBody response `shouldBe` expected
spec :: Spec
spec = do
describe "Servant.API.MatrixParam" $ do
it "allows to retrieve simple matrix parameters" $ do
testWithPath ["a;name=bob"] "Just \"bob\""
it "allows to omit matrix parameters" $ do
testWithPath ["a"] "Nothing"
it "allows multiple keys per segment" $ do
testWithPath ["b;foo=23;bar=42"] "(Just 23,Just 42)"
it "allows to overwrite matrix params" $ do
testWithPath ["a;name=alice;name=bob"] "Just \"bob\""
describe "parsePathSegment" $ do
it "parses a path segment with a matrix param" $ do
parsePathSegment "foo;bar=baz" `shouldBe`
Just (MatrixSegment "foo" (Just (fromList [("bar", "baz")])))
it "parses a bare segment" $ do
parsePathSegment "foo" `shouldBe`
Just (MatrixSegment "foo" mempty)
it "parses a segment with multiple matrix params" $ do
parsePathSegment "foo;bar=baz;huhu=baba" `shouldBe`
Just (MatrixSegment "foo" (Just (fromList [("bar", "baz"), ("huhu", "baba")])))
it "parses a segment with multiple values for the same matrix param" $ do
parsePathSegment "foo;bar=baz;bar=huhu" `shouldBe`
Just (MatrixSegment "foo" (Just (fromList [("bar", "huhu")])))
it "parses a segment with semicolon but without params" $ do
parsePathSegment "foo;" `shouldBe`
Just (MatrixSegment "foo" mempty)
it "succeeds for invalid matrix parameters strings" $ do
parsePathSegment "foo;bar==" `shouldBe`
Just (MatrixSegment "foo" mempty)
it "can parse the empty string as value" $ do
parsePathSegment "foo;bar=" `shouldBe`
Just (MatrixSegment "foo" (Just (fromList [("bar", "")])))