Skip to content

Commit

Permalink
test: add more test cases to increase test coverage (#179)
Browse files Browse the repository at this point in the history
* docs: update spec docs

* test: add test cases to increase coverage

* test: add more key tests

* test: add more cases in auction keeper

* test: add more cases

* test: add refund paying coin case

* fix: broken test case

* chore: add more test cases and update docs
  • Loading branch information
jaybxyz authored May 2, 2022
1 parent 8fa5853 commit 7524ab7
Show file tree
Hide file tree
Showing 21 changed files with 648 additions and 155 deletions.
8 changes: 4 additions & 4 deletions docs/How-To/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,18 +342,18 @@ Example command:

```bash
# Modify the bid price
fundraisingd tx fundraising modify-bid 1 1 0.45 10000000denom2 \
fundraisingd tx fundraising modify-bid 2 1 0.38 10000000denom2 \
--chain-id fundraising \
--from bob \
--from steve \
--keyring-backend test \
--broadcast-mode block \
--yes \
--output json | jq

# Modify the bid amount
fundraisingd tx fundraising modify-bid 1 2 0.35 25000000denom1 \
fundraisingd tx fundraising modify-bid 2 2 0.4 15000000denom1 \
--chain-id fundraising \
--from bob \
--from steve \
--keyring-backend test \
--broadcast-mode block \
--yes \
Expand Down
2 changes: 1 addition & 1 deletion x/fundraising/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ in our technical spec docs. https://github.com/tendermint/fundraising/blob/main/
return err
}

bidType, err := parseBidType(args[1])
bidType, err := ParseBidType(args[1])
if err != nil {
return fmt.Errorf("parse order direction: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions x/fundraising/client/cli/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ func (req BatchAuctionRequest) String() string {
return string(result)
}

// parseBidType parses bid type string and returns types.BidType.
func parseBidType(s string) (types.BidType, error) {
// ParseBidType parses bid type string and returns types.BidType.
func ParseBidType(s string) (types.BidType, error) {
switch strings.ToLower(s) {
case "fixed-price", "fp", "f":
return types.BidTypeFixedPrice, nil
Expand Down
28 changes: 28 additions & 0 deletions x/fundraising/client/cli/utils_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cli_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -121,3 +122,30 @@ func TestParseBatchAuction(t *testing.T) {
require.Equal(t, sdk.MustNewDecFromStr("0.2"), auction.ExtendedRoundRate)
require.EqualValues(t, expSchedules, auction.VestingSchedules)
}

func TestParseBidType(t *testing.T) {
for _, tc := range []struct {
bidType string
expectedErr error
}{
{"fixed-price", nil},
{"fp", nil},
{"f", nil},
{"batch-worth", nil},
{"bw", nil},
{"w", nil},
{"batch-many", nil},
{"bm", nil},
{"m", nil},
{"fixedprice", fmt.Errorf("invalid bid type: %s", "fixedprice")},
{"batchworth", fmt.Errorf("invalid bid type: %s", "batchworth")},
{"batchmany", fmt.Errorf("invalid bid type: %s", "batchmany")},
} {
_, err := cli.ParseBidType(tc.bidType)
if tc.expectedErr == nil {
require.NoError(t, err)
} else {
require.Error(t, err)
}
}
}
1 change: 1 addition & 0 deletions x/fundraising/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/tendermint/fundraising/x/fundraising/types"
)

// NewHandler returns a new msg handler.
func NewHandler(k keeper.Keeper) sdk.Handler {
msgServer := keeper.NewMsgServerImpl(k)

Expand Down
72 changes: 35 additions & 37 deletions x/fundraising/keeper/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/tendermint/fundraising/x/fundraising/types"
)

// GetNextAuctionIdWithUpdate increments auction id by one and set it.
// GetNextAuctionIdWithUpdate increments auction id by one and store it.
func (k Keeper) GetNextAuctionIdWithUpdate(ctx sdk.Context) uint64 {
id := k.GetLastAuctionId(ctx) + 1
k.SetAuctionId(ctx, id)
Expand Down Expand Up @@ -64,7 +64,7 @@ func (k Keeper) CreateFixedPriceAuction(ctx sdk.Context, msg *types.MsgCreateFix

auction := types.NewFixedPriceAuction(ba, msg.SellingCoin)

// Call the before auction created hook
// Call hook before storing an auction
k.BeforeFixedPriceAuctionCreated(
ctx,
auction.Auctioneer,
Expand Down Expand Up @@ -155,7 +155,7 @@ func (k Keeper) CreateBatchAuction(ctx sdk.Context, msg *types.MsgCreateBatchAuc
msg.ExtendedRoundRate,
)

// Call the before auction created hook
// Call hook before storing an auction
k.BeforeBatchAuctionCreated(
ctx,
auction.Auctioneer,
Expand Down Expand Up @@ -195,7 +195,8 @@ func (k Keeper) CreateBatchAuction(ctx sdk.Context, msg *types.MsgCreateBatchAuc
return auction, nil
}

// CancelAuction cancels the auction. It can only be canceled when the auction has not started yet.
// CancelAuction handles types.MsgCancelAuction and cancels the auction.
// An auction can only be canceled when it is not started yet.
func (k Keeper) CancelAuction(ctx sdk.Context, msg *types.MsgCancelAuction) error {
auction, found := k.GetAuction(ctx, msg.AuctionId)
if !found {
Expand All @@ -220,7 +221,7 @@ func (k Keeper) CancelAuction(ctx sdk.Context, msg *types.MsgCancelAuction) erro
return sdkerrors.Wrap(err, "failed to release the selling coin")
}

// Call the before auction canceled hook
// Call hook before cancelling the auction
k.BeforeAuctionCanceled(ctx, msg.AuctionId, msg.Auctioneer)

if auction.GetType() == types.AuctionTypeFixedPrice {
Expand Down Expand Up @@ -258,19 +259,17 @@ func (k Keeper) AddAllowedBidders(ctx sdk.Context, auctionId uint64, allowedBidd
return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "auction %d is not found", auctionId)
}

// Call the before allowed bidders added hook
// Call hook before adding allowed bidders for the auction
k.BeforeAllowedBiddersAdded(ctx, allowedBidders)

// Store new allowed bidders
for _, ab := range allowedBidders {
if err := ab.Validate(); err != nil {
return err
}

if ab.MaxBidAmount.GT(auction.GetSellingCoin().Amount) {
return types.ErrInsufficientRemainingAmount
}

k.SetAllowedBidder(ctx, auctionId, ab)
}

Expand Down Expand Up @@ -299,7 +298,7 @@ func (k Keeper) UpdateAllowedBidder(ctx sdk.Context, auctionId uint64, bidder sd
return err
}

// Call the before allowed bidders updated hook
// Call hook before updating the allowed bidders for the auction
k.BeforeAllowedBidderUpdated(ctx, auctionId, bidder, maxBidAmount)

k.SetAllowedBidder(ctx, auctionId, allowedBidder)
Expand All @@ -310,7 +309,7 @@ func (k Keeper) UpdateAllowedBidder(ctx sdk.Context, auctionId uint64, bidder sd
// AllocateSellingCoin allocates allocated selling coin for all matched bids in MatchingInfo and
// releases them from the selling reserve account.
func (k Keeper) AllocateSellingCoin(ctx sdk.Context, auction types.AuctionI, mInfo MatchingInfo) error {
// Call the before selling coin distributed hook
// Call hook before selling coin allocation
k.BeforeSellingCoinsAllocated(ctx, auction.GetId(), mInfo.AllocationMap, mInfo.RefundMap)

sellingReserveAddr := auction.GetSellingReserveAddress()
Expand Down Expand Up @@ -349,24 +348,24 @@ func (k Keeper) AllocateSellingCoin(ctx sdk.Context, auction types.AuctionI, mIn

// ReleaseVestingPayingCoin releases the vested selling coin to the auctioneer from the vesting reserve account.
func (k Keeper) ReleaseVestingPayingCoin(ctx sdk.Context, auction types.AuctionI) error {
vqs := k.GetVestingQueuesByAuctionId(ctx, auction.GetId())
vqsLen := len(vqs)
vestingQueues := k.GetVestingQueuesByAuctionId(ctx, auction.GetId())
vestingQueuesLen := len(vestingQueues)

for i, vq := range vqs {
if vq.ShouldRelease(ctx.BlockTime()) {
for i, vestingQueue := range vestingQueues {
if vestingQueue.ShouldRelease(ctx.BlockTime()) {
vestingReserveAddr := auction.GetVestingReserveAddress()
auctioneerAddr := auction.GetAuctioneer()
payingCoins := sdk.NewCoins(vq.PayingCoin)
payingCoins := sdk.NewCoins(vestingQueue.PayingCoin)

if err := k.bankKeeper.SendCoins(ctx, vestingReserveAddr, auctioneerAddr, payingCoins); err != nil {
return sdkerrors.Wrap(err, "failed to release paying coin to the auctioneer")
}

vq.SetReleased(true)
k.SetVestingQueue(ctx, vq)
vestingQueue.SetReleased(true)
k.SetVestingQueue(ctx, vestingQueue)

// Update status to AuctionStatusFinished when all the amounts are released
if i == vqsLen-1 {
// Update status when all the amounts are released
if i == vestingQueuesLen-1 {
_ = auction.SetStatus(types.AuctionStatusFinished)
k.SetAuction(ctx, auction)
}
Expand All @@ -376,8 +375,7 @@ func (k Keeper) ReleaseVestingPayingCoin(ctx sdk.Context, auction types.AuctionI
return nil
}

// RefundRemainingSellingCoin refunds the remaining selling coin back to the auctioneer.
// This function is called right after the selling coin is sold.
// RefundRemainingSellingCoin refunds the remaining selling coin to the auctioneer.
func (k Keeper) RefundRemainingSellingCoin(ctx sdk.Context, auction types.AuctionI) error {
sellingReserveAddr := auction.GetSellingReserveAddress()
sellingCoinDenom := auction.GetSellingCoin().Denom
Expand All @@ -390,7 +388,7 @@ func (k Keeper) RefundRemainingSellingCoin(ctx sdk.Context, auction types.Auctio
return nil
}

// RefundPayingCoin refunds paying coin back to the bidders.
// RefundPayingCoin refunds paying coin to the corresponding bidders.
func (k Keeper) RefundPayingCoin(ctx sdk.Context, auction types.AuctionI, mInfo MatchingInfo) error {
payingReserveAddr := auction.GetPayingReserveAddress()
payingCoinDenom := auction.GetPayingCoinDenom()
Expand Down Expand Up @@ -432,16 +430,15 @@ func (k Keeper) RefundPayingCoin(ctx sdk.Context, auction types.AuctionI, mInfo
// ExtendRound extends another round of ExtendedPeriod value for the auction.
func (k Keeper) ExtendRound(ctx sdk.Context, ba *types.BatchAuction) {
params := k.GetParams(ctx)
extendedPeriod := ctx.BlockTime().AddDate(0, 0, int(params.ExtendedPeriod))

endTimes := ba.GetEndTimes()
endTimes = append(endTimes, extendedPeriod)
extendedPeriod := params.ExtendedPeriod
nextEndTime := ba.GetEndTimes()[len(ba.GetEndTimes())-1].AddDate(0, 0, int(extendedPeriod))
endTimes := append(ba.GetEndTimes(), nextEndTime)

_ = ba.SetEndTimes(endTimes)
k.SetAuction(ctx, ba)
}

// CloseFixedPriceAuction finishes a fixed price auction.
// CloseFixedPriceAuction closes a fixed price auction.
func (k Keeper) CloseFixedPriceAuction(ctx sdk.Context, auction types.AuctionI) {
mInfo := k.CalculateFixedPriceAllocation(ctx, auction)

Expand All @@ -458,13 +455,20 @@ func (k Keeper) CloseFixedPriceAuction(ctx sdk.Context, auction types.AuctionI)
}
}

// CloseBatchAuction finishes a batch auction.
// CloseBatchAuction closes a batch auction.
func (k Keeper) CloseBatchAuction(ctx sdk.Context, auction types.AuctionI) {
ba := auction.(*types.BatchAuction)
ba, ok := auction.(*types.BatchAuction)
if !ok {
panic(fmt.Errorf("unable to close auction that is not a batch auction: %T", auction))
}

if ba.MaxExtendedRound+1 == uint32(len(auction.GetEndTimes())) {
mInfo := k.CalculateBatchAllocation(ctx, auction)
// Extend round since there is no last matched length to compare with
lastMatchedLen := k.GetLastMatchedBidsLen(ctx, ba.GetId())
mInfo := k.CalculateBatchAllocation(ctx, auction)

// Close the auction when maximum extended round + 1 is the same as the length of end times
// If the value of MaxExtendedRound is 0, it means that an auctioneer does not want have an extended round
if ba.MaxExtendedRound+1 == uint32(len(auction.GetEndTimes())) {
if err := k.AllocateSellingCoin(ctx, auction, mInfo); err != nil {
panic(err)
}
Expand All @@ -484,17 +488,11 @@ func (k Keeper) CloseBatchAuction(ctx sdk.Context, auction types.AuctionI) {
return
}

// TODO: what if no matched bids for the auction?
// Extend round since there is no last matched length to compare with
lastMatchedLen := k.GetLastMatchedBidsLen(ctx, ba.GetId())
if lastMatchedLen == 0 {
k.ExtendRound(ctx, ba)
return
}

// TODO: add test case
mInfo := k.CalculateBatchAllocation(ctx, auction)

currDec := sdk.NewDec(mInfo.MatchedLen)
lastDec := sdk.NewDec(lastMatchedLen)
diff := sdk.OneDec().Sub(currDec.Quo(lastDec)) // 1 - (CurrentMatchedLenDec / LastMatchedLenDec)
Expand Down
Loading

0 comments on commit 7524ab7

Please sign in to comment.