-
Notifications
You must be signed in to change notification settings - Fork 213
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0dfcb11
commit 2ef2840
Showing
4 changed files
with
257 additions
and
0 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
243 changes: 243 additions & 0 deletions
243
lib/integration/scenarios/Test/Integration/Scenario/API/Voting.hs
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,243 @@ | ||
{-# LANGUAGE AllowAmbiguousTypes #-} | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE DuplicateRecordFields #-} | ||
{-# LANGUAGE FlexibleContexts #-} | ||
{-# LANGUAGE LambdaCase #-} | ||
{-# LANGUAGE NumericUnderscores #-} | ||
{-# LANGUAGE OverloadedLabels #-} | ||
{-# LANGUAGE QuasiQuotes #-} | ||
{-# LANGUAGE RankNTypes #-} | ||
{-# LANGUAGE ScopedTypeVariables #-} | ||
{-# LANGUAGE TupleSections #-} | ||
{-# LANGUAGE TypeApplications #-} | ||
{-# LANGUAGE TypeFamilies #-} | ||
|
||
module Test.Integration.Scenario.API.Voting (spec) where | ||
|
||
import Prelude | ||
|
||
import Cardano.Wallet.Address.Derivation | ||
( DerivationIndex (..) | ||
) | ||
import Cardano.Wallet.Api.Types | ||
( ApiAnyCertificate (..) | ||
, ApiCertificate (..) | ||
, ApiConstructTransaction (..) | ||
, ApiDecodedTransaction | ||
, ApiSerialisedTransaction (..) | ||
, ApiT (..) | ||
, ApiTransaction | ||
, ApiTxId (..) | ||
, ApiWallet (..) | ||
, WalletStyle (..) | ||
) | ||
import Cardano.Wallet.Api.Types.Amount | ||
( ApiAmount (ApiAmount) | ||
) | ||
import Cardano.Wallet.Primitive.NetworkId | ||
( HasSNetworkId | ||
) | ||
import Cardano.Wallet.Primitive.Types.DRep | ||
( DRep (..) | ||
) | ||
import Cardano.Wallet.Primitive.Types.Tx.TxMeta | ||
( Direction (..) | ||
, TxStatus (..) | ||
) | ||
import Control.Monad.Trans.Resource | ||
( runResourceT | ||
) | ||
import Data.Aeson | ||
( toJSON | ||
) | ||
import Test.Hspec | ||
( SpecWith | ||
, describe | ||
) | ||
import Test.Hspec.Expectations.Lifted | ||
( shouldBe | ||
) | ||
import Test.Hspec.Extra | ||
( it | ||
) | ||
import Test.Integration.Framework.DSL | ||
( Context (..) | ||
, Headers (..) | ||
, Payload (..) | ||
, eventually | ||
, expectField | ||
, expectResponseCode | ||
, expectSuccess | ||
, fixtureWallet | ||
, getFromResponse | ||
, getResponse | ||
, json | ||
, noBabbage | ||
, notDelegating | ||
, onlyVoting | ||
, request | ||
, signTx | ||
, submitTxWithWid | ||
, verify | ||
, waitNumberOfEpochBoundaries | ||
) | ||
|
||
import qualified Cardano.Wallet.Api.Link as Link | ||
import qualified Data.List.NonEmpty as NE | ||
import qualified Network.HTTP.Types.Status as HTTP | ||
|
||
spec :: forall n. HasSNetworkId n => SpecWith Context | ||
spec = describe "VOTING_TRANSACTIONS" $ do | ||
it "VOTING_01a - Can vote and revote" $ \ctx -> runResourceT $ do | ||
noBabbage ctx "voting supported in Conway onwards" | ||
src <- fixtureWallet ctx | ||
|
||
let getSrcWallet = | ||
let endpoint = Link.getWallet @'Shelley src | ||
in request @ApiWallet ctx endpoint Default Empty | ||
getSrcWallet >>= flip verify | ||
[ expectField #delegation (`shouldBe` notDelegating []) | ||
] | ||
|
||
let depositAmt = ApiAmount 1_000_000 | ||
let voteNoConfidence = Json [json|{ | ||
"vote": "no_confidence" | ||
}|] | ||
rTx1 <- request @(ApiConstructTransaction n) ctx | ||
(Link.createUnsignedTransaction @'Shelley src) Default voteNoConfidence | ||
verify rTx1 | ||
[ expectResponseCode HTTP.status202 | ||
, expectField (#coinSelection . #depositsTaken) (`shouldBe` [depositAmt]) | ||
, expectField (#coinSelection . #depositsReturned) (`shouldBe` []) | ||
] | ||
|
||
let ApiSerialisedTransaction apiTx1 _ = getFromResponse #transaction rTx1 | ||
signedTx1 <- signTx ctx src apiTx1 [ expectResponseCode HTTP.status202 ] | ||
|
||
-- as we are joining for the first time we expect two certificates | ||
let stakeKeyDerPath = NE.fromList | ||
[ ApiT (DerivationIndex 2_147_485_500) | ||
, ApiT (DerivationIndex 2_147_485_463) | ||
, ApiT (DerivationIndex 2_147_483_648) | ||
, ApiT (DerivationIndex 2) | ||
, ApiT (DerivationIndex 0) | ||
] | ||
let registerStakeKeyCert = | ||
WalletDelegationCertificate $ RegisterRewardAccount stakeKeyDerPath | ||
let voting1 = ApiT NoConfidence | ||
let votingCert1 = | ||
WalletDelegationCertificate $ CastVote stakeKeyDerPath voting1 | ||
|
||
let decodePayload1 = Json (toJSON signedTx1) | ||
rDecodedTx1 <- request @(ApiDecodedTransaction n) ctx | ||
(Link.decodeTransaction @'Shelley src) Default decodePayload1 | ||
verify rDecodedTx1 | ||
[ expectResponseCode HTTP.status202 | ||
, expectField #certificates (`shouldBe` [registerStakeKeyCert, votingCert1]) | ||
, expectField #depositsTaken (`shouldBe` [depositAmt]) | ||
, expectField #depositsReturned (`shouldBe` []) | ||
] | ||
|
||
-- Submit tx | ||
submittedTx1 <- submitTxWithWid ctx src signedTx1 | ||
verify submittedTx1 | ||
[ expectSuccess | ||
, expectResponseCode HTTP.status202 | ||
] | ||
|
||
eventually "Wallet has voted and deposit info persists" $ do | ||
rJoin' <- request @(ApiTransaction n) ctx | ||
(Link.getTransaction @'Shelley src | ||
(getResponse submittedTx1)) | ||
Default Empty | ||
verify rJoin' | ||
[ expectResponseCode HTTP.status200 | ||
, expectField (#status . #getApiT) (`shouldBe` InLedger) | ||
, expectField (#direction . #getApiT) (`shouldBe` Outgoing) | ||
, expectField #depositTaken (`shouldBe` depositAmt) | ||
, expectField #depositReturned (`shouldBe` ApiAmount 0) | ||
] | ||
|
||
let txId1 = getFromResponse #id submittedTx1 | ||
let link1 = Link.getTransaction @'Shelley src (ApiTxId txId1) | ||
eventually "Voting transaction is in ledger" $ do | ||
request @(ApiTransaction n) ctx link1 Default Empty | ||
>>= flip verify | ||
[ expectResponseCode HTTP.status200 | ||
, expectField (#direction . #getApiT) (`shouldBe` Outgoing) | ||
, expectField (#status . #getApiT) (`shouldBe` InLedger) | ||
, expectField #metadata (`shouldBe` Nothing) | ||
] | ||
|
||
waitNumberOfEpochBoundaries 2 ctx | ||
|
||
eventually "Wallet is voting no confidence" $ do | ||
getSrcWallet >>= flip verify | ||
[ expectField #delegation (`shouldBe` onlyVoting voting1 []) | ||
] | ||
|
||
let voteAbstain = Json [json|{ | ||
"vote": "abstain" | ||
}|] | ||
rTx2 <- request @(ApiConstructTransaction n) ctx | ||
(Link.createUnsignedTransaction @'Shelley src) Default voteAbstain | ||
verify rTx2 | ||
[ expectResponseCode HTTP.status202 | ||
, expectField (#coinSelection . #depositsTaken) (`shouldBe` []) | ||
, expectField (#coinSelection . #depositsReturned) (`shouldBe` []) | ||
] | ||
|
||
let ApiSerialisedTransaction apiTx2 _ = getFromResponse #transaction rTx2 | ||
signedTx2 <- signTx ctx src apiTx2 [ expectResponseCode HTTP.status202 ] | ||
|
||
let voting2 = ApiT Abstain | ||
let votingCert2 = | ||
WalletDelegationCertificate $ CastVote stakeKeyDerPath voting2 | ||
|
||
let decodePayload2 = Json (toJSON signedTx2) | ||
rDecodedTx2 <- request @(ApiDecodedTransaction n) ctx | ||
(Link.decodeTransaction @'Shelley src) Default decodePayload2 | ||
verify rDecodedTx2 | ||
[ expectResponseCode HTTP.status202 | ||
, expectField #certificates (`shouldBe` [votingCert2]) | ||
, expectField #depositsTaken (`shouldBe` []) | ||
, expectField #depositsReturned (`shouldBe` []) | ||
] | ||
|
||
-- Submit tx | ||
submittedTx2 <- submitTxWithWid ctx src signedTx2 | ||
verify submittedTx2 | ||
[ expectSuccess | ||
, expectResponseCode HTTP.status202 | ||
] | ||
|
||
eventually "Wallet has voted again" $ do | ||
rJoin' <- request @(ApiTransaction n) ctx | ||
(Link.getTransaction @'Shelley src | ||
(getResponse submittedTx2)) | ||
Default Empty | ||
verify rJoin' | ||
[ expectResponseCode HTTP.status200 | ||
, expectField (#status . #getApiT) (`shouldBe` InLedger) | ||
, expectField (#direction . #getApiT) (`shouldBe` Outgoing) | ||
, expectField #depositTaken (`shouldBe` ApiAmount 0) | ||
, expectField #depositReturned (`shouldBe` ApiAmount 0) | ||
] | ||
|
||
let txId2 = getFromResponse #id submittedTx2 | ||
let link2 = Link.getTransaction @'Shelley src (ApiTxId txId2) | ||
eventually "Re-voting transaction is in ledger" $ do | ||
request @(ApiTransaction n) ctx link2 Default Empty | ||
>>= flip verify | ||
[ expectResponseCode HTTP.status200 | ||
, expectField (#direction . #getApiT) (`shouldBe` Outgoing) | ||
, expectField (#status . #getApiT) (`shouldBe` InLedger) | ||
, expectField #metadata (`shouldBe` Nothing) | ||
] | ||
|
||
waitNumberOfEpochBoundaries 2 ctx | ||
|
||
eventually "Wallet is voting abstain" $ do | ||
getSrcWallet >>= flip verify | ||
[ expectField #delegation (`shouldBe` onlyVoting voting2 []) | ||
] |