feat: add yutong mqtt ingestion
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package yutongmqtt
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
||||
)
|
||||
|
||||
func TestParseMessageMapsYutongPayloadToEnvelope(t *testing.T) {
|
||||
payload := []byte(`{
|
||||
"device": "LTEST000000000001",
|
||||
"time": "20260413100000",
|
||||
"plateNo": "豫A12345",
|
||||
"data": {
|
||||
"METER_SPEED": 52.3,
|
||||
"TOTAL_MILEAGE": 123456.7,
|
||||
"BATTERY_CAPACITY_SOC": 70,
|
||||
"LONGITUDE": 116397128,
|
||||
"LATITUDE": 39916527,
|
||||
"GPSDirection": 88
|
||||
}
|
||||
}`)
|
||||
|
||||
env, err := ParseMessage("endpoint-a", "/ytforward/shln/dev1", payload, 1782745114999)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseMessage() error = %v", err)
|
||||
}
|
||||
if env.Protocol != envelope.ProtocolYutongMQTT {
|
||||
t.Fatalf("protocol = %q", env.Protocol)
|
||||
}
|
||||
if env.VIN != "LTEST000000000001" || env.DeviceID != "LTEST000000000001" {
|
||||
t.Fatalf("identity fields = vin:%q device:%q", env.VIN, env.DeviceID)
|
||||
}
|
||||
if env.Plate != "豫A12345" {
|
||||
t.Fatalf("plate = %q", env.Plate)
|
||||
}
|
||||
assertFloatField(t, env, envelope.FieldSpeedKMH, 52.3)
|
||||
assertFloatField(t, env, envelope.FieldTotalMileageKM, 123456.7)
|
||||
assertFloatField(t, env, envelope.FieldSOCPercent, 70)
|
||||
assertFloatField(t, env, envelope.FieldLongitude, 116.397128)
|
||||
assertFloatField(t, env, envelope.FieldLatitude, 39.916527)
|
||||
assertFloatField(t, env, "direction_deg", 88)
|
||||
if env.EventTimeMS == 1782745114999 {
|
||||
t.Fatal("event time should come from device time")
|
||||
}
|
||||
if env.RawText == "" || env.Parsed["data"] == nil {
|
||||
t.Fatalf("raw/parsed missing: %#v", env)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseMessageUsesDeviceAsVehicleKeyWhenNotVIN(t *testing.T) {
|
||||
payload := []byte(`{"device":"YT-DEVICE-001","time":"20260413100000","data":{"METER_SPEED":"12.3"}}`)
|
||||
env, err := ParseMessage("endpoint-a", "/ytforward/shln/YT-DEVICE-001", payload, 1782745114999)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseMessage() error = %v", err)
|
||||
}
|
||||
if env.VIN != "" {
|
||||
t.Fatalf("non-vin device should not be treated as vin: %q", env.VIN)
|
||||
}
|
||||
if env.VehicleKey() != "YT-DEVICE-001" {
|
||||
t.Fatalf("vehicle key = %q", env.VehicleKey())
|
||||
}
|
||||
assertFloatField(t, env, envelope.FieldSpeedKMH, 12.3)
|
||||
}
|
||||
|
||||
func TestParseMessageRejectsMalformedJSON(t *testing.T) {
|
||||
_, err := ParseMessage("endpoint-a", "/bad", []byte("{bad-json"), 1782745114999)
|
||||
if !errors.Is(err, ErrInvalidJSON) {
|
||||
t.Fatalf("error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertFloatField(t *testing.T, env envelope.FrameEnvelope, key string, want float64) {
|
||||
t.Helper()
|
||||
got, ok := env.Fields[key].(float64)
|
||||
if !ok {
|
||||
t.Fatalf("field %s missing or not float64: %#v", key, env.Fields[key])
|
||||
}
|
||||
if got != want {
|
||||
t.Fatalf("field %s = %v, want %v", key, got, want)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user