package health import ( "encoding/json" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestEventTypeIsKnown(t *testing.T) { for _, eventType := range AllEventTypes() { assert.Truef(t, eventType.IsKnown(), "expected %q known", eventType) } assert.False(t, EventType("").IsKnown()) assert.False(t, EventType("paused").IsKnown()) } func TestAllEventTypesCoverFrozenSet(t *testing.T) { assert.ElementsMatch(t, []EventType{ EventTypeContainerStarted, EventTypeContainerExited, EventTypeContainerOOM, EventTypeContainerDisappeared, EventTypeInspectUnhealthy, EventTypeProbeFailed, EventTypeProbeRecovered, }, AllEventTypes(), ) } func TestSnapshotStatusIsKnown(t *testing.T) { for _, status := range AllSnapshotStatuses() { assert.Truef(t, status.IsKnown(), "expected %q known", status) } assert.False(t, SnapshotStatus("").IsKnown()) assert.False(t, SnapshotStatus("starting").IsKnown()) assert.False(t, SnapshotStatus("probe_recovered").IsKnown(), "snapshot status must not include event-only values") assert.False(t, SnapshotStatus("container_started").IsKnown(), "snapshot status must not include event-only values") } func TestAllSnapshotStatusesCoverFrozenSet(t *testing.T) { assert.ElementsMatch(t, []SnapshotStatus{ SnapshotStatusHealthy, SnapshotStatusProbeFailed, SnapshotStatusExited, SnapshotStatusOOM, SnapshotStatusInspectUnhealthy, SnapshotStatusContainerDisappeared, }, AllSnapshotStatuses(), ) } func TestSnapshotSourceIsKnown(t *testing.T) { for _, source := range AllSnapshotSources() { assert.Truef(t, source.IsKnown(), "expected %q known", source) } assert.False(t, SnapshotSource("").IsKnown()) assert.False(t, SnapshotSource("manual").IsKnown()) } func TestAllSnapshotSourcesCoverFrozenSet(t *testing.T) { assert.ElementsMatch(t, []SnapshotSource{ SnapshotSourceDockerEvent, SnapshotSourceInspect, SnapshotSourceProbe, }, AllSnapshotSources(), ) } func sampleSnapshot() HealthSnapshot { return HealthSnapshot{ GameID: "game-test", ContainerID: "container-1", Status: SnapshotStatusHealthy, Source: SnapshotSourceProbe, Details: json.RawMessage(`{"prior_failure_count":0}`), ObservedAt: time.Date(2026, 4, 27, 12, 0, 0, 0, time.UTC), } } func TestHealthSnapshotValidateHappy(t *testing.T) { require.NoError(t, sampleSnapshot().Validate()) } func TestHealthSnapshotValidateAcceptsEmptyDetails(t *testing.T) { snapshot := sampleSnapshot() snapshot.Details = nil assert.NoError(t, snapshot.Validate()) } func TestHealthSnapshotValidateAcceptsEmptyContainerID(t *testing.T) { snapshot := sampleSnapshot() snapshot.ContainerID = "" assert.NoError(t, snapshot.Validate()) } func TestHealthSnapshotValidateRejects(t *testing.T) { tests := []struct { name string mutate func(*HealthSnapshot) }{ {"empty game id", func(s *HealthSnapshot) { s.GameID = "" }}, {"unknown status", func(s *HealthSnapshot) { s.Status = "exotic" }}, {"unknown source", func(s *HealthSnapshot) { s.Source = "exotic" }}, {"zero observed at", func(s *HealthSnapshot) { s.ObservedAt = time.Time{} }}, {"invalid details json", func(s *HealthSnapshot) { s.Details = json.RawMessage("not-json") }}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { snapshot := sampleSnapshot() tt.mutate(&snapshot) assert.Error(t, snapshot.Validate()) }) } }