Skip to content

Commit

Permalink
Merge branch 'pagu-project:main' into fix/stake-time
Browse files Browse the repository at this point in the history
  • Loading branch information
izikdepth committed May 19, 2024
2 parents 9ace7d7 + bbf17e6 commit 795943b
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 12 deletions.
2 changes: 1 addition & 1 deletion database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (db *DB) AddZealyUser(u *ZealyUser) error {
func (db *DB) UpdateZealyUser(id string, txHash string) error {
tx := db.Model(&ZealyUser{
DiscordID: id,
}).Where("discord_id = ?", id).Update("tx_hash", txHash).Update("is_claimed", true)
}).Where("discord_id = ?", id).Update("tx_hash", txHash)
if tx.Error != nil {
return WriteError{
Reason: tx.Error.Error(),
Expand Down
3 changes: 0 additions & 3 deletions database/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,12 @@ func TestZealyDB(t *testing.T) {
err := db.AddZealyUser(&ZealyUser{
Amount: 100,
DiscordID: "12345678",
IsClaimed: false,
TxHash: "",
})
assert.NoError(t, err)

uz, err := db.GetZealyUser("12345678")
assert.NoError(t, err)
assert.Equal(t, false, uz.IsClaimed)
assert.Equal(t, "", uz.TxHash)
assert.Equal(t, int64(100), uz.Amount)

Expand All @@ -71,7 +69,6 @@ func TestZealyDB(t *testing.T) {

uz, err = db.GetZealyUser("12345678")
assert.NoError(t, err)
assert.Equal(t, true, uz.IsClaimed)
assert.Equal(t, "0x123456789", uz.TxHash)
assert.Equal(t, int64(100), uz.Amount)

Expand Down
5 changes: 4 additions & 1 deletion database/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ type Faucet struct {
type ZealyUser struct {
Amount int64
DiscordID string `gorm:"column:discord_id"`
IsClaimed bool
TxHash string

gorm.Model
}

func (z *ZealyUser) IsClaimed() bool {
return len(z.TxHash) > 0
}
67 changes: 67 additions & 0 deletions engine/command/zealy/import_winners.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package zealy

import (
"encoding/csv"
"fmt"
"os"
"strconv"

"github.com/pagu-project/Pagu/database"
"github.com/pagu-project/Pagu/engine/command"
)

/*
importWinnersHandler gives a csv file with below format and push the data into ZealyUser table.
Position| Discord User | Prize .
1st | user_id_1 | amount .
2nd | user_id_2 | amount .
*/
func (z *Zealy) importWinnersHandler(cmd command.Command, _ command.AppID, _ string, args ...string) command.CommandResult {
if len(args) == 0 {
return cmd.FailedResult("please specify a file path to import")
}

path := args[0]
records, err := readCSV(path)
if err != nil {
return cmd.ErrorResult(fmt.Errorf("csv file is not valid"))
}

totalInserted := 0

for _, record := range records[1:] {
discordID := record[1]
if _, err := z.db.GetZealyUser(discordID); err == nil {
return cmd.ErrorResult(fmt.Errorf("duplicate zealy user with discord ID: %s", discordID))
}

prizeStr := record[2]
prize, _ := strconv.Atoi(prizeStr)
if err := z.db.AddZealyUser(&database.ZealyUser{
Amount: int64(prize),
DiscordID: discordID,
TxHash: "",
}); err != nil {
return cmd.ErrorResult(fmt.Errorf("adding zealy user into db with discord ID: %s", discordID))
}

totalInserted++
}

return cmd.SuccessfulResult("Imported successfully\nTotal inserted: %d", totalInserted)
}

func readCSV(path string) ([][]string, error) {
csvFile, err := os.Open(path)
if err != nil {
return nil, err
}

reader := csv.NewReader(csvFile)
records, err := reader.ReadAll()
if err != nil {
return nil, err
}

return records, nil
}
105 changes: 105 additions & 0 deletions engine/command/zealy/import_winners_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package zealy

import (
"fmt"
"os"
"testing"

"github.com/pagu-project/Pagu/database"
"github.com/pagu-project/Pagu/engine/command"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestImportWinnersHandler(t *testing.T) {
t.Run("import list of winners successfully", func(t *testing.T) {
zealy := setup(t)
tempPath := "temp-csv"
csvData := "Position,Discord ID,Prize\n1,id1,1\n2,id2,2\n3,id3,3"
tempFile := createTempFile(t, tempPath, csvData)

cmd := zealy.GetCommand()
expectedRes := zealy.importWinnersHandler(cmd, command.AppIdCLI, "", tempFile.Name())

assert.Equal(t, true, expectedRes.Successful)
assert.Equal(t, "Imported successfully\nTotal inserted: 3", expectedRes.Message)

users, err := zealy.db.GetAllZealyUser()
assert.Equal(t, nil, err)
for i, u := range users {
assert.Equal(t, "", u.TxHash)
assert.Equal(t, fmt.Sprintf("id%d", i+1), u.DiscordID)
assert.Equal(t, int64(i+1), u.Amount)
}
})

t.Run("import list with duplicate items", func(t *testing.T) {
zealy := setup(t)
tempPath := "temp-csv"
csvData := "Position,Discord ID,Prize\n1,id1,1\n2,id2,2\n3,id3,3\n4,id3,4"
tempFile := createTempFile(t, tempPath, csvData)

cmd := zealy.GetCommand()
expectedRes := zealy.importWinnersHandler(cmd, command.AppIdCLI, "", tempFile.Name())

assert.Equal(t, false, expectedRes.Successful)
assert.Equal(t, "An error occurred: duplicate zealy user with discord ID: id3", expectedRes.Message)

users, err := zealy.db.GetAllZealyUser()
assert.Equal(t, nil, err)
for i, u := range users {
assert.Equal(t, "", u.TxHash)
assert.Equal(t, fmt.Sprintf("id%d", i+1), u.DiscordID)
assert.Equal(t, int64(i+1), u.Amount)
}
})

t.Run("no csv file passed", func(t *testing.T) {
zealy := setup(t)

cmd := zealy.GetCommand()
expectedRes := zealy.importWinnersHandler(cmd, command.AppIdCLI, "")

assert.Equal(t, false, expectedRes.Successful)
assert.Equal(t, "please specify a file path to import", expectedRes.Message)
})

t.Run("wrong csv file passed", func(t *testing.T) {
zealy := setup(t)

cmd := zealy.GetCommand()
expectedRes := zealy.importWinnersHandler(cmd, command.AppIdCLI, "", "fake_csv_file_address")

assert.Equal(t, false, expectedRes.Successful)
assert.Equal(t, "An error occurred: csv file is not valid", expectedRes.Message)
})
}

func setup(t *testing.T) *Zealy {
t.Helper()

dbFile, err := os.CreateTemp("", "temp-db")
require.NoError(t, err)
db, err := database.NewDB(dbFile.Name())
require.NoError(t, err)

zealy := NewZealy(db, nil)
return &zealy
}

func createTempFile(t *testing.T, path, data string) *os.File {
t.Helper()

tempFile, err := os.CreateTemp("", path)
if err != nil {
t.Fatalf("createTempFile() error = %v", err)
}

defer tempFile.Close()

if _, err := tempFile.Write([]byte(data)); err != nil {
t.Fatalf("createTempFile() error writing data to temp file: %v", err)
}

return tempFile
}
33 changes: 26 additions & 7 deletions engine/command/zealy/zealy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
)

const (
CommandName = "zealy"
ClaimCommandName = "claim"
StatusCommandName = "status"
HelpCommandName = "help"
CommandName = "zealy"
ClaimCommandName = "claim"
StatusCommandName = "status"
ImportWinnersCommandName = "import-winners"
HelpCommandName = "help"
)

type Zealy struct {
Expand Down Expand Up @@ -67,6 +68,24 @@ func (z *Zealy) GetCommand() command.Command {
cmdZealy.AddSubCommand(subCmdClaim)
cmdZealy.AddSubCommand(subCmdStatus)

// only accessible from cli
subCmdImportWinners := command.Command{
Name: ImportWinnersCommandName,
Desc: "Import Zealy winners using csv file",
Help: "",
Args: []command.Args{
{
Name: "path",
Desc: "CSV file path",
Optional: false,
},
},
SubCommands: nil,
AppIDs: []command.AppID{command.AppIdCLI},
Handler: z.importWinnersHandler,
}

cmdZealy.AddSubCommand(subCmdImportWinners)
return cmdZealy
}

Expand All @@ -76,13 +95,13 @@ func (z *Zealy) claimHandler(cmd command.Command, _ command.AppID, callerID stri
return cmd.ErrorResult(err)
}

if user.IsClaimed {
if user.IsClaimed() {
return cmd.FailedResult("You already claimed your reward: https://pacviewer.com/transaction/%s",
user.TxHash)
}

address := args[0]
txHash, err := z.wallet.TransferTransaction(address, "Pagu Zealy reward distribution", int64(user.Amount))
txHash, err := z.wallet.TransferTransaction(address, "PaGu Zealy reward distribution", int64(user.Amount))
if err != nil {
return cmd.ErrorResult(err)
}
Expand Down Expand Up @@ -113,7 +132,7 @@ func (z *Zealy) statusHandler(cmd command.Command, _ command.AppID, _ string, ar
total++
totalAmount += int(u.Amount)

if u.IsClaimed {
if u.IsClaimed() {
totalClaimed++
totalClaimedAmount += int(u.Amount)
} else {
Expand Down

0 comments on commit 795943b

Please sign in to comment.