srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/scope/scope_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/scope/scope_test.go')
-rw-r--r--internal/scope/scope_test.go96
1 files changed, 96 insertions, 0 deletions
diff --git a/internal/scope/scope_test.go b/internal/scope/scope_test.go
new file mode 100644
index 0000000..fee5d44
--- /dev/null
+++ b/internal/scope/scope_test.go
@@ -0,0 +1,96 @@
+package scope
+
+import "testing"
+
+func TestInScopeEmptyRulesMeansEverything(t *testing.T) {
+ if !InScope(nil, "example.com") {
+ t.Error("empty rule set should mean everything is in scope")
+ }
+ if !InScope([]Rule{}, "anything.at.all") {
+ t.Error("empty rule set should mean everything is in scope")
+ }
+}
+
+func TestInScopeAllDisabledMeansEverything(t *testing.T) {
+ rules := []Rule{{Enabled: false, Pattern: "example.com"}}
+ if !InScope(rules, "unrelated.org") {
+ t.Error("no enabled rules should mean everything is in scope")
+ }
+}
+
+func TestInScopeSubstringMatch(t *testing.T) {
+ rules := []Rule{{Enabled: true, Pattern: "example.com"}}
+ tests := []struct {
+ host string
+ want bool
+ }{
+ {"example.com", true},
+ {"www.example.com", true},
+ {"api.example.com", true},
+ {"example.com.evil.org", true}, // substring containment, deliberately simple
+ {"other.org", false},
+ }
+ for _, tt := range tests {
+ if got := InScope(rules, tt.host); got != tt.want {
+ t.Errorf("InScope(%q) = %v, want %v", tt.host, got, tt.want)
+ }
+ }
+}
+
+func TestInScopeCaseInsensitive(t *testing.T) {
+ rules := []Rule{{Enabled: true, Pattern: "Example.COM"}}
+ if !InScope(rules, "www.EXAMPLE.com") {
+ t.Error("substring match should be case-insensitive")
+ }
+}
+
+func TestInScopeRegex(t *testing.T) {
+ rules := []Rule{{Enabled: true, Pattern: `(^|\.)example\.com$`, IsRegex: true}}
+ tests := []struct {
+ host string
+ want bool
+ }{
+ {"example.com", true},
+ {"api.example.com", true},
+ {"notexample.com", false},
+ {"example.com.evil.org", false},
+ }
+ for _, tt := range tests {
+ if got := InScope(rules, tt.host); got != tt.want {
+ t.Errorf("InScope(%q) = %v, want %v", tt.host, got, tt.want)
+ }
+ }
+}
+
+func TestInScopeInvalidRegexNeverMatches(t *testing.T) {
+ rules := []Rule{{Enabled: true, Pattern: "(unclosed", IsRegex: true}}
+ if InScope(rules, "example.com") {
+ t.Error("an invalid regex rule should never match, not panic or false-positive")
+ }
+}
+
+func TestInScopeMultipleRulesAnyMatch(t *testing.T) {
+ rules := []Rule{
+ {Enabled: true, Pattern: "example.com"},
+ {Enabled: true, Pattern: "other.org"},
+ }
+ if !InScope(rules, "other.org") {
+ t.Error("should match the second rule")
+ }
+ if InScope(rules, "unrelated.net") {
+ t.Error("should not match either rule")
+ }
+}
+
+func TestInScopeDisabledRuleIgnored(t *testing.T) {
+ rules := []Rule{
+ {Enabled: false, Pattern: "example.com"},
+ {Enabled: true, Pattern: "other.org"},
+ }
+ if InScope(rules, "example.com") {
+ t.Error("a disabled rule should not match")
+ }
+ if !InScope(rules, "other.org") {
+ t.Error("the enabled rule should still match")
+ }
+}