agora/agora-specs/Spec/Proposal.hs
Hongrui Fang 9dfb73550a
fix tests
2022-11-25 18:42:39 +08:00

461 lines
19 KiB
Haskell

{- |
Module : Spec.Proposal
Maintainer : emi@haskell.fyi
Description: Tests for Proposal policy and validator
Tests for Proposal policy and validator
-}
module Spec.Proposal (specs) where
import Sample.Proposal.Advance qualified as Advance
import Sample.Proposal.Cosign qualified as Cosign
import Sample.Proposal.Create qualified as Create
import Sample.Proposal.PrivilegeEscalate qualified as PrivilegeEscalate
import Sample.Proposal.Unlock qualified as Unlock
import Sample.Proposal.Vote qualified as Vote
import Test.Specification (
SpecificationTree,
group,
)
-- | Stake specs.
specs :: [SpecificationTree]
specs =
[ group
"policy (proposal creation)"
[ Create.mkTestTree
"legal"
Create.totallyValidParameters
True
True
True
, group
"illegal"
[ Create.mkTestTree
"invalid next proposal id"
Create.invalidOutputGovernorDatumParameters
True
False
True
, Create.mkTestTree
"use other's stake"
Create.useStakeOwnBySomeoneElseParameters
True
True
False
, Create.mkTestTree
"altered stake"
Create.invalidOutputStakeParameters
True
False
False
, Create.mkTestTree
"invalid stake locks"
Create.addInvalidLocksParameters
True
True
False
, Create.mkTestTree
"has reached maximum proposals limit"
Create.exceedMaximumProposalsParameters
True
False
True
, Create.mkTestTree
"loose time range"
Create.timeRangeNotTightParameters
True
False
True
, Create.mkTestTree
"open time range"
Create.timeRangeNotClosedParameters
True
False
True
, group "invalid proposal status" $
map
( \ps ->
Create.mkTestTree
(show ps.proposalStatus)
ps
True
False
True
)
Create.invalidProposalStatusParameters
, Create.mkTestTree
"fake SST"
Create.fakeSSTParameters
True
False
False
, Create.mkTestTree
"wrong governor redeemer"
Create.wrongGovernorRedeemer
False
False
True
, Create.mkTestTree
"wrong governor redeemer"
Create.wrongGovernorRedeemer1
False
False
True
]
]
, group
"validator"
[ group
"cosignature"
[ Cosign.mkTestTree
"legal"
Cosign.totallyValid
(Cosign.Validity True True)
, group
"illegal"
[ Cosign.mkTestTree
"insufficient staked amount"
Cosign.insufficientStakedAmount
(Cosign.Validity False True)
, Cosign.mkTestTree
"proposal locks not updated"
Cosign.locksNotUpdated
(Cosign.Validity True False)
, Cosign.mkTestTree
"duplicate cosigners"
Cosign.duplicateCosigners
(Cosign.Validity False True)
, Cosign.mkTestTree
"cosigners not updated"
Cosign.cosignersNotUpdated
(Cosign.Validity False True)
, group "cosign after draft" $
map
( \b ->
Cosign.mkTestTree
"(negative test)"
b
(Cosign.Validity False True)
)
Cosign.cosignAfterDraft
]
]
, group
"voting"
[ group
"legal"
[ group "different number of stakes" $
map
( \s ->
group
(unwords [show s, "stakes"])
[ Vote.mkTestTree
"by owner"
(Vote.mkValidOwnerVoteBundle s)
(Vote.Validity True True)
, Vote.mkTestTree
"by delegatee"
(Vote.mkValidDelegateeVoteBundle s)
(Vote.Validity True True)
]
)
[1, 3, 5, 7, 9]
, Vote.mkTestTree
"transparent non-GT tokens"
Vote.transparentAssets
(Vote.Validity True True)
, Vote.mkTestTree
"Delegatee vote with own and delegated stakes in one tx"
Vote.delegateeVoteWithOwnAndDelegatedStakeBundle
(Vote.Validity True True)
]
, group
"illegal"
[ Vote.mkTestTree
"vote for nonexistent outcome"
Vote.voteForNonexistentOutcome
(Vote.Validity False True)
, Vote.mkTestTree
"unauthorized tx"
Vote.transactionNotAuthorized
(Vote.Validity True False)
, Vote.mkTestTree
"no proposal"
Vote.noProposal
(Vote.Validity False False)
, Vote.mkTestTree
"more than one proposals"
Vote.voteForNonexistentOutcome
(Vote.Validity False True)
, Vote.mkTestTree
"locks not added"
Vote.invalidLocks
(Vote.Validity True False)
, Vote.mkTestTree
"attempt to burn stakes"
Vote.destroyStakes
(Vote.Validity True False)
, Vote.mkTestTree
"insufficient staked amount"
Vote.insufficientAmount
(Vote.Validity False True)
, Vote.mkTestTree
"insufficient staked amount"
Vote.insufficientAmount1
(Vote.Validity False True)
]
]
, group
"advancing"
$ let possibleCosigners = [1, 5, 10]
possibleEffects = [1, 2, 5]
in do
cs <- possibleCosigners
es <- possibleEffects
let groupName =
unwords
[ "with"
, show cs
, "cosigners"
, "and"
, show es
, "effects"
]
pure $
group
groupName
[ group
"legal"
$ let allValid =
Advance.Validity
{ forProposalValidator = True
, forStakeValidator = True
, forGovernorValidator = Just True
, forAuthorityTokenPolicy = Just True
}
mkName b =
unwords
[ "from"
, show b.proposalParameters.fromStatus
, "to"
, show b.proposalParameters.toStatus
]
in [ Advance.mkTestTree'
"to next state"
mkName
(Advance.mkValidToNextStateBundles cs es)
allValid
, Advance.mkTestTree'
"to failed state"
mkName
(Advance.mkValidToFailedStateBundles cs es)
allValid
]
, group
"illegal"
[ Advance.mkTestTree'
"advance finished proposals"
(const "(negative test)")
(Advance.mkFromFinishedBundles cs es)
Advance.Validity
{ forProposalValidator = False
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Just True
}
, Advance.mkTestTree
"insufficient cosigns"
(Advance.mkInsufficientCosignsBundle cs es)
Advance.Validity
{ forProposalValidator = False
, forStakeValidator = True
, forGovernorValidator = Nothing
, forAuthorityTokenPolicy = Nothing
}
, Advance.mkTestTree
"insufficient votes"
(Advance.mkInsufficientVotesBundle cs es)
Advance.Validity
{ forProposalValidator = False
, forStakeValidator = True
, forGovernorValidator = Nothing
, forAuthorityTokenPolicy = Nothing
}
, Advance.mkTestTree
"ambiguous winning effect"
(Advance.mkAmbiguousWinnerBundle cs es)
Advance.Validity
{ forProposalValidator = False
, forStakeValidator = True
, forGovernorValidator = Nothing
, forAuthorityTokenPolicy = Nothing
}
, Advance.mkTestTree'
"to next state too late"
(\b -> unwords ["from", show b.proposalParameters.fromStatus])
(Advance.mkToNextStateTooLateBundles cs es)
Advance.Validity
{ forProposalValidator = False
, forStakeValidator = True
, forGovernorValidator = Just True
, forAuthorityTokenPolicy = Just True
}
, Advance.mkTestTree
"forget to mint GATs"
(Advance.mkNoGATMintedBundle cs es)
Advance.Validity
{ forProposalValidator = True
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Nothing
}
, Advance.mkTestTree
"mint GATs for wrong validators"
(Advance.mkMintGATsForWrongEffectsBundle cs es)
Advance.Validity
{ forProposalValidator = True
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Just True
}
, Advance.mkTestTree
"mint GATs with bad token name"
(Advance.mkMintGATsWithoutTagBundle cs es)
Advance.Validity
{ forProposalValidator = True
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Just True
}
, Advance.mkTestTree
"wrong GAT datum"
(Advance.mkGATsWithWrongDatumBundle cs es)
Advance.Validity
{ forProposalValidator = True
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Just True
}
, Advance.mkTestTree
"invalid governor output datum"
(Advance.mkBadGovernorOutputDatumBundle cs es)
Advance.Validity
{ forProposalValidator = True
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Just True
}
, Advance.mkTestTree'
"fastforward to finished"
(\b -> unwords ["from", show b.proposalParameters.fromStatus])
(Advance.mkFastforwardToFinishBundles cs es)
Advance.Validity
{ forProposalValidator = False
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Just True
}
, Advance.mkTestTree
"wrong governor redeemer"
(Advance.mkBadGovernorRedeemerBundle cs es)
Advance.Validity
{ forProposalValidator = True
, forStakeValidator = True
, forGovernorValidator = Just False
, forAuthorityTokenPolicy = Just False
}
]
]
, group "unlocking" $
let stakeCountCases = [1, 3, 5, 7, 9, 11]
mkSubgroupName nStakes = unwords ["with", show nStakes, "stakes"]
mkLegalGroup nStakes =
group
(mkSubgroupName nStakes)
[ Unlock.mkTestTree
"voter: retract votes while voting"
(Unlock.mkValidVoterRetractVotes nStakes)
(Unlock.Validity True True)
, Unlock.mkTestTree
"voter: retract votes while voting by delegatee"
(Unlock.mkValidDelegateeRetractVotes nStakes)
(Unlock.Validity True True)
, Unlock.mkTestTree
"voter/creator: retract votes while voting"
(Unlock.mkValidVoterCreatorRetractVotes nStakes)
(Unlock.Validity True True)
, Unlock.mkTestTree
"creator: remove creator lock after voting"
(Unlock.mkValidCreatorRemoveLock nStakes)
(Unlock.Validity True True)
, Unlock.mkTestTree
"Voter: remove lock after voting"
(Unlock.mkValidVoterRemoveLockAfterVoting nStakes)
(Unlock.Validity True True)
]
mkIllegalGroup nStakes =
group
(mkSubgroupName nStakes)
[ group "retract votes while not voting" $
map
( \c ->
Unlock.mkTestTree
"(negative test)"
c
(Unlock.Validity False True)
)
(Unlock.mkRetractVotesWhileNotVoting nStakes)
, group "remove creator too early" $
map
( \c ->
Unlock.mkTestTree
"(negative test)"
c
(Unlock.Validity True False)
)
(Unlock.mkRemoveCreatorLockBeforeFinished nStakes)
, Unlock.mkTestTree
"unlock an irrelevant stake"
(Unlock.mkUnockIrrelevantStakes nStakes)
(Unlock.Validity False False)
, Unlock.mkTestTree
"creator: retract votes"
(Unlock.mkCreatorRetractVotes nStakes)
(Unlock.Validity False True)
, Unlock.mkTestTree
"change output stake value"
(Unlock.mkChangeOutputStakeValue nStakes)
(Unlock.Validity True False)
, Unlock.mkTestTree
"use fake stake"
(Unlock.mkUseFakeStakes nStakes)
(Unlock.Validity False False)
, Unlock.mkTestTree
"retract votes in cooldown"
(Unlock.mkDisrespectCooldown nStakes)
(Unlock.Validity True False)
]
legalGroup = group "legal" $ map mkLegalGroup stakeCountCases
illegalGroup = group "illegal" $ map mkIllegalGroup stakeCountCases
in [legalGroup, illegalGroup]
]
, group
"privilege escalate"
[ PrivilegeEscalate.mkTestTree
"vote"
PrivilegeEscalate.Voting
(PrivilegeEscalate.Validity False False)
, PrivilegeEscalate.mkTestTree
"retract votes"
PrivilegeEscalate.RetractingVotes
(PrivilegeEscalate.Validity False False)
]
]