Skip to content

Commit

Permalink
Transaction tests via CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
Piotr Stachyra committed Jun 5, 2019
1 parent 0bbab9d commit 900765a
Show file tree
Hide file tree
Showing 5 changed files with 497 additions and 40 deletions.
66 changes: 62 additions & 4 deletions lib/http-bridge/test/integration/Test/Integration/Framework/DSL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ module Test.Integration.Framework.DSL
, expectListSizeEqual
, expectResponseCode
, expectEventually
, expectEventually'
, expectValidJSON
, expectCliFieldBetween
, expectCliFieldEqual
, verify
, Headers(..)
, Payload(..)
Expand Down Expand Up @@ -184,6 +187,9 @@ import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import qualified Network.HTTP.Types.Status as HTTP

--
-- API response expectations
--

-- | Expect an errored response, without any further assumptions
expectError
Expand Down Expand Up @@ -306,25 +312,77 @@ expectEventually
expectEventually ctx getter target (_, res) = case res of
Left e -> wantedSuccessButError e
Right s -> loopUntilRestore (s ^. walletId)

where
loopUntilRestore :: (MonadIO m, MonadCatch m) => Text -> m ()
loopUntilRestore wid = do
r <- request @ApiWallet ctx ("GET", "v2/wallets/" <> wid) Default Empty
let target' = getFromResponse getter r
unless (target' >= target) $ loopUntilRestore wid

expectEventually'
:: (MonadIO m, MonadCatch m, MonadFail m, Ord a)
=> Context
-> Lens' ApiWallet a
-> a
-> ApiWallet
-> m ()
expectEventually' ctx target value wallet = do
rb <- request @ApiWallet ctx (getWallet wallet) Default Empty
expectEventually ctx target value rb
--
-- CLI output expectations
--

-- | Expects a given string to be a valid JSON output corresponding to some
-- given data-type 'a'
-- given data-type 'a'. Returns this type if successful.
expectValidJSON
:: forall m a. (MonadFail m, FromJSON a)
=> Proxy a
-> String
-> m ()
-> m a
expectValidJSON _ str =
case Aeson.eitherDecode @a (BL8.pack str) of
Left e -> fail $ "expected valid JSON but failed decoding: " <> show e
Right _ -> return ()
Right a -> return a

-- | Expects wallet from the request to eventually reach the given state or
-- beyond
-- expectCliEventually
-- :: (MonadIO m, MonadCatch m, MonadFail m, Ord a)
-- => Lens' ApiWallet a
-- -> a
-- -> ApiWallet
-- -> m ()
-- expectCliEventually getter target w = loopUntilRestore (w ^. walletId)
-- where
-- loopUntilRestore :: (MonadIO m, MonadCatch m) => Text -> IO ()
-- loopUntilRestore wid = do
-- Stdout out <- getWalletViaCLI (T.unpack wid)
-- outJson <- expectValidJSON (Proxy @ApiWallet) out
-- let target' = view getter outJson
-- unless (target' >= target) $ loopUntilRestore wid

expectCliFieldBetween
:: (MonadIO m, MonadFail m, Show a, Ord a)
=> Lens' s a
-> (a, a)
-> s
-> m ()
expectCliFieldBetween getter (aMin, aMax) s = case view getter s of
a | a < aMin -> fail $
"expected " <> show a <> " >= " <> show aMin
a | a > aMax -> fail $
"expected " <> show a <> " <= " <> show aMax
_ ->
return ()

expectCliFieldEqual
:: (MonadIO m, MonadFail m, Show a, Eq a)
=> Lens' s a
-> a
-> s
-> m ()
expectCliFieldEqual getter a out = (view getter out) `shouldBe` a

-- | Apply 'a' to all actions in sequence
verify :: (Monad m) => a -> [a -> m ()] -> m ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,17 @@ module Test.Integration.Framework.TestData
, updatePassPayload

-- * Error messages
, errMsg403Fee
, errMsg403NotEnoughMoney
, errMsg403UTxO
, errMsg403WrongPass
, errMsg404NoEndpoint
, errMsg404NoRootKey
, errMsg404NoWallet
, errMsg405
, errMsg406
, errMsg415
, errMsg500
) where

import Prelude
Expand Down Expand Up @@ -204,6 +208,23 @@ updatePassPayload oldPass newPass = Json [json| {
---
--- Error messages
---
errMsg403Fee :: String
errMsg403Fee = "I'm unable to adjust the given transaction to cover the\
\ associated fee! In order to do so, I'd have to select one or\
\ more additional inputs, but I can't do that without increasing\
\ the size of the transaction beyond the acceptable limit."

errMsg403NotEnoughMoney :: Int -> Int -> String
errMsg403NotEnoughMoney has needs = "I can't process this payment because there's\
\ not enough UTxO available in the wallet. The total UTxO sums up to\
\ " ++ show has ++ " Lovelace, but I need " ++ show needs ++ " Lovelace\
\ (excluding fee amount) in order to proceed with the payment."

errMsg403UTxO :: String
errMsg403UTxO = "When creating new transactions, I'm not able to re-use the\
\ same UTxO for different outputs. Here, I only have 1\
\ available, but there are 2 outputs."

errMsg403WrongPass :: String
errMsg403WrongPass = "The given encryption passphrase doesn't match the one\
\ I use to encrypt the root private key of the given wallet"
Expand Down Expand Up @@ -238,3 +259,9 @@ errMsg415 = "I'm really sorry but I only understand 'application/json'. I need\
\ you to tell me what language you're speaking in order for me to understand\
\ your message. Please double-check your 'Content-Type' request header and\
\ make sure it's set to 'application/json'"

errMsg500 :: String
errMsg500 = "That's embarassing. It looks like I've created an invalid\
\ transaction that could not be parsed by the node. Here's an error\
\ message that may help with debugging: Transaction failed verification:\
\ output with no credited value"
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,16 @@ import Test.Integration.Framework.DSL
)
import Test.Integration.Framework.TestData
( arabicWalletName
, errMsg403Fee
, errMsg403NotEnoughMoney
, errMsg403UTxO
, errMsg403WrongPass
, errMsg404NoEndpoint
, errMsg404NoWallet
, errMsg405
, errMsg406
, errMsg415
, errMsg500
, falseWalletIds
, kanjiWalletName
, polishWalletName
Expand Down Expand Up @@ -252,10 +256,7 @@ spec = do
r <- request @(ApiTransaction t) ctx (postTx wSrc) Default payload
verify r
[ expectResponseCode HTTP.status403
, expectErrorMessage
"When creating new transactions, I'm not able to re-use the \
\same UTxO for different outputs. Here, I only have 1 \
\available, but there are 2 outputs."
, expectErrorMessage errMsg403UTxO
]

it "TRANS_CREATE_03 - 0 balance after transaction" $ \ctx -> do
Expand Down Expand Up @@ -319,11 +320,7 @@ spec = do
r <- request @(ApiTransaction t) ctx (postTx wSrc) Default payload
verify r
[ expectResponseCode HTTP.status403
, expectErrorMessage
"I'm unable to adjust the given transaction to cover the \
\associated fee! In order to do so, I'd have to select one or \
\more additional inputs, but I can't do that without increasing \
\the size of the transaction beyond the acceptable limit."
, expectErrorMessage errMsg403Fee
]

it "TRANS_CREATE_04 - Not enough money" $ \ctx -> do
Expand All @@ -345,11 +342,7 @@ spec = do
r <- request @(ApiTransaction t) ctx (postTx wSrc) Default payload
verify r
[ expectResponseCode HTTP.status403
, expectErrorMessage
"I can't process this payment because there's not enough \
\UTxO available in the wallet. The total UTxO sums up to \
\100000 Lovelace, but I need 1000000 Lovelace (excluding fee \
\amount) in order to proceed with the payment."
, expectErrorMessage (errMsg403NotEnoughMoney 100_000 1000_000)
]

it "TRANS_CREATE_04 - Wrong password" $ \ctx -> do
Expand Down Expand Up @@ -466,12 +459,7 @@ spec = do
[ ( "Quantity = 0"
, [json|{"quantity": 0, "unit": "lovelace"}|]
, [ expectResponseCode HTTP.status500
, expectErrorMessage "That's embarassing. It looks\
\ like I've created an invalid transaction that\
\ could not be parsed by the node. Here's an error\
\ message that may help with debugging:\
\ Transaction failed verification: output with no\
\ credited value" ]
, expectErrorMessage errMsg500 ] -- TODO change after #364
)
, ( "Quantity = 1.5"
, [json|{"quantity": 1.5, "unit": "lovelace"}|]
Expand Down
Loading

0 comments on commit 900765a

Please sign in to comment.