package main import ( "bufio" "bytes" "net/http" "net/http/httptest" "testing" ) func TestFetchURLList(t *testing.T) { tests := []struct { name string content string want []string wantErr bool }{ { name: "basic list with comments", content: `# comment https://example.com/1 https://example.com/2 # another comment https://example.com/3`, want: []string{ "https://example.com/1", "https://example.com/2", "https://example.com/3", }, }, { name: "empty lines and whitespace", content: ` https://example.com/1 https://example.com/2`, want: []string{ "https://example.com/1", "https://example.com/2", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, err := w.Write([]byte(tt.content)) if err != nil { t.Errorf("Couldn't write to content %v", err) } })) defer ts.Close() got, err := fetchURLList(ts.URL) if (err != nil) != tt.wantErr { t.Errorf("fetchURLList() error = %v, wantErr %v", err, tt.wantErr) return } if !stringSliceEqual(got, tt.want) { t.Errorf("fetchURLList() = %v, want %v", got, tt.want) } }) } } func TestFetchDomainsAndWrite(t *testing.T) { tests := []struct { name string content string want string wantSeen map[string]struct{} }{ { name: "ip and domain format", content: `# comment 0.0.0.0 domain1.com 0.0.0.0 domain2.com`, want: `local-zone: "domain1.com" refuse local-zone: "domain2.com" refuse `, wantSeen: map[string]struct{}{ "domain1.com": {}, "domain2.com": {}, }, }, { name: "plain domain format", content: `# comment domain1.com domain2.com`, want: `local-zone: "domain1.com" refuse local-zone: "domain2.com" refuse `, wantSeen: map[string]struct{}{ "domain1.com": {}, "domain2.com": {}, }, }, { name: "mixed format with duplicates", content: `domain1.com 0.0.0.0 domain1.com 0.0.0.0 DOMAIN1.COM domain2.com`, want: `local-zone: "domain1.com" refuse local-zone: "domain2.com" refuse `, wantSeen: map[string]struct{}{ "domain1.com": {}, "domain2.com": {}, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, err := w.Write([]byte(tt.content)) if err != nil { t.Errorf("Couldn't write to content %v", err) } })) defer ts.Close() var buf bytes.Buffer w := bufio.NewWriter(&buf) seen := make(map[string]struct{}) err := fetchDomainsAndWrite(ts.URL, w, seen) if err != nil { t.Fatalf("fetchDomainsAndWrite() error = %v", err) } w.Flush() if got := buf.String(); got != tt.want { t.Errorf("fetchDomainsAndWrite() output = %q, want %q", got, tt.want) } if !mapEqual(seen, tt.wantSeen) { t.Errorf("fetchDomainsAndWrite() seen = %v, want %v", seen, tt.wantSeen) } }) } } func stringSliceEqual(a, b []string) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true } func mapEqual(a, b map[string]struct{}) bool { if len(a) != len(b) { return false } for k := range a { if _, ok := b[k]; !ok { return false } } return true }