test: Improve coverage for security utility functions
- Add fmt.Stringer test cases for isEmptyInterface (80% -> 100%) - Expand isTrustedNetwork tests with edge cases (80% -> 100%) - Empty/invalid IP strings - Invalid CIDR handling - Whitespace trimming in CIDRs - Multiple network matching
This commit is contained in:
parent
17512e076a
commit
737c02983f
2 changed files with 117 additions and 14 deletions
|
|
@ -68,23 +68,97 @@ func TestIsPrivateIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIsTrustedNetwork(t *testing.T) {
|
func TestIsTrustedNetwork(t *testing.T) {
|
||||||
t.Helper()
|
t.Parallel()
|
||||||
|
|
||||||
if !isTrustedNetwork("10.0.0.5", nil) {
|
tests := []struct {
|
||||||
t.Fatal("expected private IP to be trusted when no networks configured")
|
name string
|
||||||
|
ip string
|
||||||
|
trustedNetworks []string
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
// Nil trusted networks - falls back to private IP check
|
||||||
|
{
|
||||||
|
name: "private IP trusted when no networks configured",
|
||||||
|
ip: "10.0.0.5",
|
||||||
|
trustedNetworks: nil,
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "public IP untrusted when no networks configured",
|
||||||
|
ip: "198.51.100.42",
|
||||||
|
trustedNetworks: nil,
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
// Empty trusted networks slice - falls back to private IP check
|
||||||
|
{
|
||||||
|
name: "private IP trusted with empty networks",
|
||||||
|
ip: "192.168.1.1",
|
||||||
|
trustedNetworks: []string{},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
// Custom CIDR networks
|
||||||
|
{
|
||||||
|
name: "IP within custom CIDR trusted",
|
||||||
|
ip: "203.0.113.44:8080",
|
||||||
|
trustedNetworks: []string{"203.0.113.0/24"},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IP outside custom CIDR untrusted",
|
||||||
|
ip: "198.51.100.42",
|
||||||
|
trustedNetworks: []string{"203.0.113.0/24"},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
// Edge cases - empty/invalid input
|
||||||
|
{
|
||||||
|
name: "empty IP string returns false",
|
||||||
|
ip: "",
|
||||||
|
trustedNetworks: []string{"10.0.0.0/8"},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid IP returns false",
|
||||||
|
ip: "not-an-ip",
|
||||||
|
trustedNetworks: []string{"10.0.0.0/8"},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
// Invalid CIDR is skipped, not matched
|
||||||
|
{
|
||||||
|
name: "invalid CIDR in list is skipped",
|
||||||
|
ip: "10.0.0.5",
|
||||||
|
trustedNetworks: []string{"invalid-cidr", "10.0.0.0/8"},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "only invalid CIDRs returns false",
|
||||||
|
ip: "10.0.0.5",
|
||||||
|
trustedNetworks: []string{"invalid-cidr", "also-invalid"},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
// Whitespace handling in CIDRs
|
||||||
|
{
|
||||||
|
name: "CIDR with whitespace is trimmed",
|
||||||
|
ip: "10.0.0.5",
|
||||||
|
trustedNetworks: []string{" 10.0.0.0/8 "},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
// Multiple valid CIDRs
|
||||||
|
{
|
||||||
|
name: "IP matches second CIDR",
|
||||||
|
ip: "172.16.5.10",
|
||||||
|
trustedNetworks: []string{"10.0.0.0/8", "172.16.0.0/12"},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if isTrustedNetwork("198.51.100.42", nil) {
|
for _, tt := range tests {
|
||||||
t.Fatal("expected public IP to be untrusted when no networks configured")
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
}
|
t.Parallel()
|
||||||
|
result := isTrustedNetwork(tt.ip, tt.trustedNetworks)
|
||||||
custom := []string{"203.0.113.0/24"}
|
if result != tt.expected {
|
||||||
if !isTrustedNetwork("203.0.113.44:8080", custom) {
|
t.Errorf("isTrustedNetwork(%q, %v) = %v, want %v", tt.ip, tt.trustedNetworks, result, tt.expected)
|
||||||
t.Fatal("expected IP within custom CIDR to be trusted")
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
if isTrustedNetwork("198.51.100.42", custom) {
|
|
||||||
t.Fatal("expected IP outside custom CIDR to be untrusted")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -694,6 +694,22 @@ func TestIsEmptyInterface(t *testing.T) {
|
||||||
value: map[string]string{},
|
value: map[string]string{},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
|
// fmt.Stringer types
|
||||||
|
{
|
||||||
|
name: "stringer with empty string",
|
||||||
|
value: emptyStringer{},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "stringer with whitespace",
|
||||||
|
value: whitespaceStringer{},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "stringer with content",
|
||||||
|
value: contentStringer{},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
@ -706,6 +722,19 @@ func TestIsEmptyInterface(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test helper types for fmt.Stringer interface
|
||||||
|
type emptyStringer struct{}
|
||||||
|
|
||||||
|
func (emptyStringer) String() string { return "" }
|
||||||
|
|
||||||
|
type whitespaceStringer struct{}
|
||||||
|
|
||||||
|
func (whitespaceStringer) String() string { return " \t " }
|
||||||
|
|
||||||
|
type contentStringer struct{}
|
||||||
|
|
||||||
|
func (contentStringer) String() string { return "content" }
|
||||||
|
|
||||||
func TestEnsurePushoverCustomFieldAliases(t *testing.T) {
|
func TestEnsurePushoverCustomFieldAliases(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue