Skip to content
Snippets Groups Projects
Stripe.hs 3.75 KiB
Newer Older
  • Learn to ignore specific revisions
  • {-# LANGUAGE OverloadedStrings #-}
    
    -- | Tests related to PaymentServer.Processors.Stripe.
    
    module Stripe
      ( tests
      ) where
    
    import Test.Tasty
      ( TestTree
      , testGroup
      )
    import Test.Tasty.HUnit
      ( testCase
      , assertEqual
      )
    
    
    
    import Control.Monad.IO.Class
      ( liftIO
      )
    
    
    import Control.Monad.Trans.Except
      ( runExceptT
      )
    
    import Servant.Server
      ( Handler(runHandler')
      , ServerError(ServerError)
      )
    
    import Web.Stripe.Types
      ( Currency(USD, AED)
      )
    
    
    import Network.Wai.Test
      ( SRequest(SRequest)
      , runSession
      , request
      , srequest
      , defaultRequest
      , assertHeader
      , setPath
      )
    
    import Network.Wai
      ( requestMethod
      , requestHeaders
      )
    
    
    import PaymentServer.Persistence
      ( memory
      )
    
    import PaymentServer.Processors.Stripe
      ( Charges(Charges)
      , Acknowledgement(Ok)
      , charge
    
      )
    
    
    import PaymentServer.Issuer
      ( trivialIssue
      )
    
    import PaymentServer.Server
      ( paymentServerApp
      )
    
    
    import FakeStripe
      ( withFakeStripe
      , chargeOkay
      )
    
    tests :: TestTree
    tests = testGroup "Stripe"
      [ chargeTests
    
      , corsTests
      ]
    
    corsTests :: TestTree
    corsTests =
      testGroup "CORS"
      [ testCase "a request with the wrong content-type receives a CORS-enabled response" $
        assertCORSHeader "POST" textPlain validChargeBytes
      , testCase "a request without a valid charge in the body receives a CORS-enabled response" $
        assertCORSHeader "POST" applicationJSON invalidChargeBytes
      , testCase "a request with the wrong request method receives a CORS-enabled response" $
        assertCORSHeader "GET" applicationJSON validChargeBytes
      , testCase "a request with a valid charge in the body receives a CORS-enabled response" $
        assertCORSHeader "POST" applicationJSON validChargeBytes
    
      where
        textPlain = [("content-type", "text/plain")]
        applicationJSON = [("content-type", "application/json")]
        validChargeBytes = "{\"token\": \"abcdef\", \"voucher\": \"lmnopqrst\", \"amount\": \"650\", \"currency\": \"USD\"}"
        invalidChargeBytes = "[1, 2, 3]"
    
        assertCORSHeader method headers body =
          withFakeStripe (return chargeOkay) $
          \stripeConfig -> do
            db <- memory
            let origins = ["example.invalid"]
            let app = paymentServerApp origins stripeConfig trivialIssue db
    
            let path = "/v1/stripe/charge"
    
            let theRequest = setPath defaultRequest
                  { requestMethod = method
                  , requestHeaders = ("origin", "example.invalid"):headers
                  } path
    
            let theSRequest = SRequest theRequest body
            (flip runSession) app $ do
              response <- srequest theSRequest
              assertHeader "Access-Control-Allow-Origin" "example.invalid" response
    
    
    
    chargeTests :: TestTree
    chargeTests =
      testGroup "Charges"
      [ testCase "non-USD currency is rejected" $
        withFakeStripe (return chargeOkay) $ \stripeConfig -> do
          let amount = 650
          let currency = AED
          db <- memory
          (Left (ServerError code _ _ _)) <- runExceptT . runHandler' $ charge stripeConfig db (Charges token voucher amount currency)
          assertEqual "The result is an error" 400 code
      , testCase "incorrect USD amount is rejected" $
        withFakeStripe (return chargeOkay) $ \stripeConfig -> do
          let amount = 649
          let currency = USD
          db <- memory
          (Left (ServerError code _ _ _)) <- runExceptT . runHandler' $ charge stripeConfig db (Charges token voucher amount currency)
          assertEqual "The result is an error" 400 code
      , testCase "currect USD amount is accepted" $
        withFakeStripe (return chargeOkay) $ \stripeConfig -> do
          let amount = 650
          let currency = USD
          db <- memory
          result <- runExceptT . runHandler' $ charge stripeConfig db (Charges token voucher amount currency)
          assertEqual "The result is Ok" (Right Ok) result
      ]
      where
        token = "foo"
        voucher = "bar"