package checker import ( "reflect" "testing" "github.com/miekg/dns" sdk "git.happydns.org/checker-sdk-go/checker" ) func TestResolveQTypes_ExplicitOverride(t *testing.T) { apex := "example.com." names := []string{apex, "www.example.com."} opts := sdk.CheckerOptions{ "zone": map[string]any{}, // ignored when recordTypes is set } owner, union, err := resolveQTypes(opts, "A,AAAA", apex, names) if err != nil { t.Fatalf("err: %v", err) } want := []uint16{dns.TypeA, dns.TypeAAAA} for _, n := range names { if !reflect.DeepEqual(owner[n], want) { t.Errorf("owner[%s] = %v, want %v", n, owner[n], want) } } if !reflect.DeepEqual(union, want) { t.Errorf("union = %v, want %v", union, want) } } func TestResolveQTypes_NoZoneNoOption(t *testing.T) { apex := "example.com." names := []string{apex} owner, union, err := resolveQTypes(sdk.CheckerOptions{}, "", apex, names) if err != nil { t.Fatalf("err: %v", err) } if !reflect.DeepEqual(owner[apex], fallbackQTypes) { t.Errorf("apex types = %v, want fallback %v", owner[apex], fallbackQTypes) } if len(union) != len(fallbackQTypes) { t.Errorf("union len = %d, want %d", len(union), len(fallbackQTypes)) } } func TestResolveQTypes_FromZone_NoCAA(t *testing.T) { apex := "example.com." names := []string{apex} // A zone with MX + TXT services at the apex, but no CAA. zone := map[string]any{ "domain_name": "example.com", "services": map[string]any{ "": []any{ map[string]any{ "_svctype": "svcs.MXs", "_domain": "example.com", "Service": map[string]any{ "mx": []any{ map[string]any{ "Hdr": map[string]any{ "Name": "example.com.", "Rrtype": float64(dns.TypeMX), }, "Mx": "mail.example.com.", "Preference": float64(10), }, }, }, }, map[string]any{ "_svctype": "svcs.TXT", "_domain": "example.com", "Service": map[string]any{ "Hdr": map[string]any{ "Name": "example.com.", "Rrtype": float64(dns.TypeTXT), }, "Txt": []any{"v=spf1 -all"}, }, }, }, }, } opts := sdk.CheckerOptions{"zone": zone} owner, union, err := resolveQTypes(opts, "", apex, names) if err != nil { t.Fatalf("err: %v", err) } got := map[uint16]bool{} for _, qt := range owner[apex] { got[qt] = true } // Must have MX, TXT, plus the always-on SOA/NS. for _, qt := range []uint16{dns.TypeSOA, dns.TypeNS, dns.TypeMX, dns.TypeTXT} { if !got[qt] { t.Errorf("apex missing %s", dns.TypeToString[qt]) } } // Must NOT include CAA (not in zone). if got[dns.TypeCAA] { t.Errorf("apex unexpectedly includes CAA: %v", owner[apex]) } // Union should match the apex set (single owner). if !reflect.DeepEqual(owner[apex], union) { t.Errorf("union %v != apex %v", union, owner[apex]) } } func TestResolveQTypes_UnknownOwnerFallback(t *testing.T) { apex := "example.com." unknown := "www.example.com." names := []string{apex, unknown} zone := map[string]any{ "services": map[string]any{ // only apex services "": []any{ map[string]any{ "_svctype": "abstract.Origin", "_domain": "example.com", "Service": map[string]any{ "soa": map[string]any{ "Hdr": map[string]any{ "Name": "example.com.", "Rrtype": float64(dns.TypeSOA), }, }, }, }, }, }, } opts := sdk.CheckerOptions{"zone": zone} owner, _, err := resolveQTypes(opts, "", apex, names) if err != nil { t.Fatalf("err: %v", err) } wantUnknown := []uint16{dns.TypeA, dns.TypeAAAA} if !reflect.DeepEqual(owner[unknown], wantUnknown) { t.Errorf("unknown owner types = %v, want %v", owner[unknown], wantUnknown) } } func TestResolveQTypes_InvalidExplicit(t *testing.T) { _, _, err := resolveQTypes(sdk.CheckerOptions{}, "nope,bogus", "example.com.", []string{"example.com."}) if err == nil { t.Fatalf("expected error for invalid recordTypes") } }