Skip to content

Commit 5a397cd

Browse files
authored
implement finding WMI when get multiple WMI matches (#290)
* implement finding WMI when get multiple WMI matches wiht tests * improve error message, make tests more reliable
1 parent 2760d04 commit 5a397cd

2 files changed

Lines changed: 102 additions & 4 deletions

File tree

internal/core/queries/decode_vin.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -490,18 +490,33 @@ func (dc DecodeVINQueryHandler) vinInfoFromKnown(vin vin.VIN, knownModel string,
490490
vinInfo.VIN = vin.String()
491491
wmis, err := models.Wmis(models.WmiWhere.Wmi.EQ(vin.Wmi())).All(context.Background(), dc.dbs().Reader)
492492
if err != nil {
493-
return nil, errors.Wrap(err, "vinInfoFromKnown: could not get WMI from vin wmi "+vin.Wmi())
493+
return nil, errors.Wrap(err, "vinInfoFromKnown: unknown WMI "+vin.Wmi())
494494
}
495495
if len(wmis) > 1 {
496-
return nil, fmt.Errorf("vinInfoFromKnown: more than one WMI found for vin wmi %s", vin.Wmi())
496+
// see if we can find an existing device definition for this WMI
497+
makeNamesForError := ""
498+
for _, wmi := range wmis {
499+
makeNamesForError += wmi.ManufacturerName + ", "
500+
definitionID := common.DeviceDefinitionSlug(stringutils.SlugString(wmi.ManufacturerName), stringutils.SlugString(knownModel), int16(knownYear))
501+
deviceDefinitionTablelandModel, _, err := dc.deviceDefinitionOnChainService.GetDefinitionByID(context.Background(), definitionID)
502+
if err == nil && deviceDefinitionTablelandModel != nil {
503+
vinInfo.Make = wmi.ManufacturerName
504+
break
505+
}
506+
}
507+
// if make is blank means no matching DD's found. We don't have a good way to determine the right Make / OEM
508+
if vinInfo.Make == "" {
509+
return nil, fmt.Errorf("vinInfoFromKnown: unable to determine the right OEM between %sfor WMI %s", makeNamesForError, vin.Wmi())
510+
}
511+
} else {
512+
vinInfo.Make = wmis[0].ManufacturerName
497513
}
498-
vinInfo.Make = wmis[0].ManufacturerName
499514
vinInfo.Year = knownYear
500515
vinInfo.Model = knownModel
501516
vinInfo.Source = "probably smartcar"
502517

503518
if len(vinInfo.Model) == 0 || len(vinInfo.Make) == 0 || vinInfo.Year == 0 {
504-
return nil, fmt.Errorf("unable to decode from known info")
519+
return nil, fmt.Errorf("vinInfoFromKnown: unable to decode from known info")
505520
}
506521

507522
return vinInfo, nil

internal/core/queries/decode_vin_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,3 +947,86 @@ func TestResolveMetadataFromInfo(t *testing.T) {
947947
func buildStyleName(vinInfo *coremodels.DrivlyVINResponse) string {
948948
return strings.TrimSpace(vinInfo.Trim + " " + vinInfo.SubModel)
949949
}
950+
951+
func (s *DecodeVINQueryHandlerSuite) TestDecodeVINQueryHandler_vinInfoFromKnown_multipleWMI() {
952+
vinny := "1FMCU0G61MUA52727"
953+
v := vinutil.VIN(vinny)
954+
// insert into wmi
955+
wmi1 := models.Wmi{
956+
Wmi: "1FM",
957+
ManufacturerName: "Ford",
958+
}
959+
wmi2 := models.Wmi{
960+
Wmi: "1FM",
961+
ManufacturerName: "Lincoln",
962+
}
963+
err := wmi1.Insert(s.ctx, s.pdb.DBS().Writer, boil.Infer())
964+
require.NoError(s.T(), err)
965+
err = wmi2.Insert(s.ctx, s.pdb.DBS().Writer, boil.Infer())
966+
require.NoError(s.T(), err)
967+
// mock call to get definition by id
968+
definitionID := "ford_escape_2020"
969+
970+
s.mockDeviceDefinitionOnChainService.EXPECT().GetDefinitionByID(gomock.Any(), gomock.AnyOf("lincoln_escape_2020", definitionID)).AnyTimes().Return(&coremodels.DeviceDefinitionTablelandModel{
971+
ID: definitionID,
972+
KSUID: ksuid.New().String(),
973+
Model: "Escape",
974+
Year: 2020,
975+
DeviceType: common.DefaultDeviceType,
976+
ImageURI: "",
977+
Metadata: nil,
978+
}, nil, nil)
979+
//s.mockDeviceDefinitionOnChainService.EXPECT().GetDefinitionByID(gomock.Any(), "lincoln_escape_2020").AnyTimes().Return(nil, nil, fmt.Errorf("not found"))
980+
981+
got, err := s.queryHandler.vinInfoFromKnown(v, "Escape", 2020)
982+
require.NoError(s.T(), err)
983+
assert.Equal(s.T(), "1FMCU0G61MUA52727", got.VIN)
984+
assert.Equal(s.T(), "Ford", got.Make)
985+
assert.Equal(s.T(), "Escape", got.Model)
986+
assert.Equal(s.T(), int32(2020), got.Year)
987+
}
988+
989+
func (s *DecodeVINQueryHandlerSuite) TestDecodeVINQueryHandler_vinInfoFromKnown_singleWMI() {
990+
vinny := "1FMCU0G61MUA52727"
991+
v := vinutil.VIN(vinny)
992+
// insert into wmi
993+
wmi1 := models.Wmi{
994+
Wmi: "1FM",
995+
ManufacturerName: "Ford",
996+
}
997+
998+
err := wmi1.Insert(s.ctx, s.pdb.DBS().Writer, boil.Infer())
999+
require.NoError(s.T(), err)
1000+
1001+
got, err := s.queryHandler.vinInfoFromKnown(v, "Escape", 2020)
1002+
require.NoError(s.T(), err)
1003+
assert.Equal(s.T(), "1FMCU0G61MUA52727", got.VIN)
1004+
assert.Equal(s.T(), "Ford", got.Make)
1005+
assert.Equal(s.T(), "Escape", got.Model)
1006+
assert.Equal(s.T(), int32(2020), got.Year)
1007+
}
1008+
1009+
func (s *DecodeVINQueryHandlerSuite) TestDecodeVINQueryHandler_vinInfoFromKnown_multipleWMINoDDFound() {
1010+
vinny := "1FMCU0G61MUA52727"
1011+
v := vinutil.VIN(vinny)
1012+
// insert into wmi
1013+
wmi1 := models.Wmi{
1014+
Wmi: "1FM",
1015+
ManufacturerName: "Ford",
1016+
}
1017+
wmi2 := models.Wmi{
1018+
Wmi: "1FM",
1019+
ManufacturerName: "Lincoln",
1020+
}
1021+
err := wmi1.Insert(s.ctx, s.pdb.DBS().Writer, boil.Infer())
1022+
require.NoError(s.T(), err)
1023+
err = wmi2.Insert(s.ctx, s.pdb.DBS().Writer, boil.Infer())
1024+
require.NoError(s.T(), err)
1025+
// mock call to get definition by id
1026+
definitionID := "ford_escape_2020"
1027+
s.mockDeviceDefinitionOnChainService.EXPECT().GetDefinitionByID(gomock.Any(), gomock.AnyOf("lincoln_escape_2020", definitionID)).Times(2).Return(nil, nil, fmt.Errorf("not found"))
1028+
1029+
got, err := s.queryHandler.vinInfoFromKnown(v, "Escape", 2020)
1030+
require.Error(s.T(), err, "vinInfoFromKnown: unable to determine the right OEM between Ford, Lincoln for WMI %s 1FM")
1031+
require.Nil(s.T(), got)
1032+
}

0 commit comments

Comments
 (0)