Skip to content

Commit 90b297d

Browse files
committed
test cases
1 parent babd157 commit 90b297d

57 files changed

Lines changed: 12752 additions & 1375 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ scripts/build/pchaind
66
.coverage/
77
coverage.out
88
coverage.html
9+
*.out

cmd/push-validator/cmd_backup.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@ import (
44
"fmt"
55

66
"github.com/pushchain/push-validator-cli/internal/admin"
7-
"github.com/pushchain/push-validator-cli/internal/config"
87
)
98

109
// handleBackup creates a backup archive of the node configuration and
1110
// prints the resulting path, or a JSON object when --output=json.
12-
func handleBackup(cfg config.Config) error {
13-
path, err := admin.Backup(admin.BackupOptions{HomeDir: cfg.HomeDir})
11+
func handleBackup(d *Deps) error {
12+
path, err := admin.Backup(admin.BackupOptions{HomeDir: d.Cfg.HomeDir})
1413
if err != nil {
15-
if flagOutput == "json" { getPrinter().JSON(map[string]any{"ok": false, "error": err.Error()}) } else { getPrinter().Error(fmt.Sprintf("backup error: %v", err)) }
14+
if flagOutput == "json" { d.Printer.JSON(map[string]any{"ok": false, "error": err.Error()}) } else { d.Printer.Error(fmt.Sprintf("backup error: %v", err)) }
1615
return err
1716
}
18-
if flagOutput == "json" { getPrinter().JSON(map[string]any{"ok": true, "backup_path": path}) } else { getPrinter().Success(fmt.Sprintf("backup created: %s", path)) }
17+
if flagOutput == "json" { d.Printer.JSON(map[string]any{"ok": true, "backup_path": path}) } else { d.Printer.Success(fmt.Sprintf("backup created: %s", path)) }
1918
return nil
2019
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestHandleBackup_Success(t *testing.T) {
8+
origOutput := flagOutput
9+
defer func() { flagOutput = origOutput }()
10+
flagOutput = "text"
11+
12+
// handleBackup calls admin.Backup which needs a real HomeDir
13+
// with specific structure. We test the error path here.
14+
d := &Deps{
15+
Cfg: testCfg(),
16+
Printer: getPrinter(),
17+
}
18+
19+
// This will likely return an error since /tmp/test-pchain doesn't exist
20+
// but we're testing that the function doesn't panic and handles errors
21+
err := handleBackup(d)
22+
if err == nil {
23+
// If it somehow succeeds (e.g., the dir exists), that's fine
24+
return
25+
}
26+
// Error is expected since the test home dir doesn't have proper structure
27+
}
28+
29+
func TestHandleBackup_Error_JSON(t *testing.T) {
30+
origOutput := flagOutput
31+
flagOutput = "json"
32+
defer func() { flagOutput = origOutput }()
33+
34+
d := &Deps{
35+
Cfg: testCfg(),
36+
Printer: getPrinter(),
37+
}
38+
39+
// Test JSON error path
40+
err := handleBackup(d)
41+
if err == nil {
42+
return // If backup succeeds in test env, that's OK
43+
}
44+
// We're testing that JSON error output doesn't panic
45+
}
46+
47+
func TestHandleBackup_RealTempDir(t *testing.T) {
48+
origOutput := flagOutput
49+
defer func() { flagOutput = origOutput }()
50+
flagOutput = "text"
51+
52+
dir := t.TempDir()
53+
cfg := testCfg()
54+
cfg.HomeDir = dir
55+
56+
d := &Deps{
57+
Cfg: cfg,
58+
Printer: getPrinter(),
59+
}
60+
61+
// admin.Backup will try to create a tar.gz of the config dir
62+
// It may fail because there's no config dir, but shouldn't panic
63+
_ = handleBackup(d)
64+
}
65+
66+
func TestHandleBackup_Success_JSON(t *testing.T) {
67+
origOutput := flagOutput
68+
defer func() { flagOutput = origOutput }()
69+
flagOutput = "json"
70+
71+
dir := t.TempDir()
72+
cfg := testCfg()
73+
cfg.HomeDir = dir
74+
75+
d := &Deps{
76+
Cfg: cfg,
77+
Printer: getPrinter(),
78+
}
79+
80+
// This should succeed since HomeDir exists and backup dir is auto-created
81+
err := handleBackup(d)
82+
if err != nil {
83+
t.Fatalf("unexpected error: %v", err)
84+
}
85+
}
86+
87+
func TestHandleBackup_Success_Text(t *testing.T) {
88+
origOutput := flagOutput
89+
origNoColor := flagNoColor
90+
origNoEmoji := flagNoEmoji
91+
defer func() {
92+
flagOutput = origOutput
93+
flagNoColor = origNoColor
94+
flagNoEmoji = origNoEmoji
95+
}()
96+
flagOutput = "text"
97+
flagNoColor = true
98+
flagNoEmoji = true
99+
100+
dir := t.TempDir()
101+
cfg := testCfg()
102+
cfg.HomeDir = dir
103+
104+
d := &Deps{
105+
Cfg: cfg,
106+
Printer: getPrinter(),
107+
}
108+
109+
err := handleBackup(d)
110+
if err != nil {
111+
t.Fatalf("unexpected error: %v", err)
112+
}
113+
}

cmd/push-validator/cmd_balance.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,29 @@ import (
44
"context"
55
"fmt"
66
"os"
7-
"os/exec"
87
"strings"
98
"time"
109

11-
"github.com/pushchain/push-validator-cli/internal/config"
1210
"github.com/pushchain/push-validator-cli/internal/dashboard"
13-
"github.com/pushchain/push-validator-cli/internal/validator"
1411
)
1512

1613
// handleBalance prints an account balance. It resolves the address from
1714
// either a positional argument or KEY_NAME when --address/arg is omitted.
1815
// When --output=json is set, it emits a structured object.
19-
func handleBalance(cfg config.Config, args []string) error {
16+
func handleBalance(d *Deps, args []string) error {
2017
var addr string
2118
if len(args) > 0 { addr = args[0] }
2219
if addr == "" {
2320
key := os.Getenv("KEY_NAME")
2421
if key == "" {
25-
if flagOutput == "json" { getPrinter().JSON(map[string]any{"ok": false, "error": "address not provided; set KEY_NAME or pass --address"}) } else { fmt.Println("usage: push-validator balance <address> (or set KEY_NAME)") }
22+
if flagOutput == "json" { d.Printer.JSON(map[string]any{"ok": false, "error": "address not provided; set KEY_NAME or pass --address"}) } else { fmt.Println("usage: push-validator balance <address> (or set KEY_NAME)") }
2623
return fmt.Errorf("address not provided")
2724
}
28-
out, err := exec.Command(findPchaind(), "keys", "show", key, "-a", "--keyring-backend", cfg.KeyringBackend, "--home", cfg.HomeDir).Output()
25+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
26+
out, err := d.Runner.Run(ctx, findPchaind(), "keys", "show", key, "-a", "--keyring-backend", d.Cfg.KeyringBackend, "--home", d.Cfg.HomeDir)
27+
cancel()
2928
if err != nil {
30-
if flagOutput == "json" { getPrinter().JSON(map[string]any{"ok": false, "error": err.Error()}) } else { fmt.Printf("resolve address error: %v\n", err) }
29+
if flagOutput == "json" { d.Printer.JSON(map[string]any{"ok": false, "error": err.Error()}) } else { fmt.Printf("resolve address error: %v\n", err) }
3130
return fmt.Errorf("resolve address: %w", err)
3231
}
3332
addr = strings.TrimSpace(string(out))
@@ -36,23 +35,22 @@ func handleBalance(cfg config.Config, args []string) error {
3635
// Convert hex address (0x...) to bech32 if needed
3736
if strings.HasPrefix(addr, "0x") || strings.HasPrefix(addr, "0X") {
3837
convCtx, convCancel := context.WithTimeout(context.Background(), 10*time.Second)
39-
bech32Addr, convErr := hexToBech32Address(convCtx, addr)
38+
bech32Addr, convErr := hexToBech32Address(convCtx, addr, d.Runner)
4039
convCancel()
4140
if convErr != nil {
42-
if flagOutput == "json" { getPrinter().JSON(map[string]any{"ok": false, "error": convErr.Error(), "address": addr}) } else { getPrinter().Error(fmt.Sprintf("address conversion error: %v", convErr)) }
41+
if flagOutput == "json" { d.Printer.JSON(map[string]any{"ok": false, "error": convErr.Error(), "address": addr}) } else { d.Printer.Error(fmt.Sprintf("address conversion error: %v", convErr)) }
4342
return convErr
4443
}
4544
addr = bech32Addr
4645
}
4746

48-
v := validator.NewWith(validator.Options{BinPath: findPchaind(), HomeDir: cfg.HomeDir, ChainID: cfg.ChainID, Keyring: cfg.KeyringBackend, GenesisDomain: cfg.GenesisDomain, Denom: cfg.Denom})
4947
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
5048
defer cancel()
51-
bal, err := v.Balance(ctx, addr)
49+
bal, err := d.Validator.Balance(ctx, addr)
5250
if err != nil {
53-
if flagOutput == "json" { getPrinter().JSON(map[string]any{"ok": false, "error": err.Error(), "address": addr}) } else { getPrinter().Error(fmt.Sprintf("balance error: %v", err)) }
51+
if flagOutput == "json" { d.Printer.JSON(map[string]any{"ok": false, "error": err.Error(), "address": addr}) } else { d.Printer.Error(fmt.Sprintf("balance error: %v", err)) }
5452
return err
5553
}
56-
if flagOutput == "json" { getPrinter().JSON(map[string]any{"ok": true, "address": addr, "balance": bal, "denom": cfg.Denom}) } else { getPrinter().Info(fmt.Sprintf("%s %s", dashboard.FormatSmartNumber(bal), cfg.Denom)) }
54+
if flagOutput == "json" { d.Printer.JSON(map[string]any{"ok": true, "address": addr, "balance": bal, "denom": d.Cfg.Denom}) } else { d.Printer.Info(fmt.Sprintf("%s %s", dashboard.FormatSmartNumber(bal), d.Cfg.Denom)) }
5755
return nil
5856
}

0 commit comments

Comments
 (0)