morz-infoboard/player/agent/internal/mqttheartbeat/heartbeat_test.go
Jesko Anschütz d0137179e5 Fuege MQTT-Heartbeat zum Agent hinzu (kein Broker konfiguriert = skip)
- neues Paket mqttheartbeat: Publisher mit paho, topic signage/screen/<id>/heartbeat,
  payload {screen_id, ts, status, server_connectivity}, auto-reconnect bei Ausfall
- MORZ_INFOBOARD_MQTT_BROKER leer (Standard) -> MQTT komplett uebersprungen
- app.emitHeartbeat() publiziert bei jedem Tick per MQTT wenn Broker konfiguriert,
  loggt Fehler und laeuft weiter (kein Stop bei MQTT-Ausfall)
- mqtt.Close() bei context.Done()
- MQTTBroker-Default von tcp://127.0.0.1:1883 auf "" geaendert
- erste externe Dep: github.com/eclipse/paho.mqtt.golang v1.5.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 20:54:12 +01:00

60 lines
1.7 KiB
Go

package mqttheartbeat
import (
"encoding/json"
"strings"
"testing"
"time"
)
func TestBuildPayloadContainsAllFields(t *testing.T) {
ts := time.Date(2026, 3, 22, 16, 9, 30, 0, time.UTC)
data, err := BuildPayload("info01-dev", "running", "online", ts)
if err != nil {
t.Fatalf("BuildPayload() error = %v", err)
}
var p struct {
ScreenID string `json:"screen_id"`
Timestamp string `json:"ts"`
Status string `json:"status"`
ServerConnectivity string `json:"server_connectivity"`
}
if err := json.Unmarshal(data, &p); err != nil {
t.Fatalf("Unmarshal() error = %v", err)
}
if got, want := p.ScreenID, "info01-dev"; got != want {
t.Errorf("screen_id = %q, want %q", got, want)
}
if got, want := p.Timestamp, "2026-03-22T16:09:30Z"; got != want {
t.Errorf("ts = %q, want %q", got, want)
}
if got, want := p.Status, "running"; got != want {
t.Errorf("status = %q, want %q", got, want)
}
if got, want := p.ServerConnectivity, "online"; got != want {
t.Errorf("server_connectivity = %q, want %q", got, want)
}
}
func TestBuildPayloadTimestampIsUTC(t *testing.T) {
loc := time.FixedZone("CET", 1*60*60)
ts := time.Date(2026, 3, 22, 17, 9, 30, 0, loc) // same moment, different zone
data, err := BuildPayload("screen-x", "running", "online", ts)
if err != nil {
t.Fatalf("BuildPayload() error = %v", err)
}
if !strings.Contains(string(data), "2026-03-22T16:09:30Z") {
t.Errorf("payload %s: expected UTC timestamp 2026-03-22T16:09:30Z", data)
}
}
func TestTopicFormat(t *testing.T) {
if got, want := Topic("info01-dev"), "signage/screen/info01-dev/heartbeat"; got != want {
t.Fatalf("Topic() = %q, want %q", got, want)
}
}