Skip to content

Commit

Permalink
add illustrative integration test for patching
Browse files Browse the repository at this point in the history
  • Loading branch information
paweljakubas committed Apr 15, 2021
1 parent 4317620 commit d59b40d
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 17 deletions.
26 changes: 25 additions & 1 deletion lib/core-integration/src/Test/Integration/Framework/DSL.hs
Expand Up @@ -77,6 +77,7 @@ module Test.Integration.Framework.DSL
, postSharedWallet
, deleteSharedWallet
, getSharedWallet
, patchSharedWallet

-- * Wallet helpers
, listFilteredWallets
Expand Down Expand Up @@ -258,6 +259,8 @@ import Cardano.Wallet.Primitive.AddressDerivation.Icarus
( IcarusKey )
import Cardano.Wallet.Primitive.AddressDerivation.Shelley
( ShelleyKey )
import Cardano.Wallet.Primitive.AddressDiscovery.Script
( CredentialType (..) )
import Cardano.Wallet.Primitive.AddressDiscovery.Sequential
( coinTypeAda )
import Cardano.Wallet.Primitive.SyncProgress
Expand Down Expand Up @@ -1342,7 +1345,6 @@ fixtureMultiAssetIcarusWallet ctx = do
]
return (getFromResponse id rb)


postSharedWallet
:: (MonadIO m, MonadUnliftIO m)
=> Context
Expand Down Expand Up @@ -1390,6 +1392,28 @@ getSharedWallet ctx (ApiSharedWallet (Right w)) = do
let link = Link.getSharedWallet w
request @ApiSharedWallet ctx link Default Empty

patchEndpointEnding :: CredentialType -> Text
patchEndpointEnding = \case
Payment -> "payment-script-template"
Delegation -> "delegation-script-template"

patchSharedWallet
:: forall m.
( MonadIO m
, MonadUnliftIO m
)
=> Context
-> ApiSharedWallet
-> CredentialType
-> Payload
-> m (HTTP.Status, Either RequestException ApiSharedWallet)
patchSharedWallet ctx (ApiSharedWallet (Left w)) cred payload = do
let endpoint = "v2/shared-wallets" </> w ^. walletId </> patchEndpointEnding cred
request @ApiSharedWallet ctx ("PATCH", endpoint) Default payload
patchSharedWallet ctx (ApiSharedWallet (Right w)) cred payload = do
let endpoint = "v2/shared-wallets" </> w ^. walletId </> patchEndpointEnding cred
request @ApiSharedWallet ctx ("PATCH", endpoint) Default payload

fixtureRawTx
:: Context
-> (Address, Natural)
Expand Down
Expand Up @@ -9,33 +9,54 @@
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}

module Test.Integration.Scenario.API.Shelley.SharedWallets
( spec
) where

import Prelude

import Cardano.Address.Derivation
( XPub, xpubFromBytes, xpubToBytes )
import Cardano.Address.Script
( Cosigner (..), ScriptTemplate (..) )
import Cardano.Wallet.Api.Types
( ApiSharedWallet (..)
, DecodeAddress
, DecodeStakeAddress
, EncodeAddress (..)
)
import Cardano.Wallet.Primitive.AddressDerivation
( DerivationIndex (..), PaymentAddress )
( DerivationIndex (..), PaymentAddress, fromHex, hex )
import Cardano.Wallet.Primitive.AddressDerivation.Shelley
( ShelleyKey )
import Cardano.Wallet.Primitive.AddressDiscovery.Script
( CredentialType (..) )
import Cardano.Wallet.Primitive.SyncProgress
( SyncProgress (..) )
import Control.Monad
( (>=>) )
import Control.Monad.IO.Class
( liftIO )
import Control.Monad.Trans.Resource
( runResourceT )
import Data.Aeson.Types
( ToJSON (..) )
import Data.Bifunctor
( second )
import Data.ByteString
( ByteString )
import Data.Either.Extra
( eitherToMaybe )
import Data.Generics.Internal.VL.Lens
( (^.) )
import Data.Quantity
( Quantity (..) )
import Data.Text
( Text )
import Test.Hspec
( SpecWith, describe, shouldBe, shouldNotBe )
import Test.Hspec.Extra
Expand All @@ -55,10 +76,13 @@ import Test.Integration.Framework.DSL
, getSharedWallet
, json
, notDelegating
, patchSharedWallet
, postSharedWallet
, verify
)

import qualified Data.Map.Strict as Map
import qualified Data.Text.Encoding as T
import qualified Network.HTTP.Types as HTTP

spec :: forall n.
Expand Down Expand Up @@ -228,3 +252,51 @@ spec = describe "SHARED_WALLETS" $ do

rDel <- deleteSharedWallet ctx wal
expectResponseCode HTTP.status204 rDel

it "SHARED_WALLETS_PATCH_01 - Patch a pending shared wallet to active shared wallet" $ \ctx -> runResourceT $ do
let accXPubTxt0 = "1423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db11423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db2"
let payloadCreate = Json [json| {
"name": "Shared Wallet",
"account_public_key": #{accXPubTxt0},
"account_index": "30H",
"payment_script_template":
{ "cosigners":
{ "cosigner#0": #{accXPubTxt0} },
"template":
{ "all":
[ "cosigner#0",
"cosigner#1",
{ "active_from": 120 }
]
}
}
} |]
rPost <- postSharedWallet ctx Default payloadCreate
expectResponseCode HTTP.status201 rPost
let wal@(ApiSharedWallet (Left pendingWal)) = getFromResponse id rPost
let cosignerKeysPost = pendingWal ^. #paymentScriptTemplate
let (Just accXPub0) = xpubFromText accXPubTxt0
liftIO $ cosigners cosignerKeysPost `shouldBe` Map.fromList [(Cosigner 0,accXPub0)]

let accXPubTxt1 = "1423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db11423856bc91c49e928f6f30f4e8d665d53eb4ab6028bd0ac971809d514c92db8"
let (Just accXPub1) = xpubFromText accXPubTxt1

let payloadPatch = Json [json| {
"account_public_key": #{accXPub1},
"cosigner": "cosigner#1"
} |]

rPatch <- patchSharedWallet ctx wal Payment payloadPatch
expectResponseCode HTTP.status200 rPatch
let (ApiSharedWallet (Right activeWal)) = getFromResponse id rPatch
let cosignerKeysPatch = activeWal ^. #paymentScriptTemplate
liftIO $ cosigners cosignerKeysPatch `shouldBe` Map.fromList [(Cosigner 0,accXPub0), (Cosigner 1,accXPub1)]
where
xpubFromText :: Text -> Maybe XPub
xpubFromText = fmap eitherToMaybe fromHexText >=> xpubFromBytes

fromHexText :: Text -> Either String ByteString
fromHexText = fromHex . T.encodeUtf8

instance ToJSON XPub where
toJSON = toJSON . T.decodeLatin1 . hex . xpubToBytes
4 changes: 2 additions & 2 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Expand Up @@ -989,12 +989,12 @@ patchSharedWallet
, Typeable n
)
=> ctx
-> ApiT WalletId
-> (XPub -> k 'AccountK XPub)
-> CredentialType
-> ApiT WalletId
-> ApiSharedWalletPatchData
-> Handler ApiSharedWallet
patchSharedWallet ctx (ApiT wid) liftKey cred body = do
patchSharedWallet ctx liftKey cred (ApiT wid) body = do
withWorkerCtx ctx wid liftE liftE $ \wrk -> do
liftHandler $ W.updateCosigner wrk wid (liftKey accXPub) cosigner cred
fst <$> getWallet ctx (mkSharedWallet @_ @s @k) (ApiT wid)
Expand Down
19 changes: 6 additions & 13 deletions lib/shelley/src/Cardano/Wallet/Shelley/Api/Server.hs
Expand Up @@ -83,6 +83,7 @@ import Cardano.Wallet.Api.Server
, mkLegacyWallet
, mkSharedWallet
, mkShelleyWallet
, patchSharedWallet
, postAccountPublicKey
, postAccountWallet
, postExternalTransaction
Expand Down Expand Up @@ -142,6 +143,8 @@ import Cardano.Wallet.Primitive.AddressDerivation.Shelley
( ShelleyKey (..), generateKeyFromSeed )
import Cardano.Wallet.Primitive.AddressDiscovery.Random
( RndState )
import Cardano.Wallet.Primitive.AddressDiscovery.Script
( CredentialType (..) )
import Cardano.Wallet.Primitive.AddressDiscovery.Sequential
( SeqState )
import Cardano.Wallet.Primitive.AddressDiscovery.SharedState
Expand Down Expand Up @@ -177,14 +180,7 @@ import Data.Text.Class
import Network.Ntp
( NtpClient )
import Servant
( (:<|>) (..)
, Handler (..)
, NoContent (..)
, Server
, err400
, err501
, throwError
)
( (:<|>) (..), Handler (..), NoContent (..), Server, err400 )
import Servant.Server
( ServerError (..) )
import Type.Reflection
Expand Down Expand Up @@ -495,12 +491,9 @@ server byron icarus shelley multisig spl ntp =
sharedWallets =
postSharedWallet multisig generateKeyFromSeed ShelleyKey
:<|> (fmap fst . getWallet multisig mkSharedWallet)
:<|> patchSharedWalletInPayment
:<|> patchSharedWalletInDelegation
:<|> patchSharedWallet multisig ShelleyKey Payment
:<|> patchSharedWallet multisig ShelleyKey Delegation
:<|> deleteWallet multisig
where
patchSharedWalletInPayment _ = pure $ throwError err501
patchSharedWalletInDelegation _ = pure $ throwError err501

postAnyAddress
:: NetworkId
Expand Down

0 comments on commit d59b40d

Please sign in to comment.