@@ -9,8 +9,9 @@ module Network.HTTP.ReqSpec
99 ( spec )
1010where
1111
12−import Control.Exception (throwIO)
12+import Control.Exception
1313import Control.Monad.Reader
14+import Control.Monad.Trans.Control
1415import Data.Aeson (Value (..), ToJSON (..), object, (.=))
1516import Data.Default.Class
1617import Data.IORef
@@ -41,16 +42,17 @@ import Data.Word (Word)
4142spec :: Spec
4243spec = do
4344
44− describe "exception throwing on non 2xx-status codes" $
45− it "throws indeed for non-2xx" $ do
46− let selector :: HttpException -> Bool
47− selector (VanillaHttpException
48− (L.HttpExceptionRequest _
49− (L.StatusCodeException response chunk))) =
50− L.responseStatus response == Y.status404 && not (B.null chunk)
51− selector _ = False
45+ describe "exception throwing on non-2xx status codes" $
46+ it "throws indeed for non-2xx" $
5247 req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty
53− `shouldThrow` selector
48+ `shouldThrow` selector404
49+
50+ describe "exception throwing on non-2xx status codes (Req monad)" $
51+ it "throws indeed for non-2xx" $
52+ asIO . runReq def $
53+ liftBaseWith $ \run ->
54+ run (req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty)
55+ `shouldThrow` selector404
5456
5557 describe "response check via httpConfigCheckResponse" $
5658 context "if it's set to always throw" $
@@ -401,6 +403,15 @@ checkStatusCode code =
401403 NoReqBody ignoreResponse mempty
402404 responseStatusCode r `shouldBe` code
403405
406+-- | Exception selector that selects only 404 “Not found” exceptions.
407+
408+selector404 :: HttpException -> Bool
409+selector404 (VanillaHttpException
410+ (L.HttpExceptionRequest _
411+ (L.StatusCodeException response chunk))) =
412+ L.responseStatus response == Y.status404 && not (B.null chunk)
413+selector404 _ = False
414+
404415-- | Empty JSON 'Object'.
405416
406417emptyObject :: Value
@@ -410,3 +421,9 @@ emptyObject = Object HM.empty
410421
411422reflectJSON :: ToJSON a => a -> Text
412423reflectJSON = T.decodeUtf8 . BL.toStrict . A.encode
424+
425+-- | Clarify to the type checker that the inner computation is in the 'IO'
426+-- monad.
427+
428+asIO :: IO a -> IO a
429+asIO = id