package internal import ( "context" "fmt" "io" "net/http" "net/http/httptest" "net/url" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) const testAPIKey = "secret" func setupTest(t *testing.T, handler http.HandlerFunc) *Client { t.Helper() server := httptest.NewServer(handler) client := NewClient(OAuthStaticAccessToken(server.Client(), testAPIKey)) client.HTTPClient = server.Client() client.baseURL, _ = url.Parse(server.URL) return client } func testHandler(method, filename string, statusCode int) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { if req.Method != method { http.Error(rw, fmt.Sprintf("unsupported method: %s", req.Method), http.StatusMethodNotAllowed) return } auth := req.Header.Get("Authorization") if auth != "Bearer "+testAPIKey { http.Error(rw, fmt.Sprintf("invalid API key: %s", auth), http.StatusUnauthorized) return } file, err := os.Open(filepath.Join("fixtures", filename)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } defer func() { _ = file.Close() }() rw.WriteHeader(statusCode) _, err = io.Copy(rw, file) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } } } func TestClient_GetDomains(t *testing.T) { client := setupTest(t, testHandler(http.MethodGet, "get_domains.json", http.StatusOK)) domains, err := client.GetDomains(context.Background()) require.NoError(t, err) expected := &Domains{ APIResponse: APIResponse{ Status: "200 OK", Info: "success", }, APICall: "get_domains", Subdomains: map[string]Subdomain{ "lego.home64.net": { Updates: 0, Wildcard: 1, DomainUpdateHash: "Dr4l6jFVgkXITqZPEyMHLNsGAfwoSu9v", Records: []Record{ { RecordID: 50665, Content: "2606:2800:220:1:248:1893:25c8:1946", TTL: 60, Type: "AAAA", Prefix: "", LastUpdate: "2023-07-19 13:18:59", RecordKey: "MTA0YzdmMWVjYTFiNDBmZjYwMTU0OGUy", }, }, }, "lego.ipv64.net": { Updates: 0, Wildcard: 1, DomainUpdateHash: "Dr4l6jFVgkXITqZPEyMHLNsGAfwoSu9v", Records: []Record{ { RecordID: 50664, Content: "2606:2800:220:1:248:1893:25c8:1946", TTL: 60, Type: "AAAA", Prefix: "", LastUpdate: "2023-07-19 13:18:59", RecordKey: "ZDMxOWUxMjZjOTk5MmQ3N2M3ODc4NjJj", }, }, }, }, } assert.Equal(t, expected, domains) } func TestClient_GetDomains_error(t *testing.T) { client := setupTest(t, testHandler(http.MethodGet, "error.json", http.StatusUnauthorized)) domains, err := client.GetDomains(context.Background()) require.Error(t, err) require.Nil(t, domains) } func TestClient_AddRecord(t *testing.T) { client := setupTest(t, testHandler(http.MethodPost, "add_record.json", http.StatusCreated)) err := client.AddRecord(context.Background(), "lego.ipv64.net", "_acme-challenge", "TXT", "value") require.NoError(t, err) } func TestClient_AddRecord_error(t *testing.T) { client := setupTest(t, testHandler(http.MethodPost, "add_record-error.json", http.StatusBadRequest)) err := client.AddRecord(context.Background(), "lego.ipv64.net", "_acme-challenge", "TXT", "value") require.Error(t, err) } func TestClient_DeleteRecord(t *testing.T) { client := setupTest(t, testHandler(http.MethodDelete, "del_record.json", http.StatusAccepted)) err := client.DeleteRecord(context.Background(), "lego.ipv64.net", "_acme-challenge", "TXT", "value") require.NoError(t, err) } func TestClient_DeleteRecord_error(t *testing.T) { client := setupTest(t, testHandler(http.MethodDelete, "del_record-error.json", http.StatusBadRequest)) err := client.DeleteRecord(context.Background(), "lego.ipv64.net", "_acme-challenge", "TXT", "value") require.Error(t, err) }