package main import ( "lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope" "lingniu-vehicle-ingest/go/vehicle-gateway/internal/stats" "testing" "time" ) func TestCustomerHydrogenIntervalsClassifyElectricZeroAndUnknown(t *testing.T) { start := time.Date(2026, 9, 29, 8, 0, 0, 0, time.UTC) days := map[string]*customerHydrogenDay{} sample := func(min int, km float64, known, active bool) stats.MetricSample { return stats.MetricSample{VIN: "VIN", StatDate: "2026-09-29", Protocol: envelope.ProtocolGB32960, SourceKey: "source", EventTime: start.Add(time.Duration(min) * time.Minute), TotalMileageKM: km, PureHydrogenModeKnown: known, PureHydrogenActive: active} } for _, s := range []stats.MetricSample{sample(0, 100, true, false), sample(5, 105, true, false), sample(10, 110, true, true), sample(15, 115, false, false), sample(15, 115, true, true), sample(60, 130, true, true), sample(65, 140, true, true)} { addCustomerHydrogenSample(days, s) } for _, d := range days { if d.HydrogenKM != 15 || d.ObservedKM != 25 || d.ClassifiedKM != 20 || d.Samples != 6 || d.KnownSamples != 5 || d.Rejected != 1 { t.Fatalf("incorrect evidence %+v", d) } } zero := map[string]*customerHydrogenDay{} addCustomerHydrogenSample(zero, sample(0, 100, true, false)) addCustomerHydrogenSample(zero, sample(5, 105, true, false)) for _, d := range zero { if d.HydrogenKM != 0 || d.ClassifiedKM != 5 || d.KnownSamples != 2 { t.Fatal("observed electric-only day not distinguished from missing") } } } func TestCustomerHydrogenSeparatesSourcesDaysAndRejectsJumps(t *testing.T) { days := map[string]*customerHydrogenDay{} s := stats.MetricSample{VIN: "VIN", StatDate: "2026-09-29", Protocol: envelope.ProtocolGB32960, SourceKey: "A", EventTime: time.Now(), TotalMileageKM: 100, PureHydrogenModeKnown: true, PureHydrogenActive: true} addCustomerHydrogenSample(days, s) s.EventTime = s.EventTime.Add(time.Minute) s.TotalMileageKM = 1100 addCustomerHydrogenSample(days, s) s.SourceKey = "B" s.TotalMileageKM = 100 addCustomerHydrogenSample(days, s) s.StatDate = "2026-09-30" addCustomerHydrogenSample(days, s) if len(days) != 3 { t.Fatal("source/day evidence mixed") } for _, d := range days { if d.HydrogenKM != 0 { t.Fatal("odometer jump counted as hydrogen") } } }