yesod/yesod-core/test/YesodCoreTest/ErrorHandling.hs
Simon Hengel dfae661878 Adept Hspec tests for forward compatibility
* Don't use hspecX, it's deprecated.

 * Do not import Test.Hspec.HUnit.  It's no longer necessary and may be
   removed in the future.
2012-10-16 14:44:58 +02:00

128 lines
3.7 KiB
Haskell

{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module YesodCoreTest.ErrorHandling
( errorHandlingTest
, Widget
) where
import Yesod.Core
import Test.Hspec
import Network.Wai
import Network.Wai.Test
import Text.Hamlet (hamlet)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Char8 as S8
import Control.Exception (SomeException, try)
data App = App
mkYesod "App" [parseRoutes|
/ HomeR GET
/not_found NotFoundR POST
/first_thing FirstThingR POST
/after_runRequestBody AfterRunRequestBodyR POST
/error-in-body ErrorInBodyR GET
/error-in-body-noeval ErrorInBodyNoEvalR GET
|]
instance Yesod App
getHomeR :: Handler RepHtml
getHomeR = do
$logDebug "Testing logging"
defaultLayout $ toWidget [hamlet|
$doctype 5
<html>
<body>
<form method=post action=@{NotFoundR}>
<input type=submit value="Not found">
<form method=post action=@{FirstThingR}>
<input type=submit value="Error is thrown first thing in handler">
<form method=post action=@{AfterRunRequestBodyR}>
<input type=submit value="BUGGY: Error thrown after runRequestBody">
|]
postNotFoundR, postFirstThingR, postAfterRunRequestBodyR :: Handler RepHtml
postNotFoundR = do
(_, _files) <- runRequestBody
_ <- notFound
getHomeR
postFirstThingR = do
_ <- error "There was an error 3.14159"
getHomeR
postAfterRunRequestBodyR = do
x <- runRequestBody
_ <- error $ show $ fst x
getHomeR
getErrorInBodyR :: Handler RepHtml
getErrorInBodyR = do
let foo = error "error in body 19328" :: String
defaultLayout [whamlet|#{foo}|]
getErrorInBodyNoEvalR :: Handler (DontFullyEvaluate RepHtml)
getErrorInBodyNoEvalR = fmap DontFullyEvaluate getErrorInBodyR
errorHandlingTest :: Spec
errorHandlingTest = describe "Test.ErrorHandling" $ do
it "says not found" caseNotFound
it "says 'There was an error' before runRequestBody" caseBefore
it "says 'There was an error' after runRequestBody" caseAfter
it "error in body == 500" caseErrorInBody
it "error in body, no eval == 200" caseErrorInBodyNoEval
runner :: Session () -> IO ()
runner f = toWaiApp App >>= runSession f
caseNotFound :: IO ()
caseNotFound = runner $ do
res <- request defaultRequest
{ pathInfo = ["not_found"]
, requestMethod = "POST"
}
assertStatus 404 res
assertBodyContains "Not Found" res
caseBefore :: IO ()
caseBefore = runner $ do
res <- request defaultRequest
{ pathInfo = ["first_thing"]
, requestMethod = "POST"
}
assertStatus 500 res
assertBodyContains "There was an error 3.14159" res
caseAfter :: IO ()
caseAfter = runner $ do
let content = "foo=bar&baz=bin12345"
res <- srequest SRequest
{ simpleRequest = defaultRequest
{ pathInfo = ["after_runRequestBody"]
, requestMethod = "POST"
, requestHeaders =
[ ("content-type", "application/x-www-form-urlencoded")
, ("content-length", S8.pack $ show $ L.length content)
]
}
, simpleRequestBody = content
}
assertStatus 500 res
assertBodyContains "bin12345" res
caseErrorInBody :: IO ()
caseErrorInBody = runner $ do
res <- request defaultRequest { pathInfo = ["error-in-body"] }
assertStatus 500 res
assertBodyContains "error in body 19328" res
caseErrorInBodyNoEval :: IO ()
caseErrorInBodyNoEval = do
eres <- try $ runner $ do
_ <- request defaultRequest { pathInfo = ["error-in-body-noeval"] }
return ()
case eres of
Left (_ :: SomeException) -> return ()
Right _ -> error "Expected an exception"