-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add Freckle.Test.Yesod and related modules
Extracted from megarepo, organized and documented a bit better, and added the MonadYesodExample class.
- Loading branch information
1 parent
832aeea
commit cdc3227
Showing
22 changed files
with
887 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
-- | Similar to "Yesod.Test" from the yesod-test package. | ||
-- | ||
-- Differences: | ||
-- | ||
-- * Contains a few additional conveniences, notably | ||
-- "Freckle.Test.Yesod.JsonAssertions" | ||
-- * Actions in the 'YesodExample' monad are generalized to a | ||
-- 'MonadYesodExample' constraint, allowing tests to be written | ||
-- in custom monads more easily. | ||
module Freckle.Test.Yesod (module X) where | ||
|
||
import Freckle.Test.Yesod.BodyAssertions as X | ||
import Freckle.Test.Yesod.Cookies as X | ||
import Freckle.Test.Yesod.Foundation as X | ||
import Freckle.Test.Yesod.GeneralAssertions as X | ||
import Freckle.Test.Yesod.GetBody as X | ||
import Freckle.Test.Yesod.HeaderAssertions as X | ||
import Freckle.Test.Yesod.JsonAssertions as X | ||
import Freckle.Test.Yesod.MakingRequests as X | ||
import Freckle.Test.Yesod.MonadYesodExample as X | ||
import Freckle.Test.Yesod.RequestBuilder as X | ||
import Freckle.Test.Yesod.SResponse as X | ||
import Freckle.Test.Yesod.StatusAssertions as X |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
module Freckle.Test.Yesod.BodyAssertions | ||
( bodyContains | ||
, bodyEquals | ||
, bodyNotContains | ||
) | ||
where | ||
|
||
import Freckle.App.Prelude | ||
import Freckle.Test.Yesod.MonadYesodExample | ||
|
||
import qualified Yesod.Test | ||
|
||
-- | Assert the last response has the given text | ||
-- | ||
-- The check is performed using the response body in full text form. | ||
bodyContains :: forall m site. MonadYesodExample site m => String -> m () | ||
bodyContains = liftYesodExample . Yesod.Test.bodyContains | ||
|
||
-- | Assert the last response is exactly equal to the given text | ||
-- | ||
-- This is useful for testing API responses. | ||
bodyEquals :: forall m site. MonadYesodExample site m => String -> m () | ||
bodyEquals = liftYesodExample . Yesod.Test.bodyEquals | ||
|
||
-- | Assert the last response doesn't have the given text | ||
-- | ||
-- The check is performed using the response body in full text form. | ||
bodyNotContains :: forall m site. MonadYesodExample site m => String -> m () | ||
bodyNotContains = liftYesodExample . Yesod.Test.bodyNotContains |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
module Freckle.Test.Yesod.Cookies | ||
( getRequestCookies | ||
, testSetCookie | ||
, testDeleteCookie | ||
, testClearCookies | ||
) | ||
where | ||
|
||
import Freckle.App.Prelude | ||
import Freckle.Test.Yesod.MonadYesodExample | ||
|
||
import Data.ByteString (ByteString) | ||
import Web.Cookie (SetCookie) | ||
import Yesod.Test (getRequestCookies) | ||
import qualified Yesod.Test | ||
|
||
-- | Clears the current cookies | ||
testClearCookies :: forall m site. MonadYesodExample site m => m () | ||
testClearCookies = liftYesodExample $ Yesod.Test.testClearCookies | ||
Check warning on line 19 in library/Freckle/Test/Yesod/Cookies.hs GitHub Actions / lint
|
||
|
||
-- | Deletes the cookie of the given name | ||
testDeleteCookie | ||
:: forall m site. MonadYesodExample site m => ByteString -> m () | ||
testDeleteCookie = liftYesodExample . Yesod.Test.testDeleteCookie | ||
|
||
-- | Sets a cookie | ||
testSetCookie :: forall m site. MonadYesodExample site m => SetCookie -> m () | ||
testSetCookie = liftYesodExample . Yesod.Test.testSetCookie |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
module Freckle.Test.Yesod.Foundation | ||
( TestApp | ||
, YesodExample | ||
, YesodExampleData (..) | ||
, SIO | ||
, testApp | ||
, getTestYesod | ||
) | ||
where | ||
|
||
import Freckle.Test.Yesod.MonadYesodExample | ||
|
||
import Yesod.Test | ||
( SIO | ||
, TestApp | ||
, YesodExample | ||
, YesodExampleData (..) | ||
, testApp | ||
) | ||
import qualified Yesod.Test | ||
|
||
-- | Get the foundation value used for the current test | ||
getTestYesod :: forall m site. MonadYesodExample site m => m site | ||
getTestYesod = liftYesodExample Yesod.Test.getTestYesod |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
module Freckle.Test.Yesod.GeneralAssertions | ||
( assertEq | ||
, assertEqualNoShow | ||
, assertNotEq | ||
) | ||
where | ||
|
||
import Freckle.App.Prelude | ||
import Freckle.Test.Yesod.MonadYesodExample | ||
|
||
import qualified Yesod.Test | ||
|
||
-- | Asserts that the two given values are equal | ||
-- | ||
-- The error message includes the values. | ||
assertEq | ||
:: forall a m site | ||
. (MonadYesodExample site m, Eq a, Show a) | ||
=> String | ||
-> a | ||
-> a | ||
-> m () | ||
assertEq s a b = liftYesodExample $ Yesod.Test.assertEq s a b | ||
|
||
-- | Like 'assertEq' but the error message does not include the values | ||
assertEqualNoShow | ||
:: forall a m site. (MonadYesodExample site m, Eq a) => String -> a -> a -> m () | ||
assertEqualNoShow s a b = liftYesodExample $ Yesod.Test.assertEqualNoShow s a b | ||
|
||
-- | Asserts that the two given values are not equal | ||
-- | ||
-- In case they are equal, the error message includes the values. | ||
assertNotEq | ||
:: forall a m site | ||
. (Eq a, Show a, MonadYesodExample site m) | ||
=> String | ||
-> a | ||
-> a | ||
-> m () | ||
assertNotEq s a b = liftYesodExample $ Yesod.Test.assertNotEq s a b |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
module Freckle.Test.Yesod.GetBody | ||
( getRawBody | ||
, getCsvBody | ||
, getJsonBody | ||
) | ||
where | ||
|
||
import Freckle.App.Prelude | ||
import Freckle.Test.Yesod.MonadYesodExample | ||
import Freckle.Test.Yesod.SResponse | ||
|
||
import Data.Aeson (FromJSON, eitherDecode) | ||
import qualified Data.ByteString.Lazy as BSL | ||
import Data.Csv (FromNamedRecord, decodeByName) | ||
import qualified Data.Vector as V | ||
import UnliftIO.Exception (throwString) | ||
|
||
-- | Get the body of the most recent response and decode it as JSON | ||
getJsonBody :: forall a m site. (MonadYesodExample site m, FromJSON a) => m a | ||
getJsonBody = either err pure . eitherDecode =<< getRawBody | ||
where | ||
err e = throwString $ "Error decoding JSON response body: " <> e | ||
|
||
-- | Get the body of the most recent response and decode it as CSV | ||
getCsvBody | ||
:: forall a m site. (MonadYesodExample site m, FromNamedRecord a) => m [a] | ||
getCsvBody = either err (pure . V.toList . snd) . decodeByName =<< getRawBody | ||
where | ||
err e = throwString $ "Error decoding CSV response body: " <> e | ||
|
||
-- | Get the body of the most recent response as a byte string | ||
getRawBody :: forall m site. MonadYesodExample site m => m BSL.ByteString | ||
getRawBody = | ||
fmap simpleBody . maybe (throwString "Test response had no body") pure | ||
=<< getResponse |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
module Freckle.Test.Yesod.HeaderAssertions | ||
( assertHeader | ||
, assertHeaderContains | ||
, assertHeaderSatisfies | ||
, assertNoHeader | ||
) | ||
where | ||
|
||
import Freckle.App.Prelude | ||
import Freckle.Test.Yesod.MonadYesodExample | ||
import Freckle.Test.Yesod.SResponse | ||
|
||
import Data.ByteString (ByteString) | ||
import qualified Data.ByteString as BS | ||
import Data.CaseInsensitive (CI) | ||
import Test.Hspec.Expectations.Lifted (expectationFailure) | ||
import qualified Yesod.Test | ||
|
||
-- | Assert that the given header field's value satisfied some predicate | ||
assertHeaderSatisfies | ||
:: forall m site | ||
. MonadYesodExample site m | ||
=> CI ByteString | ||
-- ^ Field name | ||
-> String | ||
-- ^ Some description of the predicate; this is included | ||
-- in the error message if the assertion fails | ||
-> (ByteString -> Bool) | ||
-- ^ Predicate applied to the field value which is expected | ||
-- to return 'True' | ||
-> m () | ||
assertHeaderSatisfies header predicateDesc predicate = liftYesodExample $ withResponse $ \res -> | ||
case lookup header $ simpleHeaders res of | ||
Just value | predicate value -> pure () | ||
Just value -> | ||
expectationFailure $ | ||
concat | ||
[ "Expected header " | ||
, show header | ||
, " " | ||
, predicateDesc | ||
, ", but received " | ||
, show value | ||
] | ||
Nothing -> | ||
expectationFailure $ | ||
concat | ||
[ "Expected header " | ||
, show header | ||
, predicateDesc | ||
, ", but it was not present" | ||
] | ||
|
||
-- | Assert that the given header field's value contains | ||
-- some particular byte string within it | ||
assertHeaderContains | ||
:: MonadYesodExample site m | ||
=> CI ByteString | ||
-- ^ Field name | ||
-> ByteString | ||
-- ^ Substring that we expect to find anywhere within the field value | ||
-> m () | ||
assertHeaderContains header substring = | ||
assertHeaderSatisfies | ||
header | ||
("to contain " <> show substring) | ||
(substring `BS.isInfixOf`) | ||
|
||
-- | Assert the given header key/value pair was returned | ||
assertHeader | ||
:: forall m site | ||
. MonadYesodExample site m | ||
=> CI ByteString | ||
-- ^ Field name | ||
-> ByteString | ||
-- ^ Expected field value | ||
-> m () | ||
assertHeader k v = liftYesodExample $ Yesod.Test.assertHeader k v | ||
|
||
-- | Assert the given header was __not__ included in the response | ||
assertNoHeader | ||
:: forall m site | ||
. MonadYesodExample site m | ||
=> CI ByteString | ||
-- ^ Field name | ||
-> m () | ||
assertNoHeader = liftYesodExample . Yesod.Test.assertNoHeader |
Oops, something went wrong.