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" ) func TestClient_GetZone(t *testing.T) { client := setupTest(t, "/anycast/nicmanager-anycastdns4.net", testHandler(http.MethodGet, http.StatusOK, "zone.json")) zone, err := client.GetZone(context.Background(), "nicmanager-anycastdns4.net") require.NoError(t, err) expected := &Zone{ Name: "nicmanager-anycastdns4.net", Active: true, Records: []Record{ { ID: 186, Name: "nicmanager-anycastdns4.net", Type: "A", Content: "123.123.123.123", TTL: 3600, }, }, } assert.Equal(t, expected, zone) } func TestClient_GetZone_error(t *testing.T) { client := setupTest(t, "/anycast/foo", testHandler(http.MethodGet, http.StatusNotFound, "error.json")) _, err := client.GetZone(context.Background(), "foo") require.Error(t, err) } func TestClient_AddRecord(t *testing.T) { client := setupTest(t, "/anycast/zonedomain.tld/records", testHandler(http.MethodPost, http.StatusAccepted, "error.json")) record := RecordCreateUpdate{ Type: "TXT", Name: "lego", Value: "content", TTL: 3600, } err := client.AddRecord(context.Background(), "zonedomain.tld", record) require.NoError(t, err) } func TestClient_AddRecord_error(t *testing.T) { client := setupTest(t, "/anycast/zonedomain.tld", testHandler(http.MethodPost, http.StatusUnauthorized, "error.json")) record := RecordCreateUpdate{ Type: "TXT", Name: "zonedomain.tld", Value: "content", TTL: 3600, } err := client.AddRecord(context.Background(), "zonedomain.tld", record) require.Error(t, err) } func TestClient_DeleteRecord(t *testing.T) { client := setupTest(t, "/anycast/zonedomain.tld/records/6", testHandler(http.MethodDelete, http.StatusAccepted, "error.json")) err := client.DeleteRecord(context.Background(), "zonedomain.tld", 6) require.NoError(t, err) } func TestClient_DeleteRecord_error(t *testing.T) { client := setupTest(t, "/anycast/zonedomain.tld/records/6", testHandler(http.MethodDelete, http.StatusNoContent, "")) err := client.DeleteRecord(context.Background(), "zonedomain.tld", 7) require.Error(t, err) } func setupTest(t *testing.T, path string, handler http.Handler) *Client { t.Helper() mux := http.NewServeMux() server := httptest.NewServer(mux) t.Cleanup(server.Close) mux.Handle(path, handler) opts := Options{ Login: "foo", Username: "bar", Password: "foo", OTP: "2hsn", } client := NewClient(opts) client.HTTPClient = server.Client() client.baseURL, _ = url.Parse(server.URL) return client } func testHandler(method string, statusCode int, filename string) http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { if req.Method != method { http.Error(rw, fmt.Sprintf(`{"message":"unsupported method: %s"}`, req.Method), http.StatusMethodNotAllowed) return } username, password, ok := req.BasicAuth() if !ok || username != "foo.bar" || password != "foo" { http.Error(rw, `{"message":"Unauthenticated"}`, http.StatusUnauthorized) return } rw.WriteHeader(statusCode) if statusCode == http.StatusNoContent { return } file, err := os.Open(filepath.Join("fixtures", filename)) if err != nil { http.Error(rw, fmt.Sprintf(`{"message":"%v"}`, err), http.StatusInternalServerError) return } defer func() { _ = file.Close() }() _, err = io.Copy(rw, file) if err != nil { http.Error(rw, fmt.Sprintf(`{"message":"%v"}`, err), http.StatusInternalServerError) return } } }