Files
lingniu-vehicle-ingest/go/vehicle-gateway/internal/telemetry/location_test.go

132 lines
4.4 KiB
Go

package telemetry
import (
"testing"
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
)
func TestLocationProjectionForProtocolUsesProtocolFields(t *testing.T) {
tests := []struct {
name string
protocol envelope.Protocol
fields map[string]any
assert func(*testing.T, LocationProjection)
}{
{
name: "gb32960",
protocol: envelope.ProtocolGB32960,
fields: map[string]any{
"gb32960.position.latitude": "30.56",
"gb32960.position.longitude": "121.0",
"gb32960.vehicle.speed_kmh": "54.3",
"gb32960.vehicle.soc_percent": "85",
"gb32960.vehicle.total_mileage": "123",
},
assert: func(t *testing.T, location LocationProjection) {
assertFloatPointer(t, location.SpeedKMH, 54.3)
assertFloatPointer(t, location.SOCPercent, 85)
},
},
{
name: "jt808",
protocol: envelope.ProtocolJT808,
fields: map[string]any{
"jt808.location.latitude": "30.590151",
"jt808.location.longitude": "121.069881",
"jt808.location.speed_kmh": "23",
"jt808.location.altitude_m": "5",
"jt808.location.direction_deg": "79",
"jt808.location.alarm_flag": "2",
"jt808.location.status_flag": "786435",
},
assert: func(t *testing.T, location LocationProjection) {
assertFloatPointer(t, location.SpeedKMH, 23)
assertFloatPointer(t, location.AltitudeM, 5)
assertFloatPointer(t, location.DirectionDeg, 79)
assertIntPointer(t, location.AlarmFlag, 2)
assertIntPointer(t, location.StatusFlag, 786435)
},
},
{
name: "yutong root fallback",
protocol: envelope.ProtocolYutongMQTT,
fields: map[string]any{
"yutong_mqtt.root.data.latitude": "30.590921",
"yutong_mqtt.root.data.longitude": "121.075044",
"yutong_mqtt.root.data.meter_speed": "27",
"yutong_mqtt.root.data.battery_capacity_soc": "78.4",
"yutong_mqtt.root.data.gpsdirection": "88",
},
assert: func(t *testing.T, location LocationProjection) {
assertFloatPointer(t, location.SpeedKMH, 27)
assertFloatPointer(t, location.SOCPercent, 78.4)
assertFloatPointer(t, location.DirectionDeg, 88)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
location, ok := LocationProjectionForProtocol(tt.protocol, tt.fields)
if !ok {
t.Fatal("LocationProjectionForProtocol() did not find coordinates")
}
if location.Latitude == 0 || location.Longitude == 0 {
t.Fatalf("coordinates = %v,%v", location.Latitude, location.Longitude)
}
tt.assert(t, location)
})
}
}
func TestLocationProjectionForProtocolRejectsBareStandardizedFields(t *testing.T) {
for _, protocol := range []envelope.Protocol{
envelope.ProtocolGB32960,
envelope.ProtocolJT808,
envelope.ProtocolYutongMQTT,
} {
if location, ok := LocationProjectionForProtocol(protocol, map[string]any{
"latitude": 30.5,
"longitude": 121.0,
"speed_kmh": 20,
}); ok {
t.Fatalf("protocol %s unexpectedly accepted bare fields: %#v", protocol, location)
}
}
}
func TestHasRealtimeFieldsExcludesMetadataOnlyPayloads(t *testing.T) {
tests := []struct {
protocol envelope.Protocol
fields map[string]any
want bool
}{
{protocol: envelope.ProtocolGB32960, fields: map[string]any{"gb32960.header.command": "0x02"}, want: false},
{protocol: envelope.ProtocolGB32960, fields: map[string]any{"gb32960.gd_fc_stack.stack_count": "1"}, want: true},
{protocol: envelope.ProtocolJT808, fields: map[string]any{"jt808.registration.plate": "粤A00001"}, want: false},
{protocol: envelope.ProtocolJT808, fields: map[string]any{"jt808.location.speed_kmh": "20"}, want: true},
{protocol: envelope.ProtocolYutongMQTT, fields: map[string]any{"yutong_mqtt.metadata.topic": "/ytforward/shln/3"}, want: false},
{protocol: envelope.ProtocolYutongMQTT, fields: map[string]any{"yutong_mqtt.data.meter_speed": "20"}, want: true},
}
for _, tt := range tests {
if got := HasRealtimeFields(tt.protocol, tt.fields); got != tt.want {
t.Fatalf("HasRealtimeFields(%s, %#v) = %v, want %v", tt.protocol, tt.fields, got, tt.want)
}
}
}
func assertFloatPointer(t *testing.T, value *float64, want float64) {
t.Helper()
if value == nil || *value != want {
t.Fatalf("float pointer = %v, want %v", value, want)
}
}
func assertIntPointer(t *testing.T, value *int64, want int64) {
t.Helper()
if value == nil || *value != want {
t.Fatalf("int pointer = %v, want %v", value, want)
}
}