servant-routes-0.1.0.0: test/Servant/API/Routes/RouteSpec.hs
module Servant.API.Routes.RouteSpec
( spec
)
where
import Data.Function
import qualified Data.Set as Set
import qualified Data.Text as T
import Lens.Micro
import Network.HTTP.Types.Method
import Servant.API.Routes.HeaderSpec hiding (spec)
import Servant.API.Routes.Internal.Auth
import Servant.API.Routes.Internal.Path
import Servant.API.Routes.Internal.Route
import Servant.API.Routes.ParamSpec hiding (spec)
import Servant.API.Routes.PathSpec (genAlphaText, shrinkText)
import Servant.API.Routes.RequestSpec ()
import Servant.API.Routes.ResponseSpec ()
import Servant.API.Routes.Route
import Test.Hspec as H
import Test.QuickCheck as Q
instance Q.Arbitrary Route where
arbitrary = do
_routeMethod <- renderStdMethod <$> Q.arbitraryBoundedEnum
_routePath <- arbitrary
_routeParams <- Set.fromList <$> Q.sublistOf [sing, arrayElem, flag]
_routeRequestHeaders <- Set.fromList <$> Q.sublistOf sampleReps
_routeRequestBody <- arbitrary
_routeResponse <- arbitrary
_routeAuths <- Set.fromList <$> Q.listOf genAuths
pure Route {..}
where
genAuths =
Q.oneof
[ Basic <$> genAlphaText
, Custom <$> genAlphaText
]
shrink r =
routeMethod shrinkMethod r
<> routePath Q.shrink r
<> routeParams shrinkSubset r
<> routeRequestHeaders shrinkSubset r
<> routeRequestBody Q.shrink r
<> routeResponse Q.shrink r
<> routeAuths (shrinkSet shrinkAuth) r
where
shrinkMethod = either (const []) (fmap renderStdMethod . Q.shrinkBoundedEnum) . parseMethod
shrinkSet shr = fmap Set.fromList . Q.shrinkList shr . Set.toList
shrinkSubset :: Ord a => Set.Set a -> [Set.Set a]
shrinkSubset = shrinkSet (const [])
shrinkAuth = \case
Basic realm -> Basic <$> shrinkText realm
Custom tag -> Custom <$> shrinkText tag
spec :: Spec
spec = do
describe "Route" $ do
describe "renderRoute" $ do
it "renders default route correctly" $
renderRoute (defRoute "POST") `shouldBe` "POST " <> pathSeparator
it "renders path correctly" $
let route =
defRoute "GET"
& routePath .~ Path ["api", "v2"]
expected = "GET /api/v2"
in renderRoute route `shouldBe` expected
it "renders query params correctly" $
let route =
defRoute "PUT"
& routePath .~ Path ["api", "v2"]
& routeParams .~ Set.fromList [sing, arrayElem, flag]
expected = "PUT /api/v2?" <> T.intercalate "&" [singExpected, arrayElemExpected, flagExpected]
in renderRoute route `shouldBe` expected