Skip to content

Commit 1d7e4a8

Browse files
committed
fixes
1 parent 3998fa6 commit 1d7e4a8

2 files changed

Lines changed: 444 additions & 0 deletions

File tree

Lines changed: 397 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
8+
"github.com/pushchain/push-validator-cli/internal/validator"
9+
)
10+
11+
func editValidatorDeps(overrides ...func(*Deps)) *Deps {
12+
d := &Deps{
13+
Cfg: testCfg(),
14+
Sup: &mockSupervisor{running: true},
15+
Node: &mockNodeClient{},
16+
RemoteNode: &mockNodeClient{},
17+
Fetcher: &mockFetcher{myValidator: validator.MyValidatorInfo{
18+
IsValidator: true,
19+
Address: "pushvaloper1test",
20+
Moniker: "test-validator",
21+
}},
22+
Validator: &mockValidator{editValResult: "TXHASH_EDIT"},
23+
Runner: newMockRunner(),
24+
Prompter: &nonInteractivePrompter{},
25+
RPCCheck: func(string, time.Duration) bool { return true },
26+
}
27+
for _, fn := range overrides {
28+
fn(d)
29+
}
30+
return d
31+
}
32+
33+
func TestHandleEditValidator_NodeNotRunning(t *testing.T) {
34+
origOutput := flagOutput
35+
defer func() { flagOutput = origOutput }()
36+
flagOutput = "json"
37+
38+
d := editValidatorDeps(func(d *Deps) {
39+
d.Sup = &mockSupervisor{running: false}
40+
})
41+
42+
err := handleEditValidator(d)
43+
if err == nil {
44+
t.Fatal("expected error")
45+
}
46+
if !containsSubstr(err.Error(), "node is not running") {
47+
t.Errorf("unexpected error: %v", err)
48+
}
49+
}
50+
51+
func TestHandleEditValidator_FetcherError(t *testing.T) {
52+
origOutput := flagOutput
53+
defer func() { flagOutput = origOutput }()
54+
flagOutput = "json"
55+
56+
d := editValidatorDeps(func(d *Deps) {
57+
d.Fetcher = &mockFetcher{myValidatorErr: fmt.Errorf("timeout")}
58+
})
59+
60+
err := handleEditValidator(d)
61+
if err == nil {
62+
t.Fatal("expected error")
63+
}
64+
if !containsSubstr(err.Error(), "failed to check validator status") {
65+
t.Errorf("unexpected error: %v", err)
66+
}
67+
}
68+
69+
func TestHandleEditValidator_NotValidator(t *testing.T) {
70+
origOutput := flagOutput
71+
defer func() { flagOutput = origOutput }()
72+
flagOutput = "json"
73+
74+
d := editValidatorDeps(func(d *Deps) {
75+
d.Fetcher = &mockFetcher{myValidator: validator.MyValidatorInfo{IsValidator: false}}
76+
})
77+
78+
err := handleEditValidator(d)
79+
if err == nil {
80+
t.Fatal("expected error")
81+
}
82+
if !containsSubstr(err.Error(), "not registered as validator") {
83+
t.Errorf("unexpected error: %v", err)
84+
}
85+
}
86+
87+
func TestHandleEditValidator_NoChanges(t *testing.T) {
88+
origOutput := flagOutput
89+
defer func() { flagOutput = origOutput }()
90+
flagOutput = "json"
91+
92+
d := editValidatorDeps(func(d *Deps) {
93+
d.Prompter = &mockPrompter{
94+
responses: []string{"", "", "", "", ""},
95+
interactive: true,
96+
}
97+
})
98+
99+
err := handleEditValidator(d)
100+
if err != nil {
101+
t.Fatalf("expected nil error for no changes, got: %v", err)
102+
}
103+
}
104+
105+
func TestHandleEditValidator_Success_JSON(t *testing.T) {
106+
origOutput := flagOutput
107+
defer func() { flagOutput = origOutput }()
108+
flagOutput = "json"
109+
110+
t.Setenv("VALIDATOR_MONIKER", "json-moniker")
111+
112+
d := editValidatorDeps()
113+
114+
err := handleEditValidator(d)
115+
if err != nil {
116+
t.Fatalf("unexpected error: %v", err)
117+
}
118+
}
119+
120+
func TestHandleEditValidator_Success_Text(t *testing.T) {
121+
origOutput := flagOutput
122+
origNoColor := flagNoColor
123+
origNoEmoji := flagNoEmoji
124+
defer func() {
125+
flagOutput = origOutput
126+
flagNoColor = origNoColor
127+
flagNoEmoji = origNoEmoji
128+
}()
129+
flagOutput = "text"
130+
flagNoColor = true
131+
flagNoEmoji = true
132+
133+
d := editValidatorDeps(func(d *Deps) {
134+
d.Prompter = &mockPrompter{
135+
responses: []string{"new-moniker", "", "", "", ""},
136+
interactive: true,
137+
}
138+
})
139+
140+
err := handleEditValidator(d)
141+
if err != nil {
142+
t.Fatalf("unexpected error: %v", err)
143+
}
144+
}
145+
146+
func TestHandleEditValidator_EditValidatorFails(t *testing.T) {
147+
origOutput := flagOutput
148+
origNoColor := flagNoColor
149+
origNoEmoji := flagNoEmoji
150+
defer func() {
151+
flagOutput = origOutput
152+
flagNoColor = origNoColor
153+
flagNoEmoji = origNoEmoji
154+
}()
155+
flagOutput = "text"
156+
flagNoColor = true
157+
flagNoEmoji = true
158+
159+
d := editValidatorDeps(func(d *Deps) {
160+
d.Validator = &mockValidator{editValErr: fmt.Errorf("insufficient gas")}
161+
d.Prompter = &mockPrompter{
162+
responses: []string{"new-moniker", "", "", "", ""},
163+
interactive: true,
164+
}
165+
})
166+
167+
err := handleEditValidator(d)
168+
if err == nil {
169+
t.Fatal("expected error")
170+
}
171+
if !containsSubstr(err.Error(), "edit validator failed") {
172+
t.Errorf("unexpected error: %v", err)
173+
}
174+
}
175+
176+
func TestHandleEditValidator_EditValidatorFails_JSON(t *testing.T) {
177+
origOutput := flagOutput
178+
defer func() { flagOutput = origOutput }()
179+
flagOutput = "json"
180+
181+
t.Setenv("VALIDATOR_MONIKER", "fail-moniker")
182+
183+
d := editValidatorDeps(func(d *Deps) {
184+
d.Validator = &mockValidator{editValErr: fmt.Errorf("insufficient gas")}
185+
})
186+
187+
err := handleEditValidator(d)
188+
if err == nil {
189+
t.Fatal("expected error")
190+
}
191+
if !containsSubstr(err.Error(), "edit validator failed") {
192+
t.Errorf("unexpected error: %v", err)
193+
}
194+
}
195+
196+
func TestHandleEditValidator_EditValidatorFails_Text(t *testing.T) {
197+
origOutput := flagOutput
198+
origNoColor := flagNoColor
199+
origNoEmoji := flagNoEmoji
200+
defer func() {
201+
flagOutput = origOutput
202+
flagNoColor = origNoColor
203+
flagNoEmoji = origNoEmoji
204+
}()
205+
flagOutput = "text"
206+
flagNoColor = true
207+
flagNoEmoji = true
208+
209+
d := editValidatorDeps(func(d *Deps) {
210+
d.Validator = &mockValidator{editValErr: fmt.Errorf("insufficient gas")}
211+
d.Prompter = &mockPrompter{
212+
responses: []string{"new-moniker", "", "", "", ""},
213+
interactive: true,
214+
}
215+
})
216+
217+
err := handleEditValidator(d)
218+
if err == nil {
219+
t.Fatal("expected error")
220+
}
221+
if !containsSubstr(err.Error(), "edit validator failed") {
222+
t.Errorf("unexpected error: %v", err)
223+
}
224+
}
225+
226+
func TestHandleEditValidator_NonInteractive_EnvVars(t *testing.T) {
227+
origOutput := flagOutput
228+
defer func() { flagOutput = origOutput }()
229+
flagOutput = "json"
230+
231+
t.Setenv("VALIDATOR_MONIKER", "env-moniker")
232+
t.Setenv("VALIDATOR_WEBSITE", "https://example.com")
233+
t.Setenv("VALIDATOR_DETAILS", "my validator")
234+
t.Setenv("VALIDATOR_SECURITY", "sec@example.com")
235+
t.Setenv("VALIDATOR_IDENTITY", "ABCD1234ABCD1234")
236+
237+
d := editValidatorDeps() // non-interactive prompter by default
238+
239+
err := handleEditValidator(d)
240+
if err != nil {
241+
t.Fatalf("unexpected error: %v", err)
242+
}
243+
}
244+
245+
func TestHandleEditValidator_Interactive_AllFields(t *testing.T) {
246+
origOutput := flagOutput
247+
origNoColor := flagNoColor
248+
origNoEmoji := flagNoEmoji
249+
defer func() {
250+
flagOutput = origOutput
251+
flagNoColor = origNoColor
252+
flagNoEmoji = origNoEmoji
253+
}()
254+
flagOutput = "text"
255+
flagNoColor = true
256+
flagNoEmoji = true
257+
258+
d := editValidatorDeps(func(d *Deps) {
259+
d.Fetcher = &mockFetcher{myValidator: validator.MyValidatorInfo{
260+
IsValidator: true,
261+
Address: "pushvaloper1test",
262+
Moniker: "old-moniker",
263+
Website: "https://old.example.com",
264+
Details: "old details",
265+
SecurityContact: "old@example.com",
266+
Identity: "OLD_IDENTITY",
267+
}}
268+
d.Prompter = &mockPrompter{
269+
responses: []string{"new-moniker", "https://new.example.com", "new details", "new@example.com", "NEW_IDENTITY"},
270+
interactive: true,
271+
}
272+
})
273+
274+
err := handleEditValidator(d)
275+
if err != nil {
276+
t.Fatalf("unexpected error: %v", err)
277+
}
278+
}
279+
280+
func TestHandleEditValidator_KeyDerivation_Success(t *testing.T) {
281+
origOutput := flagOutput
282+
origNoColor := flagNoColor
283+
origNoEmoji := flagNoEmoji
284+
defer func() {
285+
flagOutput = origOutput
286+
flagNoColor = origNoColor
287+
flagNoEmoji = origNoEmoji
288+
}()
289+
flagOutput = "text"
290+
flagNoColor = true
291+
flagNoEmoji = true
292+
293+
runner := newMockRunner()
294+
binPath := findPchaind()
295+
cfg := testCfg()
296+
// Mock address conversion
297+
runner.outputs[binPath+" debug addr pushvaloper1test"] = []byte("Bech32 Acc: push1account\n")
298+
// Mock key list lookup
299+
runner.outputs[binPath+" keys list --keyring-backend "+cfg.KeyringBackend+" --home "+cfg.HomeDir+" --output json"] = []byte(`[{"name":"my-derived-key","address":"push1account"}]`)
300+
301+
d := editValidatorDeps(func(d *Deps) {
302+
d.Runner = runner
303+
d.Prompter = &mockPrompter{
304+
responses: []string{"new-moniker", "", "", "", ""},
305+
interactive: true,
306+
}
307+
})
308+
309+
err := handleEditValidator(d)
310+
if err != nil {
311+
t.Fatalf("unexpected error: %v", err)
312+
}
313+
}
314+
315+
func TestHandleEditValidator_KeyDerivation_Fallback(t *testing.T) {
316+
origOutput := flagOutput
317+
origNoColor := flagNoColor
318+
origNoEmoji := flagNoEmoji
319+
defer func() {
320+
flagOutput = origOutput
321+
flagNoColor = origNoColor
322+
flagNoEmoji = origNoEmoji
323+
}()
324+
flagOutput = "text"
325+
flagNoColor = true
326+
flagNoEmoji = true
327+
328+
runner := newMockRunner()
329+
binPath := findPchaind()
330+
// Address conversion fails — should fall back to default key name
331+
runner.errors[binPath+" debug addr pushvaloper1test"] = fmt.Errorf("binary not found")
332+
333+
d := editValidatorDeps(func(d *Deps) {
334+
d.Runner = runner
335+
d.Prompter = &mockPrompter{
336+
responses: []string{"new-moniker", "", "", "", ""},
337+
interactive: true,
338+
}
339+
})
340+
341+
err := handleEditValidator(d)
342+
if err != nil {
343+
t.Fatalf("unexpected error: %v", err)
344+
}
345+
}
346+
347+
func TestHandleEditValidator_NotValidator_Text(t *testing.T) {
348+
origOutput := flagOutput
349+
origNoColor := flagNoColor
350+
origNoEmoji := flagNoEmoji
351+
defer func() {
352+
flagOutput = origOutput
353+
flagNoColor = origNoColor
354+
flagNoEmoji = origNoEmoji
355+
}()
356+
flagOutput = "text"
357+
flagNoColor = true
358+
flagNoEmoji = true
359+
360+
d := editValidatorDeps(func(d *Deps) {
361+
d.Fetcher = &mockFetcher{myValidator: validator.MyValidatorInfo{IsValidator: false}}
362+
})
363+
364+
err := handleEditValidator(d)
365+
if err == nil {
366+
t.Fatal("expected error")
367+
}
368+
if !containsSubstr(err.Error(), "not registered as validator") {
369+
t.Errorf("unexpected error: %v", err)
370+
}
371+
}
372+
373+
func TestHandleEditValidator_FetcherError_Text(t *testing.T) {
374+
origOutput := flagOutput
375+
origNoColor := flagNoColor
376+
origNoEmoji := flagNoEmoji
377+
defer func() {
378+
flagOutput = origOutput
379+
flagNoColor = origNoColor
380+
flagNoEmoji = origNoEmoji
381+
}()
382+
flagOutput = "text"
383+
flagNoColor = true
384+
flagNoEmoji = true
385+
386+
d := editValidatorDeps(func(d *Deps) {
387+
d.Fetcher = &mockFetcher{myValidatorErr: fmt.Errorf("timeout")}
388+
})
389+
390+
err := handleEditValidator(d)
391+
if err == nil {
392+
t.Fatal("expected error")
393+
}
394+
if !containsSubstr(err.Error(), "failed to check validator status") {
395+
t.Errorf("unexpected error: %v", err)
396+
}
397+
}

0 commit comments

Comments
 (0)