package main import ( "testing" "time" "github.com/segmentio/kafka-go" "lingniu/vehicle-data-platform/apps/api/internal/config" "lingniu/vehicle-data-platform/apps/api/internal/platform" ) func validAlertStreamConfig() config.Config { return config.Config{ MySQLDSN: "user:pass@tcp(localhost:3306)/db?parseTime=true", AlertStreamMode: "shadow", AlertStreamKafkaBrokers: []string{"kafka-a:9092"}, AlertStreamKafkaTopics: []string{"vehicle.fields.go.jt808.v1"}, AlertStreamKafkaGroup: "vehicle-alert-stream-v1", AlertStreamBatchSize: 200, AlertStreamBatchWait: 100 * time.Millisecond, AlertStreamLateness: 2 * time.Minute, } } func TestAlertStreamConfigAcceptsReleasedModesAndRefusesUnknownTopics(t *testing.T) { cfg := validAlertStreamConfig() if err := validateAlertStreamConfig(cfg); err != nil { t.Fatalf("valid shadow config rejected: %v", err) } cfg.AlertStreamMode = "active" if err := validateAlertStreamConfig(cfg); err != nil { t.Fatalf("released active mode rejected: %v", err) } cfg.AlertStreamMode = "unsafe" if err := validateAlertStreamConfig(cfg); err == nil { t.Fatal("unknown mode must fail closed") } cfg = validAlertStreamConfig() cfg.AlertStreamKafkaTopics = []string{"vehicle.raw.go.jt808.v1"} if err := validateAlertStreamConfig(cfg); err == nil { t.Fatal("raw topic must not be accepted as a fields alert stream") } } func TestNewAlertStreamGroupStartsAtLatestAndThenUsesCommittedOffsets(t *testing.T) { cfg := validAlertStreamConfig() reader := alertStreamReaderConfig(cfg) if reader.StartOffset != kafka.LastOffset { t.Fatalf("new production group would replay the full retained topic: start=%d", reader.StartOffset) } if reader.GroupID != cfg.AlertStreamKafkaGroup || len(reader.GroupTopics) != 1 || reader.GroupTopics[0] != cfg.AlertStreamKafkaTopics[0] { t.Fatalf("reader group contract drifted: %+v", reader) } } func TestAlertStreamInvalidCodesAreAggregatedWithoutPayloads(t *testing.T) { records := []platform.AlertStreamRecord{{ErrorCode: "missing_vin_jt808"}, {Valid: true}, {ErrorCode: "invalid_field_name"}, {ErrorCode: "missing_vin_jt808"}} if got := alertStreamInvalidCodes(records); got != "invalid_field_name:1,missing_vin_jt808:2" { t.Fatalf("invalid code summary=%q", got) } }