@@ -17,7 +17,8 @@ import Data.String (fromString)
1717import Data.String.Conversions (cs)
1818import qualified Data.Text as T
1919import GHC.Generics (Generic)
20−import Network.HTTP.Types (hContentType, methodDelete,
20+import Network.HTTP.Types (hAccept, hContentType,
21+ methodDelete, methodGet,
2122 methodPatch, methodPost, methodPut,
2223 ok200, parseQuery, status409)
2324import Network.Wai (Application, Request, pathInfo,
@@ -43,7 +44,7 @@ import Servant.Server.Internal (RouteMismatch (..))
4344
4445data Person = Person {
4546 name :: String,
46− age :: Integer
47+ age :: Integer
4748 }
4849 deriving (Eq, Show, Generic)
4950
@@ -54,7 +55,7 @@ alice :: Person
5455alice = Person "Alice" 42
5556
5657data Animal = Animal {
57− species :: String,
58+ species :: String,
5859 numberOfLegs :: Integer
5960 }
6061 deriving (Eq, Show, Generic)
@@ -99,10 +100,13 @@ captureSpec :: Spec
99100captureSpec = do
100101 describe "Servant.API.Capture" $ do
101102 with (return (serve captureApi captureServer)) $ do
103+
102104 it "can capture parts of the 'pathInfo'" $ do
103105 response <- get "/2"
104− liftIO $ do
105− decode' (simpleBody response) `shouldBe` Just tweety
106+ liftIO $ decode' (simpleBody response) `shouldBe` Just tweety
107+
108+ it "returns 404 if the decoding fails" $ do
109+ get "/notAnInt" `shouldRespondWith` 404
106110
107111 with (return (serve
108112 (Proxy :: Proxy (Capture "captured" String :> Raw))
@@ -122,18 +126,23 @@ getSpec = do
122126 describe "Servant.API.Get" $ do
123127 let server = return alice :<|> return ()
124128 with (return $ serve getApi server) $ do
129+
125130 it "allows to GET a Person" $ do
126131 response <- get "/"
127132 return response `shouldRespondWith` 200
128− liftIO $ do
129− decode' (simpleBody response) `shouldBe` Just alice
133+ liftIO $ decode' (simpleBody response) `shouldBe` Just alice
130134
131135 it "throws 405 (wrong method) on POSTs" $ do
132136 post "/" "" `shouldRespondWith` 405
137+ post "/empty" "" `shouldRespondWith` 405
133138
134139 it "returns 204 if the type is '()'" $ do
135140 get "empty" `shouldRespondWith` ""{ matchStatus = 204 }
136141
142+ it "returns 415 if the Accept header is not supported" $ do
143+ Test.Hspec.Wai.request methodGet "" [(hAccept, "crazy/mime")] ""
144+ `shouldRespondWith` 415
145+
137146
138147
139148type QueryParamApi = QueryParam "name" String :> Get '[JSON] Person
@@ -486,6 +495,9 @@ type AlternativeApi =
486495 "foo" :> Get '[JSON] Person
487496 :<|> "bar" :> Get '[JSON] Animal
488497 :<|> "foo" :> Get '[PlainText] T.Text
498+ :<|> "bar" :> Post '[JSON] Animal
499+ :<|> "bar" :> Put '[JSON] Animal
500+ :<|> "bar" :> Delete
489501unionApi :: Proxy AlternativeApi
490502unionApi = Proxy
491503
@@ -494,11 +506,15 @@ unionServer =
494506 return alice
495507 :<|> return jerry
496508 :<|> return "a string"
509+ :<|> return jerry
510+ :<|> return jerry
511+ :<|> return ()
497512
498513unionSpec :: Spec
499514unionSpec = do
500515 describe "Servant.API.Alternative" $ do
501516 with (return $ serve unionApi unionServer) $ do
517+
502518 it "unions endpoints" $ do
503519 response <- get "/foo"
504520 liftIO $ do
@@ -508,9 +524,13 @@ unionSpec = do
508524 liftIO $ do
509525 decode' (simpleBody response_) `shouldBe`
510526 Just jerry
511− it "checks all endpoints before returning 406" $ do
527+
528+ it "checks all endpoints before returning 415" $ do
512529 get "/foo" `shouldRespondWith` 200
513530
531+ it "returns 404 if the path does not exist" $ do
532+ get "/nonexistent" `shouldRespondWith` 404
533+
514534-- | Test server error functionality.
515535errorsSpec :: Spec
516536errorsSpec = do