{-# LANGUAGE CPP, OverloadedStrings #-}
module Snap.Internal.Test.Assertions where
import Control.Monad (liftM)
import Data.ByteString.Builder (toLazyByteString)
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as S
import qualified Data.ByteString.Lazy.Char8 as L
import Data.Maybe (fromJust)
import Snap.Internal.Http.Types (Response (rspBody, rspStatus), getHeader, rspBodyToEnum)
import qualified System.IO.Streams as Streams
import Test.HUnit (Assertion, assertBool, assertEqual)
import Text.Regex.Posix ((=~))
#if !MIN_VERSION_base(4,8,0)
import Data.Monoid (mconcat)
#endif
getResponseBody :: Response -> IO ByteString
getResponseBody :: Response -> IO ByteString
getResponseBody Response
rsp = do
(OutputStream Builder
os, IO [Builder]
grab) <- forall c. IO (OutputStream c, IO [c])
Streams.listOutputStream
OutputStream Builder -> IO ()
enum OutputStream Builder
os
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM [Builder] -> ByteString
toBS IO [Builder]
grab
where
enum :: OutputStream Builder -> IO ()
enum OutputStream Builder
os = do
OutputStream Builder
os' <- ResponseBody -> StreamProc
rspBodyToEnum (Response -> ResponseBody
rspBody Response
rsp) OutputStream Builder
os
forall a. Maybe a -> OutputStream a -> IO ()
Streams.write forall a. Maybe a
Nothing OutputStream Builder
os'
toBS :: [Builder] -> ByteString
toBS = [ByteString] -> ByteString
S.concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
toLazyByteString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat
assertSuccess :: Response -> Assertion
assertSuccess :: Response -> IO ()
assertSuccess Response
rsp = forall a. (HasCallStack, Eq a, Show a) => String -> a -> a -> IO ()
assertEqual String
message Int
200 Int
status
where
message :: String
message = String
"Expected success (200) but got (" forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show Int
status) forall a. [a] -> [a] -> [a]
++ String
")"
status :: Int
status = Response -> Int
rspStatus Response
rsp
assert404 :: Response -> Assertion
assert404 :: Response -> IO ()
assert404 Response
rsp = forall a. (HasCallStack, Eq a, Show a) => String -> a -> a -> IO ()
assertEqual String
message Int
404 Int
status
where
message :: String
message = String
"Expected Not Found (404) but got (" forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show Int
status) forall a. [a] -> [a] -> [a]
++ String
")"
status :: Int
status = Response -> Int
rspStatus Response
rsp
assertRedirectTo :: ByteString
-> Response
-> Assertion
assertRedirectTo :: ByteString -> Response -> IO ()
assertRedirectTo ByteString
uri Response
rsp = do
Response -> IO ()
assertRedirect Response
rsp
forall a. (HasCallStack, Eq a, Show a) => String -> a -> a -> IO ()
assertEqual String
message ByteString
uri ByteString
rspUri
where
rspUri :: ByteString
rspUri = forall a. HasCallStack => Maybe a -> a
fromJust forall a b. (a -> b) -> a -> b
$ forall a. HasHeaders a => CI ByteString -> a -> Maybe ByteString
getHeader CI ByteString
"Location" Response
rsp
message :: String
message = String
"Expected redirect to " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ByteString
uri
forall a. [a] -> [a] -> [a]
++ String
" but got redirected to "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ByteString
rspUri forall a. [a] -> [a] -> [a]
++ String
" instead"
assertRedirect :: Response -> Assertion
assertRedirect :: Response -> IO ()
assertRedirect Response
rsp = HasCallStack => String -> Bool -> IO ()
assertBool String
message (Int
300 forall a. Ord a => a -> a -> Bool
<= Int
status Bool -> Bool -> Bool
&& Int
status forall a. Ord a => a -> a -> Bool
<= Int
399)
where
message :: String
message = String
"Expected redirect but got status code ("
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
status forall a. [a] -> [a] -> [a]
++ String
")"
status :: Int
status = Response -> Int
rspStatus Response
rsp
assertBodyContains :: ByteString
-> Response
-> Assertion
assertBodyContains :: ByteString -> Response -> IO ()
assertBodyContains ByteString
match Response
rsp = do
ByteString
body <- Response -> IO ByteString
getResponseBody Response
rsp
HasCallStack => String -> Bool -> IO ()
assertBool String
message (ByteString
body forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
RegexContext Regex source1 target) =>
source1 -> source -> target
=~ ByteString
match)
where
message :: String
message = String
"Expected body to match regexp \"" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ByteString
match
forall a. [a] -> [a] -> [a]
++ String
"\", but didn't"