refactor tests of the effect

* test both the effect and governor in the spec
* test that the effect and governor will fail when try setting the
  governor state to a invalid one
This commit is contained in:
fanghr 2022-05-19 20:12:24 +08:00
parent fc050527a1
commit ad33b0cbbc
3 changed files with 125 additions and 63 deletions

View file

@ -1,9 +1,14 @@
module Sample.Effect.GovernorMutation ( module Sample.Effect.GovernorMutation (
validContext, mkEffectTransaction,
effectValidator, effectValidator,
effectValidatorAddress, effectValidatorAddress,
effectValidatorHash, effectValidatorHash,
atAssetClass, atAssetClass,
govRef,
effectRef,
invalidNewGovernorDatum,
validNewGovernorDatum,
mkEffectDatum,
) where ) where
import Agora.Effect.GovernorMutation ( import Agora.Effect.GovernorMutation (
@ -11,14 +16,13 @@ import Agora.Effect.GovernorMutation (
mutateGovernorValidator, mutateGovernorValidator,
) )
import Agora.Governor (GovernorDatum (..)) import Agora.Governor (GovernorDatum (..))
import Agora.Proposal (ProposalId (..)) import Agora.Proposal (ProposalId (..), ProposalThresholds (..))
import Plutarch.Api.V1 (mkValidator, validatorHash) import Plutarch.Api.V1 (mkValidator, validatorHash)
import Plutarch.SafeMoney (Tagged (Tagged))
import Plutus.V1.Ledger.Address (scriptHashAddress) import Plutus.V1.Ledger.Address (scriptHashAddress)
import Plutus.V1.Ledger.Api ( import Plutus.V1.Ledger.Api (
Address, Address,
Datum (..), Datum (..),
ScriptContext (..),
ScriptPurpose (Spending),
ToData (..), ToData (..),
TokenName (..), TokenName (..),
TxInInfo (..), TxInInfo (..),
@ -42,15 +46,19 @@ import Sample.Shared (
) )
import Test.Util (datumPair, toDatumHash) import Test.Util (datumPair, toDatumHash)
-- | The effect validator instance.
effectValidator :: Validator effectValidator :: Validator
effectValidator = mkValidator $ mutateGovernorValidator governor effectValidator = mkValidator $ mutateGovernorValidator governor
-- | The hash of the validator instance.
effectValidatorHash :: ValidatorHash effectValidatorHash :: ValidatorHash
effectValidatorHash = validatorHash effectValidator effectValidatorHash = validatorHash effectValidator
-- | The address of the validator.
effectValidatorAddress :: Address effectValidatorAddress :: Address
effectValidatorAddress = scriptHashAddress effectValidatorHash effectValidatorAddress = scriptHashAddress effectValidatorHash
-- | The assetclass of the authority token.
atAssetClass :: AssetClass atAssetClass :: AssetClass
atAssetClass = assetClass authorityTokenSymbol tokenName atAssetClass = assetClass authorityTokenSymbol tokenName
where where
@ -58,20 +66,36 @@ atAssetClass = assetClass authorityTokenSymbol tokenName
ValidatorHash bs = effectValidatorHash ValidatorHash bs = effectValidatorHash
tokenName = TokenName bs tokenName = TokenName bs
validContext :: ScriptContext -- | The mock reference of the governor state UTXO.
validContext = govRef :: TxOutRef
govRef = TxOutRef "614481d2159bfb72350222d61fce17e548e0fc00e5a1f841ff1837c431346ce7" 1
-- | The mock reference of the effect UTXO.
effectRef :: TxOutRef
effectRef = TxOutRef "c31164dc11835de7eb6187f67d0e1a19c1dfc0786a456923eef5043189cdb578" 1
-- | The input effect datum in 'mkEffectTransaction'.
mkEffectDatum :: GovernorDatum -> MutateGovernorDatum
mkEffectDatum newGovDatum =
MutateGovernorDatum
{ governorRef = govRef
, newDatum = newGovDatum
}
{- | Given the new governor state, create an effect to update the governor's state.
Note that the transaction is valid only if the given new datum is valid.
-}
mkEffectTransaction :: GovernorDatum -> TxInfo
mkEffectTransaction newGovDatum =
let gst = Value.assetClassValue govAssetClass 1 let gst = Value.assetClassValue govAssetClass 1
at = Value.assetClassValue atAssetClass 1 at = Value.assetClassValue atAssetClass 1
-- One authority token is burnt in the process.
burnt = Value.assetClassValue atAssetClass (-1) burnt = Value.assetClassValue atAssetClass (-1)
-- --
governorInputRef :: TxOutRef
governorInputRef = TxOutRef "614481d2159bfb72350222d61fce17e548e0fc00e5a1f841ff1837c431346ce7" 1
--
governorInputDatum' :: GovernorDatum governorInputDatum' :: GovernorDatum
governorInputDatum' = governorInputDatum' =
GovernorDatum GovernorDatum
@ -92,21 +116,14 @@ validContext =
-- The effect should update 'nextProposalId' -- The effect should update 'nextProposalId'
effectInputDatum' :: MutateGovernorDatum effectInputDatum' :: MutateGovernorDatum
effectInputDatum' = effectInputDatum' = mkEffectDatum newGovDatum
MutateGovernorDatum
{ governorRef = governorInputRef
, newDatum =
governorInputDatum'
{ nextProposalId = ProposalId 42
}
}
effectInputDatum :: Datum effectInputDatum :: Datum
effectInputDatum = Datum $ toBuiltinData effectInputDatum' effectInputDatum = Datum $ toBuiltinData effectInputDatum'
effectInput :: TxOut effectInput :: TxOut
effectInput = effectInput =
TxOut TxOut
{ txOutAddress = effectValidatorAddress { txOutAddress = effectValidatorAddress
, txOutValue = at , txOutValue = at -- The effect carry an authotity token.
, txOutDatumHash = Just $ toDatumHash effectInputDatum , txOutDatumHash = Just $ toDatumHash effectInputDatum
} }
@ -123,27 +140,35 @@ validContext =
, txOutValue = mconcat [gst, minAda] , txOutValue = mconcat [gst, minAda]
, txOutDatumHash = Just $ toDatumHash governorOutputDatum , txOutDatumHash = Just $ toDatumHash governorOutputDatum
} }
in TxInfo
-- { txInfoInputs =
[ TxInInfo effectRef effectInput
ownInputRef :: TxOutRef , TxInInfo govRef governorInput
ownInputRef = TxOutRef "c31164dc11835de7eb6187f67d0e1a19c1dfc0786a456923eef5043189cdb578" 1 ]
in ScriptContext , txInfoOutputs = [governorOutput]
{ scriptContextPurpose = Spending ownInputRef , txInfoFee = Value.singleton "" "" 2
, scriptContextTxInfo = , txInfoMint = burnt
TxInfo , txInfoDCert = []
{ txInfoInputs = , txInfoWdrl = []
[ TxInInfo ownInputRef effectInput , txInfoValidRange = Interval.always
, TxInInfo governorInputRef governorInput , txInfoSignatories = [signer]
] , txInfoData = datumPair <$> [governorInputDatum, governorOutputDatum, effectInputDatum]
, txInfoOutputs = [governorOutput] , txInfoId = "4dae3806cc69615b721d52ed09b758f43f25a8f39b7934d6b28514caf71f5f7b"
, txInfoFee = Value.singleton "" "" 2
, txInfoMint = burnt
, txInfoDCert = []
, txInfoWdrl = []
, txInfoValidRange = Interval.always
, txInfoSignatories = [signer]
, txInfoData = datumPair <$> [governorInputDatum, governorOutputDatum, effectInputDatum]
, txInfoId = "4dae3806cc69615b721d52ed09b758f43f25a8f39b7934d6b28514caf71f5f7b"
}
} }
validNewGovernorDatum :: GovernorDatum
validNewGovernorDatum =
GovernorDatum
{ proposalThresholds = defaultProposalThresholds
, nextProposalId = ProposalId 42
}
invalidNewGovernorDatum :: GovernorDatum
invalidNewGovernorDatum =
GovernorDatum
{ proposalThresholds =
defaultProposalThresholds
{ countVoting = Tagged (-1)
}
, nextProposalId = ProposalId 42
}

View file

@ -502,7 +502,7 @@ mintGATs =
The effect script should carry an valid tagged authority token, The effect script should carry an valid tagged authority token,
and said token will be burnt in the transaction. We use 'noOpValidator' and said token will be burnt in the transaction. We use 'noOpValidator'
here as a mock effect, so no actual change is done to the governor state. here as a mock effect, so no actual change is done to the governor state.
TODO: use 'mutateGovernorEffect' as the mock effect in the future. TODO: use 'Agora.Effect.GovernorMutation.mutateGovernorEffect' as the mock effect in the future.
The governor will ensure the new governor state is valid. The governor will ensure the new governor state is valid.
-} -}

View file

@ -1,30 +1,67 @@
module Spec.Effect.GovernorMutation (tests) where module Spec.Effect.GovernorMutation (tests) where
import Agora.Effect.GovernorMutation (MutateGovernorDatum (..), mutateGovernorValidator) import Agora.Effect.GovernorMutation (mutateGovernorValidator)
import Agora.Governor (GovernorDatum (..)) import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor))
import Agora.Governor.Scripts (governorValidator)
import Agora.Proposal (ProposalId (..)) import Agora.Proposal (ProposalId (..))
import Plutus.V1.Ledger.Api (TxOutRef (..)) import Plutus.V1.Ledger.Api (ScriptContext (ScriptContext), ScriptPurpose (Spending))
import Sample.Effect.GovernorMutation (validContext) import Sample.Effect.GovernorMutation (
import Sample.Shared (defaultProposalThresholds, governor) effectRef,
govRef,
invalidNewGovernorDatum,
mkEffectDatum,
mkEffectTransaction,
validNewGovernorDatum,
)
import Sample.Shared qualified as Shared
import Test.Tasty (TestTree, testGroup) import Test.Tasty (TestTree, testGroup)
import Test.Util (effectSucceedsWith) import Test.Util (effectFailsWith, effectSucceedsWith, validatorFailsWith, validatorSucceedsWith)
tests :: [TestTree] tests :: [TestTree]
tests = tests =
[ testGroup [ testGroup
"validator" "validator"
[ effectSucceedsWith [ testGroup
"Simple" "valid new governor datum"
(mutateGovernorValidator governor) [ validatorSucceedsWith
( MutateGovernorDatum "governor"
{ governorRef = TxOutRef "614481d2159bfb72350222d61fce17e548e0fc00e5a1f841ff1837c431346ce7" 1 (governorValidator Shared.governor)
, newDatum = ( GovernorDatum
GovernorDatum { proposalThresholds = Shared.defaultProposalThresholds
{ nextProposalId = ProposalId 42 , nextProposalId = ProposalId 0
, proposalThresholds = defaultProposalThresholds }
} )
} MutateGovernor
) ( ScriptContext
validContext (mkEffectTransaction validNewGovernorDatum)
(Spending govRef)
)
, effectSucceedsWith
"effect"
(mutateGovernorValidator Shared.governor)
(mkEffectDatum validNewGovernorDatum)
(ScriptContext (mkEffectTransaction validNewGovernorDatum) (Spending effectRef))
]
, testGroup
"invalid new governor datum"
[ validatorFailsWith
"governor"
(governorValidator Shared.governor)
( GovernorDatum
{ proposalThresholds = Shared.defaultProposalThresholds
, nextProposalId = ProposalId 0
}
)
MutateGovernor
( ScriptContext
(mkEffectTransaction invalidNewGovernorDatum)
(Spending govRef)
)
, effectFailsWith
"effect"
(mutateGovernorValidator Shared.governor)
(mkEffectDatum validNewGovernorDatum)
(ScriptContext (mkEffectTransaction invalidNewGovernorDatum) (Spending effectRef))
]
] ]
] ]