rollbar-wai-1.0.0: test/Rollbar/WaiSpec.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Rollbar.WaiSpec
( spec
) where
import qualified Data.Aeson.KeyMap as KM
import qualified Data.Text as T
import qualified Network.Wai as W
import qualified Network.Wai.Handler.Warp as W
import Control.Concurrent (threadDelay)
import Control.Monad (join)
import Control.Monad.IO.Class
import Data.Aeson
import Data.IORef
import Network.HTTP.Req
import Network.HTTP.Types (status200, status404)
import Rollbar.Client
import Rollbar.Wai (rollbarOnExceptionWith)
import Test.Hspec
spec :: Spec
spec = before getSettingsAndItemRef $
describe "rollbarOnExceptionWith" $ do
context "when the response status code is 200" $
it "does not trigger a call to Rollbar" $
withApp $ \itemRef warpPort -> do
let url = http "localhost" /: "success"
response <- runReq
defaultHttpConfig
(req GET url NoReqBody bsResponse $ port warpPort)
responseStatusCode response `shouldBe` 200
responseBody response `shouldBe` "OK"
threadDelay 500
readIORef itemRef `shouldReturn` Nothing
context "when the response status code is not 200" $
it "triggers a call to Rollbar" $
withApp $ \itemRef warpPort -> do
let url = http "localhost" /: "error"
response <- fmap responseBody $ runReq
(defaultHttpConfig { httpConfigCheckResponse = \_ _ _ -> Nothing })
(req GET url NoReqBody bsResponse $ port warpPort)
response `shouldBe` "Something went wrong"
threadDelay 500
let portAsText = T.pack $ show warpPort
join . fmap itemRequest <$> readIORef itemRef `shouldReturn` Just
( Request
{ requestUrl = "http://localhost:" <> portAsText <> "/error"
, requestMethod = "GET"
, requestHeaders = KM.fromList
[ ("Accept-Encoding", "gzip")
, ("Host", String $ "localhost:" <> portAsText)
]
, requestParams = mempty
, requestGet = mempty
, requestQueryStrings = ""
, requestPost = mempty
, requestBody = ""
, requestUserIp = ""
}
)
getSettingsAndItemRef :: IO (Settings, IORef (Maybe Item))
getSettingsAndItemRef =
(,) <$> readSettings "rollbar.yaml"
<*> newIORef Nothing
withApp
:: (IORef (Maybe Item) -> W.Port -> IO a)
-> (Settings, IORef (Maybe Item))
-> IO a
withApp f (settings, itemRef) = do
let waiSettings = W.setOnException
(rollbarOnExceptionWith (createItemFake itemRef) settings)
W.defaultSettings
W.withApplicationSettings waiSettings (return app) $ f itemRef
app :: W.Application
app wrequest respond =
case W.rawPathInfo wrequest of
"/error" -> error "Boom"
"/success" -> respond $ W.responseLBS status200 [] "OK"
_ -> respond $ W.responseLBS status404 [] "Not Found"
createItemFake :: IORef (Maybe Item) -> Item -> Rollbar ()
createItemFake itemRef item = do
requestModifier <- getRequestModifier
liftIO $ writeIORef itemRef $ Just $
item { itemRequest = requestModifier <$> itemRequest item }