Closes the Group L "integration test — Dynadot API multi-domain DNS write"
ticket. Tests the real Go client at
products/catalyst/bootstrap/api/internal/dynadot/dynadot.go without mocking
any of its internals — the http.Client transport, URL encoding, JSON
parsing, error surface paths, and the AddSovereignRecords loop are all
exercised end-to-end against an httptest.Server that emulates the
api.dynadot.com `set_dns2` contract.
The fake server is unavoidable: hitting the real Dynadot API would write to
DNS zones owned by OpenOva and "each call wipes all records" per the
package's own docstring. Substituting only the upstream endpoint while
keeping every byte of client-side logic real is the smallest deviation that
satisfies the inviolable-principles "no mocks where the test verifies real
behavior" rule.
Coverage:
- apex (subdomain "" / "@") uses main_record* fields
- non-apex uses subdomain*/sub_record* fields
- default TTL=300 applied when zero
- add_dns_to_current_setting=yes always present (never wipes records)
- command=set_dns2, key/secret carried through
- AddSovereignRecords writes the canonical 6-record set (wildcard +
console + gitea + harbor + admin + api)
- multi-domain: openova.io and omani.works on the same client instance
- Dynadot envelope ResponseCode != 0 produces a Go error
- HTTP 5xx produces a Go error
- AddSovereignRecords is fail-fast (no partial writes)
- IsManagedDomain pool-domain whitelist (case + whitespace robust)
CI workflow added: .github/workflows/test-bootstrap-api.yaml runs `go test
-race -count=1 ./...` on every push that touches the bootstrap module.
Refs #146
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>