package imgcache import ( "net/url" "testing" ) func TestHostWhitelist_IsWhitelisted(t *testing.T) { tests := []struct { name string patterns []string testURL string want bool }{ { name: "exact match", patterns: []string{"cdn.example.com"}, testURL: "https://cdn.example.com/image.jpg", want: true, }, { name: "exact match case insensitive", patterns: []string{"CDN.Example.COM"}, testURL: "https://cdn.example.com/image.jpg", want: true, }, { name: "exact match not found", patterns: []string{"cdn.example.com"}, testURL: "https://other.example.com/image.jpg", want: false, }, { name: "suffix match", patterns: []string{".example.com"}, testURL: "https://cdn.example.com/image.jpg", want: true, }, { name: "suffix match deep subdomain", patterns: []string{".example.com"}, testURL: "https://cdn.images.example.com/image.jpg", want: true, }, { name: "suffix match apex domain", patterns: []string{".example.com"}, testURL: "https://example.com/image.jpg", want: true, }, { name: "suffix match not found", patterns: []string{".example.com"}, testURL: "https://notexample.com/image.jpg", want: false, }, { name: "suffix match partial not allowed", patterns: []string{".example.com"}, testURL: "https://fakeexample.com/image.jpg", want: false, }, { name: "multiple patterns", patterns: []string{"cdn.example.com", ".images.org", "static.test.net"}, testURL: "https://photos.images.org/image.jpg", want: true, }, { name: "empty whitelist", patterns: []string{}, testURL: "https://cdn.example.com/image.jpg", want: false, }, { name: "nil url", patterns: []string{"cdn.example.com"}, testURL: "", want: false, }, { name: "url with port", patterns: []string{"cdn.example.com"}, testURL: "https://cdn.example.com:443/image.jpg", want: true, }, { name: "whitespace in patterns", patterns: []string{" cdn.example.com ", " .other.com "}, testURL: "https://cdn.example.com/image.jpg", want: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { w := NewHostWhitelist(tt.patterns) var u *url.URL if tt.testURL != "" { var err error u, err = url.Parse(tt.testURL) if err != nil { t.Fatalf("failed to parse test URL: %v", err) } } got := w.IsWhitelisted(u) if got != tt.want { t.Errorf("IsWhitelisted() = %v, want %v", got, tt.want) } }) } } func TestHostWhitelist_IsEmpty(t *testing.T) { tests := []struct { name string patterns []string want bool }{ { name: "empty", patterns: []string{}, want: true, }, { name: "nil", patterns: nil, want: true, }, { name: "whitespace only", patterns: []string{" ", ""}, want: true, }, { name: "has entries", patterns: []string{"example.com"}, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { w := NewHostWhitelist(tt.patterns) if got := w.IsEmpty(); got != tt.want { t.Errorf("IsEmpty() = %v, want %v", got, tt.want) } }) } } func TestHostWhitelist_Count(t *testing.T) { tests := []struct { name string patterns []string want int }{ { name: "empty", patterns: []string{}, want: 0, }, { name: "exact hosts only", patterns: []string{"a.com", "b.com", "c.com"}, want: 3, }, { name: "suffix hosts only", patterns: []string{".a.com", ".b.com"}, want: 2, }, { name: "mixed", patterns: []string{"exact.com", ".suffix.com"}, want: 2, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { w := NewHostWhitelist(tt.patterns) if got := w.Count(); got != tt.want { t.Errorf("Count() = %v, want %v", got, tt.want) } }) } }