morz-infoboard/player/agent/internal/statusreporter/reporter_test.go
Jesko Anschütz 6084712800 feat(mqtt): MQTT-Config per Heartbeat-Response vom Server an Agents übertragen
Server gibt bei POST /api/v1/player/status jetzt mqtt-Block zurück (broker,
username, password) wenn MORZ_INFOBOARD_MQTT_BROKER gesetzt ist. Agents
parsen die Response und verbinden sich bei Config-Änderung automatisch neu
(applyMQTTConfig mit Reconnect-Logik, thread-safe via Mutex).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 15:03:15 +01:00

94 lines
2.8 KiB
Go

package statusreporter
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestBuildPayloadFromSnapshot(t *testing.T) {
startedAt := time.Date(2026, 3, 22, 15, 59, 30, 0, time.UTC)
lastHeartbeatAt := time.Date(2026, 3, 22, 16, 0, 0, 0, time.UTC)
snapshot := Snapshot{
Status: "running",
ServerConnectivity: "online",
ScreenID: "info01-dev",
ServerBaseURL: "http://127.0.0.1:8080",
MQTTBroker: "tcp://127.0.0.1:1883",
HeartbeatEverySeconds: 30,
StartedAt: startedAt,
LastHeartbeatAt: lastHeartbeatAt,
}
payload := buildPayload(snapshot, lastHeartbeatAt)
if got, want := payload.ScreenID, "info01-dev"; got != want {
t.Fatalf("ScreenID = %q, want %q", got, want)
}
if got, want := payload.Timestamp, lastHeartbeatAt.Format(time.RFC3339); got != want {
t.Fatalf("Timestamp = %q, want %q", got, want)
}
if got, want := payload.StartedAt, startedAt.Format(time.RFC3339); got != want {
t.Fatalf("StartedAt = %q, want %q", got, want)
}
if got, want := payload.ServerConnectivity, "online"; got != want {
t.Fatalf("ServerConnectivity = %q, want %q", got, want)
}
if got, want := payload.LastHeartbeatAt, lastHeartbeatAt.Format(time.RFC3339); got != want {
t.Fatalf("LastHeartbeatAt = %q, want %q", got, want)
}
}
func TestReporterSendStatus(t *testing.T) {
var received statusPayload
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Method, http.MethodPost; got != want {
t.Fatalf("method = %s, want %s", got, want)
}
if got, want := r.URL.Path, "/api/v1/player/status"; got != want {
t.Fatalf("path = %s, want %s", got, want)
}
if err := json.NewDecoder(r.Body).Decode(&received); err != nil {
t.Fatalf("Decode() error = %v", err)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"accepted"}`))
}))
defer server.Close()
reporter := New(server.URL, server.Client(), func() time.Time {
return time.Date(2026, 3, 22, 16, 0, 0, 0, time.UTC)
})
_, err := reporter.Send(context.Background(), Snapshot{
Status: "running",
ServerConnectivity: "online",
ScreenID: "info01-dev",
ServerBaseURL: "http://127.0.0.1:8080",
MQTTBroker: "tcp://127.0.0.1:1883",
HeartbeatEverySeconds: 30,
StartedAt: time.Date(2026, 3, 22, 15, 59, 30, 0, time.UTC),
LastHeartbeatAt: time.Date(2026, 3, 22, 15, 59, 55, 0, time.UTC),
})
if err != nil {
t.Fatalf("Send() error = %v", err)
}
if got, want := received.ScreenID, "info01-dev"; got != want {
t.Fatalf("received.ScreenID = %q, want %q", got, want)
}
if got, want := received.ServerConnectivity, "online"; got != want {
t.Fatalf("received.ServerConnectivity = %q, want %q", got, want)
}
}