fix(stats): reconcile stale gps mileage candidates
This commit is contained in:
@@ -50,6 +50,73 @@ func TestChooseTrustedSourceKeepsContinuingSourceAndRejectsNewJump(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanupSubthresholdGPSMileageCandidatesDryRunReportsWithoutDeleting(t *testing.T) {
|
||||
db, mock, err := sqlmock.New()
|
||||
if err != nil {
|
||||
t.Fatalf("sqlmock.New() error = %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
mock.ExpectQuery("SELECT vin, DATE_FORMAT").
|
||||
WithArgs("2026-07-20", "2026-07-20", stats.QualityReasonGPSCoordinate, stats.GPSMinimumDailyDistanceKM, "JT808").
|
||||
WillReturnRows(sqlmock.NewRows([]string{"vin", "stat_date", "protocol", "row_count"}).
|
||||
AddRow("LKLG7C4E9NA774739", "2026-07-20", "JT808", 1))
|
||||
|
||||
found, deleted, err := cleanupSubthresholdGPSMileageCandidates(context.Background(), db, config{
|
||||
DateFrom: "2026-07-20",
|
||||
DateTo: "2026-07-20",
|
||||
Protocols: []envelope.Protocol{envelope.ProtocolJT808},
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatalf("cleanupSubthresholdGPSMileageCandidates() error = %v", err)
|
||||
}
|
||||
if found != 1 || deleted != 0 {
|
||||
t.Fatalf("cleanup result found=%d deleted=%d", found, deleted)
|
||||
}
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Fatalf("unmet SQL expectations: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanupSubthresholdGPSMileageCandidatesDeletesAndReprojectsAtomically(t *testing.T) {
|
||||
db, mock, err := sqlmock.New()
|
||||
if err != nil {
|
||||
t.Fatalf("sqlmock.New() error = %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
mock.ExpectQuery("SELECT vin, DATE_FORMAT").
|
||||
WithArgs("2026-07-20", "2026-07-20", stats.QualityReasonGPSCoordinate, stats.GPSMinimumDailyDistanceKM, "JT808").
|
||||
WillReturnRows(sqlmock.NewRows([]string{"vin", "stat_date", "protocol", "row_count"}).
|
||||
AddRow("LKLG7C4E9NA774739", "2026-07-20", "JT808", 1))
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectExec("DELETE FROM vehicle_daily_mileage_source").
|
||||
WithArgs("LKLG7C4E9NA774739", "2026-07-20", "JT808", stats.QualityReasonGPSCoordinate, stats.GPSMinimumDailyDistanceKM).
|
||||
WillReturnResult(sqlmock.NewResult(0, 1))
|
||||
mock.ExpectExec("INSERT INTO vehicle_daily_mileage").
|
||||
WillReturnResult(sqlmock.NewResult(0, 0))
|
||||
mock.ExpectExec("UPDATE vehicle_daily_mileage_source").
|
||||
WillReturnResult(sqlmock.NewResult(0, 0))
|
||||
mock.ExpectExec("DELETE FROM vehicle_daily_mileage").
|
||||
WillReturnResult(sqlmock.NewResult(0, 1))
|
||||
mock.ExpectCommit()
|
||||
|
||||
found, deleted, err := cleanupSubthresholdGPSMileageCandidates(context.Background(), db, config{
|
||||
DateFrom: "2026-07-20",
|
||||
DateTo: "2026-07-20",
|
||||
Protocols: []envelope.Protocol{envelope.ProtocolJT808},
|
||||
}, true)
|
||||
if err != nil {
|
||||
t.Fatalf("cleanupSubthresholdGPSMileageCandidates() error = %v", err)
|
||||
}
|
||||
if found != 1 || deleted != 1 {
|
||||
t.Fatalf("cleanup result found=%d deleted=%d", found, deleted)
|
||||
}
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Fatalf("unmet SQL expectations: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChooseTrustedSourceAcceptsSmallNegativeMileageJitter(t *testing.T) {
|
||||
previous := []dailySourceLast{{
|
||||
VIN: "LB9A32A28R0LS1574",
|
||||
|
||||
Reference in New Issue
Block a user