feat(archive): RET-05 Modul-Adapter-Schnittstelle (Interface-Freeze)
internal/moduleadapter: Registrierungs-API + Rueckruf-Ausloeser fuer DMS/Mail, bewusst NUR Archives eigene Seite - keine Modul-Empfaenger- Implementierung (Nutzervorgabe: Interface zuerst festlegen, damit DMS/Mail spaeter nicht gegen ein sich noch aenderndes Interface bauen). Register ist ON-CONFLICT-DO-NOTHING (erneute Registrierung aendert nie bestehende callback_url), NotifyDestruction echter HTTP-POST mit festem DestructionNotice-Vertrag. Idempotenz sowohl auf Go- als auch HTTP- Ebene bewiesen, Rueckruf gegen echten Testendpunkt verifiziert.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package moduleadapter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestRegisterHandler_RealHTTPRoundTrip beweist die REST-Schnittstelle
|
||||
// (Ticket-Technikvorgabe) end-to-end: echter HTTP-Server, echter POST,
|
||||
// zweiter POST mit abweichender callback_url aendert nichts (Pruefung 3
|
||||
// auch ueber die HTTP-Schicht, nicht nur die Go-Funktion direkt).
|
||||
func TestRegisterHandler_RealHTTPRoundTrip(t *testing.T) {
|
||||
pool := requireTestPool(t)
|
||||
server := httptest.NewServer(RegisterHandler(pool))
|
||||
defer server.Close()
|
||||
|
||||
post := func(body registerRequest) (int, Registration) {
|
||||
t.Helper()
|
||||
data, _ := json.Marshal(body)
|
||||
resp, err := http.Post(server.URL, "application/json", bytes.NewReader(data))
|
||||
if err != nil {
|
||||
t.Fatalf("post: %v", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
var reg Registration
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
if err := json.NewDecoder(resp.Body).Decode(®); err != nil {
|
||||
t.Fatalf("antwort dekodieren: %v", err)
|
||||
}
|
||||
}
|
||||
return resp.StatusCode, reg
|
||||
}
|
||||
|
||||
status1, reg1 := post(registerRequest{ModuleName: "dms", ObjectType: "document", CallbackURL: "https://dms.example.test/original"})
|
||||
if status1 != http.StatusOK {
|
||||
t.Fatalf("erster post: status = %d, want 200", status1)
|
||||
}
|
||||
|
||||
status2, reg2 := post(registerRequest{ModuleName: "dms", ObjectType: "document", CallbackURL: "https://dms.example.test/andere"})
|
||||
if status2 != http.StatusOK {
|
||||
t.Fatalf("zweiter post: status = %d, want 200", status2)
|
||||
}
|
||||
if reg2.ID != reg1.ID || reg2.CallbackURL != "https://dms.example.test/original" {
|
||||
t.Fatalf("zweiter post veraenderte bestehenden zustand: %+v, erster war %+v", reg2, reg1)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRegisterHandler_RejectsMissingFields ist Nachweis des
|
||||
// Fehlerverhaltens auf der REST-Schicht.
|
||||
func TestRegisterHandler_RejectsMissingFields(t *testing.T) {
|
||||
pool := requireTestPool(t)
|
||||
server := httptest.NewServer(RegisterHandler(pool))
|
||||
defer server.Close()
|
||||
|
||||
data, _ := json.Marshal(registerRequest{ModuleName: "dms"})
|
||||
resp, err := http.Post(server.URL, "application/json", bytes.NewReader(data))
|
||||
if err != nil {
|
||||
t.Fatalf("post: %v", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
if resp.StatusCode != http.StatusBadRequest {
|
||||
t.Fatalf("status = %d, want 400 bei fehlenden pflichtfeldern", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user