Files
mailgoserver/internal/dnspublish/digitalocean_test.go
T

99 lines
3.5 KiB
Go

package dnspublish
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
)
func TestDigitaloceanRelativeName(t *testing.T) {
cases := []struct{ fqdn, zone, want string }{
{"selector._domainkey.example.com", "example.com", "selector._domainkey"},
{"example.com", "example.com", "@"},
{"selector._domainkey.example.com.", "example.com.", "selector._domainkey"},
}
for _, c := range cases {
got, err := digitaloceanRelativeName(c.fqdn, c.zone)
if err != nil {
t.Fatalf("%s/%s: %v", c.fqdn, c.zone, err)
}
if got != c.want {
t.Errorf("digitaloceanRelativeName(%q, %q) = %q, want %q", c.fqdn, c.zone, got, c.want)
}
}
if _, err := digitaloceanRelativeName("selector._domainkey.other.com", "example.com"); err == nil {
t.Error("expected an error for a record outside the zone")
}
}
func TestSetTXTRecordDigitalOceanCreatesWhenNoneExists(t *testing.T) {
var gotMethod, gotPath string
var gotBody map[string]any
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/domains/example.com/records":
w.Write([]byte(`{"domain_records":[]}`))
case r.Method == http.MethodPost && r.URL.Path == "/domains/example.com/records":
gotMethod, gotPath = r.Method, r.URL.Path
body, _ := io.ReadAll(r.Body)
json.Unmarshal(body, &gotBody)
if got := r.Header.Get("Authorization"); got != "Bearer do-token" {
t.Errorf("Authorization header = %q, want Bearer do-token", got)
}
w.Write([]byte(`{"domain_record":{"id":1}}`))
default:
t.Errorf("unexpected request %s %s", r.Method, r.URL.String())
w.WriteHeader(http.StatusNotFound)
}
}))
defer srv.Close()
orig := DigitalOceanAPIBase
DigitalOceanAPIBase = srv.URL
defer func() { DigitalOceanAPIBase = orig }()
err := SetTXTRecord(Credentials{Provider: "digitalocean", ZoneName: "example.com", DigitalOceanAPIToken: "do-token"},
"selector._domainkey.example.com", `"v=DKIM1; k=rsa; p=abc"`)
if err != nil {
t.Fatal(err)
}
if gotMethod != http.MethodPost || gotPath != "/domains/example.com/records" {
t.Fatalf("expected a POST to create the record, got %s %s", gotMethod, gotPath)
}
if gotBody["name"] != "selector._domainkey" || gotBody["data"] != `"v=DKIM1; k=rsa; p=abc"` {
t.Fatalf("unexpected request body: %+v", gotBody)
}
}
func TestSetTXTRecordDigitalOceanUpdatesExisting(t *testing.T) {
var gotMethod, gotPath string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/domains/example.com/records":
w.Write([]byte(`{"domain_records":[{"id":42,"type":"TXT","name":"selector._domainkey"}]}`))
case r.Method == http.MethodPut && r.URL.Path == "/domains/example.com/records/42":
gotMethod, gotPath = r.Method, r.URL.Path
w.Write([]byte(`{"domain_record":{"id":42}}`))
default:
t.Errorf("unexpected request %s %s", r.Method, r.URL.String())
w.WriteHeader(http.StatusNotFound)
}
}))
defer srv.Close()
orig := DigitalOceanAPIBase
DigitalOceanAPIBase = srv.URL
defer func() { DigitalOceanAPIBase = orig }()
err := SetTXTRecord(Credentials{Provider: "digitalocean", ZoneName: "example.com", DigitalOceanAPIToken: "do-token"},
"selector._domainkey.example.com", `"v=DKIM1"`)
if err != nil {
t.Fatal(err)
}
if gotMethod != http.MethodPut || gotPath != "/domains/example.com/records/42" {
t.Fatalf("expected a PUT to update the existing record, got %s %s", gotMethod, gotPath)
}
}