fix(outages): format numeric portal dates as integers
Portal date fields arrive as numbers; fmt's %v rendered them in scientific notation, so the "current outage" filter could not parse them and kept past outages (a 'Прошлые' record leaked through). Format integer-valued attributes explicitly.
This commit is contained in:
@@ -191,14 +191,22 @@ func codeKey(v any) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stringOf renders an attribute value as a string. The important case is
|
||||||
|
// numeric dates: fmt's %v turns a float64 into scientific notation ("1.79e+12")
|
||||||
|
// which the date parser cannot read, so integers are formatted explicitly.
|
||||||
func stringOf(v any) string {
|
func stringOf(v any) string {
|
||||||
if s, ok := v.(string); ok {
|
switch t := v.(type) {
|
||||||
return s
|
case nil:
|
||||||
}
|
|
||||||
if v == nil {
|
|
||||||
return ""
|
return ""
|
||||||
}
|
case string:
|
||||||
|
return t
|
||||||
|
case float64:
|
||||||
|
return strconv.FormatInt(int64(t), 10)
|
||||||
|
case json.Number:
|
||||||
|
return t.String()
|
||||||
|
default:
|
||||||
return fmt.Sprintf("%v", v)
|
return fmt.Sprintf("%v", v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// actionFor maps a portal system name to the canonical action code used by the
|
// actionFor maps a portal system name to the canonical action code used by the
|
||||||
|
|||||||
@@ -94,6 +94,24 @@ func TestQueryStripsDistrictSuffix(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestQueryFormatsNumericDates guards against scientific notation in dates,
|
||||||
|
// which broke the "current outage" filter.
|
||||||
|
func TestQueryFormatsNumericDates(t *testing.T) {
|
||||||
|
const env = `{"features":[{"value":"Ленина улица, 1","attributes":{"address":"Ленина улица, 1","start_date":1790820000000,"end_date":1791799200000}}]}`
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, _ = w.Write([]byte(env))
|
||||||
|
}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
rows, err := New(ts.URL, time.Second, 0).Query(context.Background(), "Ленина улица 1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Query: %v", err)
|
||||||
|
}
|
||||||
|
if rows[0].StartDate != "1790820000000" || rows[0].EndDate != "1791799200000" {
|
||||||
|
t.Errorf("numeric dates must be integer-formatted: %q..%q", rows[0].StartDate, rows[0].EndDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestLikePattern guards the ordinal/house padding rule: padding an ordinal
|
// TestLikePattern guards the ordinal/house padding rule: padding an ordinal
|
||||||
// that starts the string breaks the portal match.
|
// that starts the string breaks the portal match.
|
||||||
func TestLikePattern(t *testing.T) {
|
func TestLikePattern(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user