aboutsummaryrefslogtreecommitdiff
path: root/main_test.go
diff options
context:
space:
mode:
authorMax Resnick <max@ofmax.li>2025-02-28 22:59:23 -0800
committerMax Resnick <max@ofmax.li>2025-02-28 22:59:23 -0800
commit5680113281aa58b63b1bdd7445a17e281007df23 (patch)
treea9e6438086c2fe8f61d44f5d46b358ca9cddabe4 /main_test.go
downloadunbound-adblock-config-5680113281aa58b63b1bdd7445a17e281007df23.tar.gz
feat: ad domain parser
Diffstat (limited to '')
-rw-r--r--main_test.go161
1 files changed, 161 insertions, 0 deletions
diff --git a/main_test.go b/main_test.go
new file mode 100644
index 0000000..29a8341
--- /dev/null
+++ b/main_test.go
@@ -0,0 +1,161 @@
+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) {
+ w.Write([]byte(tt.content))
+ }))
+ 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) {
+ w.Write([]byte(tt.content))
+ }))
+ 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
+}