Skip to content

Commit b48f95c

Browse files
committed
Adding tests for new utils/scan work
1 parent faf10eb commit b48f95c

3 files changed

Lines changed: 269 additions & 0 deletions

File tree

cmd/scan_test.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package cmd
2+
3+
import (
4+
"net"
5+
"reflect"
6+
"testing"
7+
8+
"github.com/spf13/cobra"
9+
)
10+
11+
func TestScanCmd_FlagParsing(t *testing.T) {
12+
testCases := []struct {
13+
desc string
14+
flags map[string]string
15+
expectedMode string // "subnets", "broad-search", "cidr"
16+
}{
17+
{
18+
desc: "Default behavior uses CIDR",
19+
flags: map[string]string{},
20+
expectedMode: "cidr",
21+
},
22+
{
23+
desc: "Broad search flag set",
24+
flags: map[string]string{
25+
"broad-search": "true",
26+
},
27+
expectedMode: "broad-search",
28+
},
29+
{
30+
desc: "Subnets flag overrides broad search",
31+
flags: map[string]string{
32+
"broad-search": "true",
33+
"subnets": "192.168.1.0/24,10.0.0.0/24",
34+
},
35+
expectedMode: "subnets",
36+
},
37+
{
38+
desc: "Subnets flag with wildcard",
39+
flags: map[string]string{
40+
"subnets": "*",
41+
},
42+
expectedMode: "subnets",
43+
},
44+
}
45+
46+
for _, tc := range testCases {
47+
t.Run(tc.desc, func(t *testing.T) {
48+
cmd := &cobra.Command{}
49+
cmd.Flags().String("subnets", "", "")
50+
cmd.Flags().Bool("broad-search", false, "")
51+
cmd.Flags().String("cidr", "192.168.50.0/24", "")
52+
53+
// Set flags
54+
for key, value := range tc.flags {
55+
err := cmd.Flags().Set(key, value)
56+
if err != nil {
57+
t.Fatalf("Failed to set flag %s: %v", key, err)
58+
}
59+
}
60+
61+
// Get flag values
62+
subnetsFlag, _ := cmd.Flags().GetString("subnets")
63+
broadSearch, _ := cmd.Flags().GetBool("broad-search")
64+
65+
// Determine mode based on the same logic as the scan command
66+
var actualMode string
67+
if subnetsFlag != "" {
68+
actualMode = "subnets"
69+
} else if broadSearch {
70+
actualMode = "broad-search"
71+
} else {
72+
actualMode = "cidr"
73+
}
74+
75+
if actualMode != tc.expectedMode {
76+
t.Errorf("Expected mode %s, got %s", tc.expectedMode, actualMode)
77+
}
78+
})
79+
}
80+
}
81+
82+
func TestScanCmd_SubnetParsing(t *testing.T) {
83+
testCases := []struct {
84+
desc string
85+
input string
86+
expected []string
87+
}{
88+
{
89+
desc: "Single subnet",
90+
input: "192.168.1.0/24",
91+
expected: []string{"192.168.1.0/24"},
92+
},
93+
{
94+
desc: "Multiple subnets",
95+
input: "192.168.1.0/24,10.0.0.0/24,172.16.0.0/16",
96+
expected: []string{"192.168.1.0/24", "10.0.0.0/24", "172.16.0.0/16"},
97+
},
98+
{
99+
desc: "Subnets with spaces",
100+
input: "192.168.1.0/24, 10.0.0.0/24, 172.16.0.0/16",
101+
expected: []string{"192.168.1.0/24", "10.0.0.0/24", "172.16.0.0/16"},
102+
},
103+
{
104+
desc: "Empty input",
105+
input: "",
106+
expected: nil,
107+
},
108+
}
109+
110+
for _, tc := range testCases {
111+
t.Run(tc.desc, func(t *testing.T) {
112+
var result []string
113+
if tc.input != "" {
114+
for _, s := range splitAndTrim(tc.input, ",") {
115+
if s != "" {
116+
result = append(result, s)
117+
}
118+
}
119+
}
120+
121+
if (len(result) == 0 && len(tc.expected) == 0) ||
122+
(result == nil && tc.expected == nil) {
123+
return // Both empty or nil, test passes
124+
}
125+
if !reflect.DeepEqual(result, tc.expected) {
126+
t.Errorf("Expected %v, got %v", tc.expected, result)
127+
}
128+
})
129+
}
130+
}
131+
132+
func TestDetectLocalSubnet(t *testing.T) {
133+
// This test will verify that detectLocalSubnet doesn't crash
134+
// We can't mock network interfaces easily, so we'll just test basic functionality
135+
t.Run("DetectLocalSubnet doesn't crash", func(t *testing.T) {
136+
// This should either return a subnet or an error, but not crash
137+
subnet, err := detectLocalSubnet("")
138+
if err != nil {
139+
// It's okay if no subnet is detected in test environment
140+
t.Logf("No subnet detected (expected in test env): %v", err)
141+
} else {
142+
t.Logf("Detected subnet: %s", subnet)
143+
// Verify it's a valid CIDR
144+
_, _, err := net.ParseCIDR(subnet)
145+
if err != nil {
146+
t.Errorf("Invalid CIDR returned: %s, error: %v", subnet, err)
147+
}
148+
}
149+
})
150+
}
151+
152+
// TestScanCmd_Integration tests the actual scan command behavior
153+
func TestScanCmd_Integration(t *testing.T) {
154+
// Skip this test if we're not in an environment where we can safely run network scans
155+
if testing.Short() {
156+
t.Skip("Skipping integration test in short mode")
157+
}
158+
159+
t.Run("Command structure is valid", func(t *testing.T) {
160+
cmd := scanCmd
161+
162+
// Reset flags to default values
163+
cmd.Flags().Set("subnets", "")
164+
cmd.Flags().Set("broad-search", "false")
165+
cmd.Flags().Set("cidr", "192.168.50.0/24")
166+
167+
// We can't easily test the actual scanning without mocking
168+
// So we'll just verify the command can be created and flags work
169+
if cmd == nil {
170+
t.Error("scanCmd should not be nil")
171+
}
172+
173+
// Test that flags can be retrieved
174+
subnets, err := cmd.Flags().GetString("subnets")
175+
if err != nil {
176+
t.Errorf("Failed to get subnets flag: %v", err)
177+
}
178+
if subnets != "" {
179+
t.Errorf("Expected empty subnets, got %s", subnets)
180+
}
181+
182+
broadSearch, err := cmd.Flags().GetBool("broad-search")
183+
if err != nil {
184+
t.Errorf("Failed to get broad-search flag: %v", err)
185+
}
186+
if broadSearch {
187+
t.Error("Expected broad-search to be false")
188+
}
189+
})
190+
}

cmd/utils_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package cmd
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestSplitAndTrim(t *testing.T) {
9+
testCases := []struct {
10+
desc string
11+
input string
12+
sep string
13+
expected []string
14+
}{
15+
{
16+
desc: "Empty input",
17+
input: "",
18+
sep: ",",
19+
expected: []string{},
20+
},
21+
{
22+
desc: "Single item",
23+
input: "192.168.1.1",
24+
sep: ",",
25+
expected: []string{"192.168.1.1"},
26+
},
27+
{
28+
desc: "Multiple items with spaces",
29+
input: "192.168.1.1, 10.0.0.1, 172.16.0.1",
30+
sep: ",",
31+
expected: []string{"192.168.1.1", "10.0.0.1", "172.16.0.1"},
32+
},
33+
{
34+
desc: "Multiple items without spaces",
35+
input: "192.168.1.1,10.0.0.1,172.16.0.1",
36+
sep: ",",
37+
expected: []string{"192.168.1.1", "10.0.0.1", "172.16.0.1"},
38+
},
39+
{
40+
desc: "Items with leading/trailing spaces",
41+
input: " 192.168.1.1 , 10.0.0.1 ",
42+
sep: ",",
43+
expected: []string{"192.168.1.1", "10.0.0.1"},
44+
},
45+
{
46+
desc: "Different separator",
47+
input: "item1|item2|item3",
48+
sep: "|",
49+
expected: []string{"item1", "item2", "item3"},
50+
},
51+
}
52+
53+
for _, tc := range testCases {
54+
t.Run(tc.desc, func(t *testing.T) {
55+
result := splitAndTrim(tc.input, tc.sep)
56+
if len(result) == 0 && len(tc.expected) == 0 {
57+
// This is fine, just continue
58+
return
59+
}
60+
if !reflect.DeepEqual(result, tc.expected) {
61+
t.Errorf("splitAndTrim(%q, %q) = %v; want %v", tc.input, tc.sep, result, tc.expected)
62+
}
63+
})
64+
}
65+
}

testdata/scan.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Test scan command help and basic functionality
2+
go-chromecast scan --help
3+
stdout 'Scan for chromecast devices'
4+
stdout 'subnets'
5+
stdout 'broad-search'
6+
stdout 'cidr'
7+
! stderr .
8+
9+
# Test that scan command accepts the flags in help output
10+
go-chromecast scan --subnets 192.168.1.0/24 --help
11+
stdout 'subnets'
12+
13+
go-chromecast scan --broad-search --help
14+
stdout 'broad-search'

0 commit comments

Comments
 (0)