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 apiKey = "secret" func setupTest(t *testing.T) (*Client, *http.ServeMux) { t.Helper() mux := http.NewServeMux() server := httptest.NewServer(mux) t.Cleanup(server.Close) client := NewClient(apiKey) client.baseURL, _ = url.Parse(server.URL) return client, mux } func testHandler(filename string, method 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 } username, key, ok := req.BasicAuth() if username != "api" || key != apiKey || !ok { http.Error(rw, http.StatusText(http.StatusUnauthorized), 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, mux := setupTest(t) mux.HandleFunc("/domains.json", testHandler("get-domains.json", http.MethodGet, http.StatusOK)) domains, err := client.GetDomains(context.Background()) require.NoError(t, err) expected := []Domain{{ ID: 123, UnicodeFqdn: "example.com", Domain: "example", TLD: "com", Status: "ok", }} assert.Equal(t, expected, domains) } func TestClient_GetDomains_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains.json", testHandler("error.json", http.MethodGet, http.StatusBadRequest)) _, err := client.GetDomains(context.Background()) require.EqualError(t, err, "[status code: 400] status: invalid_resource, details: name: [muss ausgefüllt werden]") } func TestClient_GetRecords(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records.json", testHandler("get-records.json", http.MethodGet, http.StatusOK)) records, err := client.GetRecords(context.Background(), 123) require.NoError(t, err) expected := []Record{ { ID: 1234, Content: "ns1.lima-city.de", Name: "example.com", TTL: 36000, Type: "NS", }, { ID: 5678, Content: `"foobar"`, Name: "_acme-challenge.example.com", TTL: 36000, Type: "TXT", }, } assert.Equal(t, expected, records) } func TestClient_GetRecords_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records.json", testHandler("error.json", http.MethodGet, http.StatusBadRequest)) _, err := client.GetRecords(context.Background(), 123) require.EqualError(t, err, "[status code: 400] status: invalid_resource, details: name: [muss ausgefüllt werden]") } func TestClient_AddRecord(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records.json", testHandler("ok.json", http.MethodPost, http.StatusOK)) record := Record{ Name: "foo", Content: "bar", TTL: 12, Type: "TXT", } err := client.AddRecord(context.Background(), 123, record) require.NoError(t, err) } func TestClient_AddRecord_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records.json", testHandler("error.json", http.MethodPost, http.StatusBadRequest)) record := Record{ Name: "foo", Content: "bar", TTL: 12, Type: "TXT", } err := client.AddRecord(context.Background(), 123, record) require.EqualError(t, err, "[status code: 400] status: invalid_resource, details: name: [muss ausgefüllt werden]") } func TestClient_UpdateRecord(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records/456", testHandler("ok.json", http.MethodPut, http.StatusOK)) err := client.UpdateRecord(context.Background(), 123, 456, Record{}) require.NoError(t, err) } func TestClient_UpdateRecord_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records/456", testHandler("error.json", http.MethodPut, http.StatusBadRequest)) err := client.UpdateRecord(context.Background(), 123, 456, Record{}) require.EqualError(t, err, "[status code: 400] status: invalid_resource, details: name: [muss ausgefüllt werden]") } func TestClient_DeleteRecord(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records/456", testHandler("ok.json", http.MethodDelete, http.StatusOK)) err := client.DeleteRecord(context.Background(), 123, 456) require.NoError(t, err) } func TestClient_DeleteRecord_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/domains/123/records/456", testHandler("error.json", http.MethodDelete, http.StatusBadRequest)) err := client.DeleteRecord(context.Background(), 123, 456) require.EqualError(t, err, "[status code: 400] status: invalid_resource, details: name: [muss ausgefüllt werden]") }