172 lines
5.2 KiB
Go
172 lines
5.2 KiB
Go
package identity
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"github.com/DATA-DOG/go-sqlmock"
|
|
|
|
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
|
)
|
|
|
|
func TestCandidateKeysPrioritizesPhoneDevicePlate(t *testing.T) {
|
|
keys := CandidateKeys(envelope.FrameEnvelope{
|
|
Phone: "013307795425",
|
|
DeviceID: "D1",
|
|
Plate: "豫A12345",
|
|
VehicleKeyHint: "D1",
|
|
})
|
|
got := []string{}
|
|
for _, key := range keys {
|
|
got = append(got, key.Column+"="+key.Value)
|
|
}
|
|
want := []string{"phone=013307795425", "phone=13307795425", "device_id=D1", "plate=豫A12345", "vin=D1"}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("candidate count = %d got=%#v", len(got), got)
|
|
}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("candidate[%d] = %q, want %q", i, got[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCandidateKeysAddsTrimmedPhoneVariant(t *testing.T) {
|
|
keys := CandidateKeys(envelope.FrameEnvelope{
|
|
Phone: "013079963379",
|
|
})
|
|
got := []string{}
|
|
for _, key := range keys {
|
|
got = append(got, key.Column+"="+key.Value)
|
|
}
|
|
want := []string{"phone=013079963379", "phone=13079963379"}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("candidate count = %d got=%#v", len(got), got)
|
|
}
|
|
for i := range want {
|
|
if got[i] != want[i] {
|
|
t.Fatalf("candidate[%d] = %q, want %q", i, got[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMySQLResolverFillsVINFromPhone(t *testing.T) {
|
|
db, mock := newMockDB(t)
|
|
defer db.Close()
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
|
WithArgs("013307795425").
|
|
WillReturnRows(sqlmock.NewRows([]string{"vin"}).AddRow("LNBVIN00000000001"))
|
|
|
|
resolver := NewMySQLResolver(db, "vehicle_identity_binding")
|
|
env, err := resolver.Resolve(context.Background(), envelope.FrameEnvelope{
|
|
Protocol: envelope.ProtocolJT808,
|
|
Phone: "013307795425",
|
|
Parsed: map[string]any{},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Resolve() error = %v", err)
|
|
}
|
|
if env.VIN != "LNBVIN00000000001" {
|
|
t.Fatalf("vin = %q", env.VIN)
|
|
}
|
|
identity, ok := env.Parsed["identity"].(map[string]any)
|
|
if !ok || identity["source"] != "phone" {
|
|
t.Fatalf("identity metadata = %#v", env.Parsed["identity"])
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("sql expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestMySQLResolverFallsBackToDeviceID(t *testing.T) {
|
|
db, mock := newMockDB(t)
|
|
defer db.Close()
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
|
WithArgs("013307795425").
|
|
WillReturnError(sql.ErrNoRows)
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
|
WithArgs("13307795425").
|
|
WillReturnError(sql.ErrNoRows)
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE device_id = \\?").
|
|
WithArgs("D1").
|
|
WillReturnRows(sqlmock.NewRows([]string{"vin"}).AddRow("LNBVIN00000000002"))
|
|
|
|
resolver := NewMySQLResolver(db, "vehicle_identity_binding")
|
|
env, err := resolver.Resolve(context.Background(), envelope.FrameEnvelope{
|
|
Protocol: envelope.ProtocolJT808,
|
|
Phone: "013307795425",
|
|
DeviceID: "D1",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Resolve() error = %v", err)
|
|
}
|
|
if env.VIN != "LNBVIN00000000002" {
|
|
t.Fatalf("vin = %q", env.VIN)
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("sql expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestMySQLResolverTracksJT808RegistrationAndBackfillsBinding(t *testing.T) {
|
|
db, mock := newMockDB(t)
|
|
defer db.Close()
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
|
WithArgs("013079963379").
|
|
WillReturnError(sql.ErrNoRows)
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE phone = \\?").
|
|
WithArgs("13079963379").
|
|
WillReturnError(sql.ErrNoRows)
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE device_id = \\?").
|
|
WithArgs("DEV0001").
|
|
WillReturnError(sql.ErrNoRows)
|
|
mock.ExpectQuery("SELECT vin FROM vehicle_identity_binding WHERE plate = \\?").
|
|
WithArgs("TEST123").
|
|
WillReturnRows(sqlmock.NewRows([]string{"vin"}).AddRow("LKLG7C4E3NA774736"))
|
|
mock.ExpectExec("INSERT INTO jt808_registration").
|
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
|
mock.ExpectExec("UPDATE IGNORE vehicle_identity_binding").
|
|
WithArgs("013079963379", "013079963379", "DEV0001", "DEV0001", "TEST123", "TEST123", "LKLG7C4E3NA774736").
|
|
WillReturnResult(sqlmock.NewResult(0, 1))
|
|
|
|
resolver := NewMySQLResolver(db, "vehicle_identity_binding")
|
|
env, err := resolver.Resolve(context.Background(), envelope.FrameEnvelope{
|
|
Protocol: envelope.ProtocolJT808,
|
|
MessageID: "0x0100",
|
|
Phone: "013079963379",
|
|
DeviceID: "DEV0001",
|
|
Plate: "TEST123",
|
|
SourceEndpoint: "115.231.168.135:43625",
|
|
Parsed: map[string]any{
|
|
"registration": map[string]any{
|
|
"province": uint16(16),
|
|
"city": uint16(32),
|
|
"manufacturer": "YUTNG",
|
|
"device_type": "ZK6105CHEVNPG4",
|
|
"device_id": "DEV0001",
|
|
"plate_color": uint8(2),
|
|
"plate": "TEST123",
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Resolve() error = %v", err)
|
|
}
|
|
if env.VIN != "LKLG7C4E3NA774736" {
|
|
t.Fatalf("vin = %q", env.VIN)
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("sql expectations: %v", err)
|
|
}
|
|
}
|
|
|
|
func newMockDB(t *testing.T) (*sql.DB, sqlmock.Sqlmock) {
|
|
t.Helper()
|
|
db, mock, err := sqlmock.New()
|
|
if err != nil {
|
|
t.Fatalf("sqlmock.New() error = %v", err)
|
|
}
|
|
return db, mock
|
|
}
|