meldestelle/docs/04_Agents/Besprechung_2026-04-03/Postman_Tests_Dokumentation.md

24 KiB

type status owner last_update
Note REDIRECT Curator 2026-04-03

🧪 Postman Tests — Vollständige Dokumentation (verschoben)

Diese ausführliche Arbeitsversion wurde konsolidiert und in das zentrale Runbook für Betriebsanleitungen überführt.

Aktuelle Fassung:

  • docs/07_Infrastructure/runbooks/POSTMAN_API_Tests_Runbook.md

Archiv:

  • Zusammenfassung im Archiv: docs/04_Agents/_archive/Postman_Tests_Dokumentation_2026-04-03.md

Hinweis: Diese Datei bleibt als Weiterleitung bestehen, damit bestehende Links nicht brechen.


2.4 Swagger UI

Feld Wert
Methode GET
URL {{baseUrl}}/swagger
Auth Keine

Erwartete Antwort: 200 OK — Swagger HTML-Interface
Tipp: Im Browser öffnen für interaktive API-Erkundung.


3. Ping Service

Zweck: Funktionsfähigkeit des Ping-Service testen, Circuit Breaker und Sync-Funktionen validieren.
Direkt-URL: {{pingUrl}} = http://localhost:8082
Via Gateway: {{baseUrl}} = http://localhost:8081


3.1 Simple Ping

Feld Wert
Methode GET
URL {{pingUrl}}/ping/simple
Auth Keine

Erwartete Antwort: 200 OK

{
  "message": "pong",
  "timestamp": "2026-04-03T14:00:00+02:00",
  "service": "ping-service",
  "status": "simple"
}

Wozu: Einfachster Smoke-Test — bestätigt dass der Service läuft und die DB erreichbar ist.


3.2 Simple Ping via Gateway

Feld Wert
Methode GET
URL {{baseUrl}}/ping/simple
Auth Keine

Erwartete Antwort: 200 OK (identisch wie 3.1)
Wozu: Bestätigt dass das Gateway den Ping-Service korrekt routet (Service Discovery via Consul).


3.3 Enhanced Ping (mit Circuit Breaker)

Feld Wert
Methode GET
URL {{pingUrl}}/ping/enhanced
Auth Keine
Query-Param simulate=false (Standard)

Erwartete Antwort: 200 OK

{
  "message": "enhanced pong",
  "timestamp": "...",
  "service": "ping-service",
  "status": "enhanced",
  "circuitBreakerStatus": "CLOSED"
}

Wozu: Bestätigt dass Resilience4j Circuit Breaker korrekt konfiguriert ist.


3.4 Enhanced Ping — Fehler simulieren

Feld Wert
Methode GET
URL {{pingUrl}}/ping/enhanced?simulate=true
Auth Keine

Erwartete Antwort: 200 OK mit Fallback-Response (kein 500-Fehler!)

{
  "message": "fallback response",
  "status": "fallback",
  "circuitBreakerStatus": "OPEN",
  "error": "..."
}

Wozu: Bestätigt dass der Circuit Breaker Fallback greift (60% simulierte Fehlerrate). Der Service antwortet trotz Fehler mit einem sinnvollen Fallback.
Mehrfach ausführen: Nach ~5 Anfragen mit simulate=true öffnet der Circuit Breaker.


3.5 Public Ping (kein Auth erforderlich)

Feld Wert
Methode GET
URL {{pingUrl}}/ping/public
Auth Keine

Erwartete Antwort: 200 OK
Wozu: Bestätigt dass der /ping/public-Endpunkt ohne JWT-Token erreichbar ist (Security-Konfiguration).


3.6 Secure Ping (Auth erforderlich)

Feld Wert
Methode GET
URL {{pingUrl}}/ping/secure
Header Authorization: Bearer {{authToken}}

Mit gültigem Token: 200 OK
Ohne Token: 401 Unauthorized
Wozu: Bestätigt dass JWT-Authentifizierung korrekt erzwungen wird.


3.7 Sync Pings (seit Timestamp)

Feld Wert
Methode GET
URL {{pingUrl}}/ping/sync
Auth Keine
Query-Param since=0 (alle Pings seit Epoch)

Erwartete Antwort: 200 OK

[
  {
    "id": "...",
    "message": "pong",
    "timestamp": "...",
    "lamportClock": 1
  }
]

Wozu: Testet den LAN-Sync-Endpunkt (Lamport-Uhren, Event-Sourcing Light). since ist ein Unix-Timestamp in Millisekunden.


3.8 Ping Service Health

Feld Wert
Methode GET
URL {{pingUrl}}/ping/health
Auth Keine

Erwartete Antwort: 200 OK

{
  "status": "up",
  "timestamp": "...",
  "service": "ping-service",
  "healthy": true
}

4. Authentication Context

Zweck: Benutzer-Registrierung, Login und Profilverwaltung über Keycloak testen.
Reihenfolge: Zuerst registrieren → dann einloggen → Token in {{authToken}} speichern.


4.1 User Registration

Feld Wert
Methode POST
URL {{baseUrl}}/auth/register
Header Content-Type: application/json

Request Body:

{
  "email": "test@example.com",
  "password": "SecurePassword123!",
  "firstName": "Test",
  "lastName": "User",
  "phoneNumber": "+43123456789"
}

Erwartete Antwort: 201 Created

{
  "userId": "uuid-...",
  "email": "test@example.com",
  "message": "Registrierung erfolgreich"
}

Wozu: Legt einen neuen Benutzer in Keycloak an.


4.2 User Login

Feld Wert
Methode POST
URL {{baseUrl}}/auth/login
Header Content-Type: application/json

Request Body:

{
  "email": "test@example.com",
  "password": "SecurePassword123!"
}

Erwartete Antwort: 200 OK

{
  "accessToken": "eyJhbGci...",
  "refreshToken": "...",
  "expiresIn": 300
}

Tipp: Postman-Test-Script einfügen um Token automatisch zu speichern:

var json = pm.response.json();
pm.environment.set("authToken", json.accessToken);

4.3 Get User Profile

Feld Wert
Methode GET
URL {{baseUrl}}/auth/profile
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 200 OK

{
  "userId": "...",
  "email": "test@example.com",
  "firstName": "Test",
  "lastName": "User"
}

4.4 Update User Profile

Feld Wert
Methode PUT
URL {{baseUrl}}/auth/profile
Header Content-Type: application/json
Header Authorization: Bearer {{authToken}}

Request Body:

{
  "firstName": "Updated",
  "lastName": "User",
  "phoneNumber": "+43987654321"
}

Erwartete Antwort: 200 OK — aktualisierte Profildaten


4.5 Change Password

Feld Wert
Methode POST
URL {{baseUrl}}/auth/change-password
Header Content-Type: application/json
Header Authorization: Bearer {{authToken}}

Request Body:

{
  "currentPassword": "SecurePassword123!",
  "newPassword": "NewSecurePassword456!"
}

Erwartete Antwort: 200 OK
Fehlerfall (falsches Passwort): 400 Bad Request


5. Master Data: Countries

Zweck: Länderstammdaten verwalten. Diese sind Voraussetzung für Pferde- und Reiter-Datensätze.
Basis-URL: {{baseUrl}}/api/masterdata/countries
Hinweis: GET-Endpunkte sind ohne Auth zugänglich; POST/PUT/DELETE benötigen {{authToken}}.


5.1 Get All Countries

Feld Wert
Methode GET
URL {{baseUrl}}/api/masterdata/countries
Auth Keine

Erwartete Antwort: 200 OK — Array aller Länder (inkl. inaktive)


5.2 Get Active Countries

Feld Wert
Methode GET
URL {{baseUrl}}/api/masterdata/countries/active
Auth Keine

Erwartete Antwort: 200 OK — Nur Länder mit istAktiv: true
Wozu: Für Dropdown-Listen in der Desktop-App (nur aktive Länder anzeigen).


5.3 Get Country by ID

Feld Wert
Methode GET
URL {{baseUrl}}/api/masterdata/countries/{{countryId}}
Auth Keine

Erwartete Antwort: 200 OK — Einzelnes Land
Fehlerfall: 404 Not Found


5.4 Get Country by ISO Code

Feld Wert
Methode GET
URL {{baseUrl}}/api/masterdata/countries/iso/AT
Auth Keine

Erwartete Antwort: 200 OK

{
  "id": "...",
  "isoAlpha2Code": "AT",
  "nameDeutsch": "Österreich",
  "istEuMitglied": true,
  "istAktiv": true
}

Wozu: Österreich ist das primäre Land — dieser Test prüft ob die Stammdaten korrekt befüllt sind.


5.5 Create Country

Feld Wert
Methode POST
URL {{baseUrl}}/api/masterdata/countries
Header Content-Type: application/json
Header Authorization: Bearer {{authToken}}

Request Body:

{
  "isoAlpha2Code": "TS",
  "isoAlpha3Code": "TST",
  "isoNumerischerCode": "999",
  "nameDeutsch": "Testland",
  "nameEnglisch": "Testland",
  "istEuMitglied": false,
  "istEwrMitglied": false,
  "istAktiv": true,
  "sortierReihenfolge": 999
}

Erwartete Antwort: 201 Created

Tipp: countryId aus der Antwort in Environment-Variable speichern:

var json = pm.response.json();
pm.environment.set("countryId", json.id);

5.6 Update Country

Feld Wert
Methode PUT
URL {{baseUrl}}/api/masterdata/countries/{{countryId}}
Header Content-Type: application/json
Header Authorization: Bearer {{authToken}}

Request Body:

{
  "isoAlpha2Code": "TS",
  "isoAlpha3Code": "TST",
  "isoNumerischerCode": "999",
  "nameDeutsch": "Updated Testland",
  "nameEnglisch": "Updated Testland",
  "istEuMitglied": false,
  "istEwrMitglied": false,
  "istAktiv": true,
  "sortierReihenfolge": 999
}

Erwartete Antwort: 200 OK


5.7 Delete Country

Feld Wert
Methode DELETE
URL {{baseUrl}}/api/masterdata/countries/{{countryId}}
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 204 No Content
Fehlerfall (nicht gefunden): 404 Not Found


6. Horse Registry (Pferde)

Zweck: Pferde-Stammdaten verwalten (CRUD).
⚠️ Hinweis Tabellen-Name: In der Datenbank heißt die Tabelle horse (englisch), nicht pferd.
Basis-URL: {{baseUrl}}/api/horses


6.1 Get All Horses

Feld Wert
Methode GET
URL {{baseUrl}}/api/horses
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 200 OK — Array aller Pferde
Nach ZNS-Import: Hier erscheinen alle importierten Pferde.


6.2 Get Active Horses

Feld Wert
Methode GET
URL {{baseUrl}}/api/horses/active
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 200 OK — Nur Pferde mit istAktiv: true


6.3 Get Horse by ID

Feld Wert
Methode GET
URL {{baseUrl}}/api/horses/{{horseId}}
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 200 OK

{
  "id": "uuid-...",
  "pferdeName": "Amadeus",
  "geschlecht": "WALLACH",
  "geburtsdatum": "2020-05-15",
  "rasse": "Warmblut",
  "farbe": "Braun",
  "stockmass": 165,
  "istAktiv": true
}

6.4 Search Horses by Name

Feld Wert
Methode GET
URL {{baseUrl}}/api/horses/search
Query name=Test (Suchbegriff), limit=10 (max.)
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 200 OK — gefilterte Pferde-Liste
Wozu: Echtzeit-Suche in der Desktop-App. Testen mit einem Namen aus dem ZNS-Import.


6.5 Get Horses by Owner

Feld Wert
Methode GET
URL {{baseUrl}}/api/horses/owner/{{ownerId}}
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 200 OK — alle Pferde eines bestimmten Besitzers


6.6 Create Horse

Feld Wert
Methode POST
URL {{baseUrl}}/api/horses
Header Content-Type: application/json
Header Authorization: Bearer {{authToken}}

Request Body:

{
  "pferdeName": "Test Horse",
  "geschlecht": "WALLACH",
  "geburtsdatum": "2020-05-15",
  "rasse": "Warmblut",
  "farbe": "Braun",
  "zuechterName": "Test Breeder",
  "stockmass": 165,
  "istAktiv": true,
  "bemerkungen": "Test horse for API demonstration"
}

Gültige Werte für geschlecht: WALLACH, STUTE, HENGST

Erwartete Antwort: 201 Created

Tipp: horseId automatisch speichern:

var json = pm.response.json();
pm.environment.set("horseId", json.id);

6.7 Update Horse

Feld Wert
Methode PUT
URL {{baseUrl}}/api/horses/{{horseId}}
Header Content-Type: application/json
Header Authorization: Bearer {{authToken}}

Request Body:

{
  "pferdeName": "Updated Test Horse",
  "geschlecht": "WALLACH",
  "geburtsdatum": "2020-05-15",
  "rasse": "Warmblut",
  "farbe": "Dunkelbraun",
  "zuechterName": "Updated Test Breeder",
  "stockmass": 167,
  "istAktiv": true,
  "bemerkungen": "Updated test horse for API demonstration"
}

Erwartete Antwort: 200 OK


6.8 Delete Horse

Feld Wert
Methode DELETE
URL {{baseUrl}}/api/horses/{{horseId}}
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 204 No Content


6.9 Batch Delete Horses

Feld Wert
Methode DELETE
URL {{baseUrl}}/api/horses/batch
Header Content-Type: application/json
Header Authorization: Bearer {{authToken}}

Request Body:

{
  "horseIds": ["{{horseId1}}", "{{horseId2}}"],
  "forceDelete": false
}

forceDelete: false → Nur löschen wenn keine Abhängigkeiten vorhanden
forceDelete: true → Auch bei Abhängigkeiten löschen (⚠️ Vorsicht!)

Erwartete Antwort: 200 OK


6.10 Get Horse Statistics

Feld Wert
Methode GET
URL {{baseUrl}}/api/horses/stats
Header Authorization: Bearer {{authToken}}

Erwartete Antwort: 200 OK

{
  "total": 42,
  "active": 38,
  "inactive": 4,
  "byGeschlecht": {
    "WALLACH": 20,
    "STUTE": 18,
    "HENGST": 4
  }
}

Wozu: Schnelle Übersicht über den Datenbestand nach dem ZNS-Import.


7. ZNS Import Service

Zweck: ZNS-Daten (Reiter, Pferde, Vereine, Funktionäre) aus einer .zip/.dat-Datei importieren.
Direkt-URL: {{znsUrl}} = http://localhost:8095
Basis-Pfad: /api/v1/import/zns


7.1 ZNS Import starten

Feld Wert
Methode POST
URL {{znsUrl}}/api/v1/import/zns
Body-Typ form-data
Key file (Type: File)
Value ZNS-Datei auswählen (.zip oder .dat)

Schritt-für-Schritt in Postman:

  1. Methode: POST
  2. URL: http://localhost:8095/api/v1/import/zns
  3. Tab Bodyform-data
  4. Key: file → Typ auf File umstellen (Dropdown neben dem Key-Feld)
  5. Value: ZNS-Datei auswählen
  6. Send klicken

Erwartete Antwort: 202 Accepted

{
  "jobId": "abc-123-def-456",
  "status": "STARTED",
  "message": "Import gestartet",
  "startedAt": "2026-04-03T14:00:00+02:00"
}

Tipp: jobId automatisch speichern:

var json = pm.response.json();
pm.environment.set("znsJobId", json.jobId);

7.2 ZNS Import-Status abfragen

Feld Wert
Methode GET
URL {{znsUrl}}/api/v1/import/zns/{{znsJobId}}/status
Auth Keine

Antwort während Import: 200 OK

{
  "jobId": "abc-123-def-456",
  "status": "IN_PROGRESS",
  "processedRecords": 150,
  "totalRecords": 500,
  "progressPercent": 30,
  "startedAt": "2026-04-03T14:00:00+02:00"
}

Antwort nach Abschluss: 200 OK

{
  "jobId": "abc-123-def-456",
  "status": "COMPLETED",
  "processedRecords": 500,
  "totalRecords": 500,
  "progressPercent": 100,
  "importedReiter": 200,
  "importedPferde": 180,
  "importedVereine": 30,
  "importedFunktionaere": 90,
  "startedAt": "2026-04-03T14:00:00+02:00",
  "completedAt": "2026-04-03T14:01:30+02:00"
}

Mögliche Status-Werte:

Status Bedeutung
STARTED Job wurde angenommen, noch nicht aktiv
IN_PROGRESS Import läuft gerade
COMPLETED Import erfolgreich abgeschlossen
FAILED Import fehlgeschlagen (Fehlerdetails)

Wozu: Status pollen bis COMPLETED — dann Daten in pgAdmin oder Desktop-App prüfen.


7.3 ZNS Import Health-Check

Feld Wert
Methode GET
URL {{znsUrl}}/actuator/health
Auth Keine

Erwartete Antwort: 200 OK

{
  "status": "UP",
  "components": {
    "db": { "status": "UP" },
    "diskSpace": { "status": "UP" }
  }
}

⚠️ Consul-Check: Nach dem Neustart des ZNS-Service sollte er im Consul-UI unter http://localhost:8500 unter dem Namen zns-import-service erscheinen.


8. Empfohlene Test-Reihenfolge

Schnell-Smoke-Test (5 Minuten)

1. GET  {{pingUrl}}/ping/simple          → "pong" ✓
2. GET  {{baseUrl}}/health               → "UP" ✓
3. GET  {{znsUrl}}/actuator/health       → "UP" ✓
4. GET  {{baseUrl}}/api/masterdata/countries/iso/AT  → Österreich ✓

Vollständiger Integrations-Test (heute, ZNS-Import)

1.  GET  {{pingUrl}}/ping/simple                    → Smoke-Test
2.  GET  {{pingUrl}}/ping/enhanced                  → Circuit Breaker CLOSED
3.  GET  {{pingUrl}}/ping/enhanced?simulate=true    → Fallback greift
4.  POST {{baseUrl}}/auth/login                     → Token speichern
5.  GET  {{baseUrl}}/api/masterdata/countries/iso/AT → Stammdaten vorhanden
6.  GET  {{baseUrl}}/api/horses                     → (leer vor Import)
7.  GET  {{znsUrl}}/actuator/health                 → ZNS bereit
8.  POST {{znsUrl}}/api/v1/import/zns               → ZNS-Datei hochladen → jobId speichern
9.  GET  {{znsUrl}}/api/v1/import/zns/{{znsJobId}}/status  → Status pollen bis COMPLETED
10. GET  {{baseUrl}}/api/horses                     → Pferde jetzt befüllt ✓
11. GET  {{baseUrl}}/api/horses/stats               → Statistiken prüfen
12. GET  {{baseUrl}}/api/horses/search?name=...     → Suche testen

Anhang: Alle URLs auf einen Blick

Service URL Verwendung
API-Gateway http://localhost:8081 Haupt-Einstiegspunkt
Ping (direkt) http://localhost:8082 Ping-Endpunkte direkt
ZNS-Import http://localhost:8095 Import-Endpunkte
Keycloak Admin http://localhost:8180 Auth-Verwaltung
Consul UI http://localhost:8500 Service-Discovery prüfen
Zipkin http://localhost:9411 Traces nachverfolgen
pgAdmin http://localhost:8888 DB-Inhalte prüfen
Mailpit http://localhost:8025 E-Mail-Mock