package hetzner_test import ( "context" "encoding/json" "io" "net/http" "net/http/httptest" "strings" "testing" "git.cloonar.com/cloonar/updns/internal/provider/hetzner" ) func TestUpdateRecordFullAPILifecycle(t *testing.T) { domain := "test.example.com" ip := "1.2.3.4" zoneName := "example.com" zoneID := "zone-123" recID := "rec-456" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case r.Method == http.MethodGet && r.URL.Path == "/zones": // Query zones by name resp := map[string]interface{}{ "zones": []map[string]string{{"id": zoneID, "name": zoneName}}, } json.NewEncoder(w).Encode(resp) case r.Method == http.MethodGet && r.URL.Path == "/records": // Query records by zone_id resp := map[string]interface{}{ "records": []map[string]string{{"id": recID, "name": domain, "value": "0.0.0.0", "type": "A"}}, } json.NewEncoder(w).Encode(resp) case r.Method == http.MethodPut && r.URL.Path == "/records/"+recID: // Validate update payload body, _ := io.ReadAll(r.Body) var payload map[string]string json.Unmarshal(body, &payload) if payload["value"] != ip { t.Errorf("expected update value %s, got %s", ip, payload["value"]) } w.WriteHeader(http.StatusOK) default: http.Error(w, "not found", http.StatusNotFound) } })) defer ts.Close() provider := hetzner.NewProviderWithURL("token", ts.URL) if err := provider.UpdateRecord(context.Background(), domain, ip); err != nil { t.Fatalf("full API lifecycle failed: %v", err) } } func TestUpdateRecordZoneNotFound(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]interface{}{"zones": []map[string]string{}}) })) defer ts.Close() provider := hetzner.NewProviderWithURL("token", ts.URL) err := provider.UpdateRecord(context.Background(), "nozone.example", "1.1.1.1") if err == nil || !strings.Contains(err.Error(), "zone example not found") { t.Fatalf("expected zone not found error, got %v", err) } } func TestUpdateRecordRecordNotFound(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/zones": json.NewEncoder(w).Encode(map[string]interface{}{ "zones": []map[string]string{{"id": "z", "name": "example.com"}}, }) case "/records": json.NewEncoder(w).Encode(map[string]interface{}{"records": []map[string]string{}}) default: http.Error(w, "not found", http.StatusNotFound) } })) defer ts.Close() provider := hetzner.NewProviderWithURL("token", ts.URL) err := provider.UpdateRecord(context.Background(), "missing.example.com", "1.1.1.1") if err == nil || !strings.Contains(err.Error(), "record missing.example.com not found") { t.Fatalf("expected record not found error, got %v", err) } }