From 0876e0d3b743ce9bfaf5aad80415b1cbf5656d40 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Fri, 23 Aug 2019 14:35:37 -0400 Subject: [PATCH] Get property tests working --- test/SpecStripe.hs | 25 ++++++++++++++----------- test/Util/Gen.hs | 8 ++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/test/SpecStripe.hs b/test/SpecStripe.hs index 8701540..9c4f61f 100644 --- a/test/SpecStripe.hs +++ b/test/SpecStripe.hs @@ -28,13 +28,15 @@ import Test.Hspec.Wai , shouldRespondWith , liftIO ) +import Test.Hspec.Wai.QuickCheck + ( property + ) import Test.QuickCheck ( Property , Gen , arbitrary , suchThat , suchThatMap - , property , generate , forAll , (===) @@ -47,7 +49,8 @@ import Util.WAI ( postJSON ) import Util.Gen - ( chargeSucceededEvents + ( GoodChargeEvent(GoodChargeEvent) + , chargeSucceededEvents , hasVoucher ) import Util.JSON @@ -83,14 +86,8 @@ stripeAPI = Proxy app :: IO Application app = memory >>= return . stripeServer >>= return . serve stripeAPI -aChargeEvent :: IO LazyBS.ByteString -aChargeEvent = encode <$> generate chargeSucceededEvents - spec_webhook :: Spec spec_webhook = with app $ do - -- I would like to make these property tests but I can't figure out how to - -- use QuickCheck (or Hedgehog) to write property tests for web code. - describe "error behavior of POST /webhook" $ do it "responds to non-JSON Content-Type with 415 (Unsupported Media Type)" $ post "/webhook" "xxx" `shouldRespondWith` 415 @@ -98,10 +95,16 @@ spec_webhook = with app $ do it "responds to JSON non-Event body with 400 (Invalid Request)" $ postJSON "/webhook" "{}" `shouldRespondWith` 400 + -- I would like to make most or all of these into property tests. *This* + -- test shows how you can do it. Yay. The main thing (for me, anyway) to + -- remember is to use `property` from Test.Hspec.Wai.QuickCheck and not from + -- `Test.QuickCheck`. :/ Unsure whether I love the apparent Haskell + -- convention of giving the same name to *similar* functions. describe "success behavior of POST /webhook" $ - it "responds to a JSON Event body with 200 (OK)" $ do - event <- liftIO aChargeEvent - postJSON "/webhook" event `shouldRespondWith` 200 { matchBody = MatchBody bodyMatcher } + it "responds to a JSON Event body with 200 (OK)" $ + property $ + \(GoodChargeEvent event) -> + postJSON "/webhook" (encode event) `shouldRespondWith` 200 { matchBody = MatchBody bodyMatcher } bodyMatcher :: [Network.HTTP.Types.Header] -> Body -> Maybe String bodyMatcher _ "{}" = Nothing diff --git a/test/Util/Gen.hs b/test/Util/Gen.hs index 5bdcd45..863116c 100644 --- a/test/Util/Gen.hs +++ b/test/Util/Gen.hs @@ -4,6 +4,7 @@ module Util.Gen ( chargeSucceededEvents , posixTimes , hasVoucher + , GoodChargeEvent(GoodChargeEvent) ) where import Data.Text @@ -143,6 +144,13 @@ chargeSucceededEvents = <*> arbitrary -- eventPendingWebHooks <*> arbitrary -- eventRequest + +data GoodChargeEvent = GoodChargeEvent Event deriving (Show, Eq) + +instance Arbitrary GoodChargeEvent where + arbitrary = chargeSucceededEvents `suchThatMap` (Just . GoodChargeEvent) + + posixTimes :: Gen UTCTime posixTimes = (arbitrary :: Gen Integer) `suchThatMap` (Just . posixSecondsToUTCTime . fromIntegral . abs) -- GitLab