@cryptotaxi247 / kubo / commits / 798b889ba

test(cmdutils): add tests for PathOrCidPath and ValidatePinName (#11062)

Marcin Rataj committed Nov 17, 2025 at 18:00 UTC 798b889ba258821c9faa5e4b0af903c21516c4c2
1 file changed +106
core/commands/cmdutils/utils_test.go new
+106
@@ -0,0 +1,106 @@
1 +package cmdutils
2 +
3 +import (
4 + "strings"
5 + "testing"
6 +
7 + "github.com/stretchr/testify/assert"
8 + "github.com/stretchr/testify/require"
9 +)
10 +
11 +func TestPathOrCidPath(t *testing.T) {
12 + t.Run("valid path is returned as-is", func(t *testing.T) {
13 + validPath := "/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"
14 + p, err := PathOrCidPath(validPath)
15 + require.NoError(t, err)
16 + assert.Equal(t, validPath, p.String())
17 + })
18 +
19 + t.Run("valid CID is converted to /ipfs/ path", func(t *testing.T) {
20 + cid := "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"
21 + p, err := PathOrCidPath(cid)
22 + require.NoError(t, err)
23 + assert.Equal(t, "/ipfs/"+cid, p.String())
24 + })
25 +
26 + t.Run("valid ipns path is returned as-is", func(t *testing.T) {
27 + validPath := "/ipns/example.com"
28 + p, err := PathOrCidPath(validPath)
29 + require.NoError(t, err)
30 + assert.Equal(t, validPath, p.String())
31 + })
32 +
33 + t.Run("returns original error when both attempts fail", func(t *testing.T) {
34 + invalidInput := "invalid!@#path"
35 + _, err := PathOrCidPath(invalidInput)
36 + require.Error(t, err)
37 +
38 + // The error should reference the original input attempt.
39 + // This ensures users get meaningful error messages about their actual input.
40 + assert.Contains(t, err.Error(), invalidInput,
41 + "error should mention the original input")
42 + assert.Contains(t, err.Error(), "path does not have enough components",
43 + "error should describe the problem with the original input")
44 + })
45 +
46 + t.Run("empty string returns error about original input", func(t *testing.T) {
47 + _, err := PathOrCidPath("")
48 + require.Error(t, err)
49 +
50 + // Verify we're not getting an error about "/ipfs/" (the fallback)
51 + errMsg := err.Error()
52 + assert.NotContains(t, errMsg, "/ipfs/",
53 + "error should be about empty input, not the fallback path")
54 + })
55 +
56 + t.Run("invalid characters return error about original input", func(t *testing.T) {
57 + invalidInput := "not a valid path or CID with spaces and /@#$%"
58 + _, err := PathOrCidPath(invalidInput)
59 + require.Error(t, err)
60 +
61 + // The error message should help debug the original input
62 + assert.True(t, strings.Contains(err.Error(), invalidInput) ||
63 + strings.Contains(err.Error(), "invalid"),
64 + "error should reference original problematic input")
65 + })
66 +
67 + t.Run("CID with path is converted correctly", func(t *testing.T) {
68 + cidWithPath := "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/file.txt"
69 + p, err := PathOrCidPath(cidWithPath)
70 + require.NoError(t, err)
71 + assert.Equal(t, "/ipfs/"+cidWithPath, p.String())
72 + })
73 +}
74 +
75 +func TestValidatePinName(t *testing.T) {
76 + t.Run("valid pin name is accepted", func(t *testing.T) {
77 + err := ValidatePinName("my-pin-name")
78 + assert.NoError(t, err)
79 + })
80 +
81 + t.Run("empty pin name is accepted", func(t *testing.T) {
82 + err := ValidatePinName("")
83 + assert.NoError(t, err)
84 + })
85 +
86 + t.Run("pin name at max length is accepted", func(t *testing.T) {
87 + maxName := strings.Repeat("a", MaxPinNameBytes)
88 + err := ValidatePinName(maxName)
89 + assert.NoError(t, err)
90 + })
91 +
92 + t.Run("pin name exceeding max length is rejected", func(t *testing.T) {
93 + tooLong := strings.Repeat("a", MaxPinNameBytes+1)
94 + err := ValidatePinName(tooLong)
95 + require.Error(t, err)
96 + assert.Contains(t, err.Error(), "max")
97 + })
98 +
99 + t.Run("pin name with unicode is counted by bytes", func(t *testing.T) {
100 + // Unicode character can be multiple bytes
101 + unicodeName := strings.Repeat("🔒", MaxPinNameBytes/4+1) // emoji is 4 bytes
102 + err := ValidatePinName(unicodeName)
103 + require.Error(t, err)
104 + assert.Contains(t, err.Error(), "bytes")
105 + })
106 +}