Aufgaben-Python/courses/go/14_json_apis_und_middleware/test_aufgabe.go

101 lines
3.5 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
)
// 🧪 GO 14 TESTSUITE: REST JSON APIs & Middleware
func assertEquals[T comparable](actual, expected T, msg string) {
if actual != expected {
panic(fmt.Sprintf("❌ Test fehlgeschlagen: %s (Erwartet: '%v', Erhalten: '%v')", msg, expected, actual))
}
}
// TEST: TestCreateAndGetDevices - Prüft REST Endpoints
func TestCreateAndGetDevices() {
fmt.Println("=== RUN TestCreateAndGetDevices")
store := NewDeviceStore()
// 1. Create Device
payload := `{"name":"Switch-01","ip":"192.168.1.1","active":true}`
reqPost := httptest.NewRequest(http.MethodPost, "/devices", bytes.NewBufferString(payload))
recPost := httptest.NewRecorder()
store.CreateDeviceHandler(recPost, reqPost)
assertEquals(recPost.Code, http.StatusCreated, "CreateDeviceHandler muss Status 201 Created liefern")
var created Device
err := json.Unmarshal(recPost.Body.Bytes(), &created)
assertEquals(err, nil, "Response muss valides JSON sein")
assertEquals(created.ID, 1, "Erstes Device muss ID 1 erhalten")
assertEquals(created.Name, "Switch-01", "Name muss Switch-01 sein")
// 2. Get Devices
reqGet := httptest.NewRequest(http.MethodGet, "/devices", nil)
recGet := httptest.NewRecorder()
store.GetDevicesHandler(recGet, reqGet)
assertEquals(recGet.Code, http.StatusOK, "GetDevicesHandler muss Status 200 OK liefern")
var list []Device
errGet := json.Unmarshal(recGet.Body.Bytes(), &list)
assertEquals(errGet, nil, "Get-Response muss als Device-Slice parsbar sein")
assertEquals(len(list), 1, "Liste muss 1 Device enthalten")
fmt.Println("--- PASS: TestCreateAndGetDevices")
}
// TEST: TestAuthMiddleware - Prüft X-API-Key Validierung
func TestAuthMiddleware() {
fmt.Println("=== RUN TestAuthMiddleware")
protectedHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"success":true}`))
})
authMw := AuthMiddleware("valid-secret-key")
secured := authMw(protectedHandler)
// 1. Request OHNE Key -> 401
reqUnauthorized := httptest.NewRequest(http.MethodGet, "/secure", nil)
recUnauthorized := httptest.NewRecorder()
secured.ServeHTTP(recUnauthorized, reqUnauthorized)
assertEquals(recUnauthorized.Code, http.StatusUnauthorized, "Ohne Key muss 401 Unauthorized kommen")
// 2. Request MIT gültigem Key -> 200
reqAuthorized := httptest.NewRequest(http.MethodGet, "/secure", nil)
reqAuthorized.Header.Set("X-API-Key", "valid-secret-key")
recAuthorized := httptest.NewRecorder()
secured.ServeHTTP(recAuthorized, reqAuthorized)
assertEquals(recAuthorized.Code, http.StatusOK, "Mit gültigem Key muss 200 OK kommen")
fmt.Println("--- PASS: TestAuthMiddleware")
}
// TEST: TestRecoveryMiddleware - Prüft Panic-Abfang
func TestRecoveryMiddleware() {
fmt.Println("=== RUN TestRecoveryMiddleware")
panickingHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
panic("Simulierter kritischer Null-Pointer-Crash!")
})
recovered := RecoveryMiddleware(panickingHandler)
req := httptest.NewRequest(http.MethodGet, "/crash", nil)
rec := httptest.NewRecorder()
recovered.ServeHTTP(rec, req)
assertEquals(rec.Code, http.StatusInternalServerError, "Panic muss als 500 Internal Server Error abgefangen werden")
fmt.Println("--- PASS: TestRecoveryMiddleware")
}
func main() {
fmt.Println("🧪 Starte Go 14 Testsuite...")
TestCreateAndGetDevices()
TestAuthMiddleware()
TestRecoveryMiddleware()
fmt.Println("\n✅ Alle Tests in Go 14 erfolgreich bestanden!")
}