diff --git a/internal/adapters/arcgis/client.go b/internal/adapters/arcgis/client.go index b4380f6..d4a2b9d 100644 --- a/internal/adapters/arcgis/client.go +++ b/internal/adapters/arcgis/client.go @@ -220,24 +220,29 @@ func actionFor(system string) string { } } -// likePattern builds the substring pattern the portal supports. Numeric tokens -// are padded with spaces, matching the historical integration, so that "1" does -// not incidentally match "10". +// likePattern builds the substring pattern the portal supports. Only pure +// numeric tokens (house numbers) are padded with spaces, so "1" does not +// incidentally match "10". Ordinals ("3-я") and houses with a letter ("24а") +// are left as-is: padding an ordinal breaks the match when it starts the +// string, and precision is guaranteed by the local house filter anyway. func likePattern(canonical string) string { parts := strings.Fields(canonical) for i, part := range parts { - if containsDigit(part) { + if isPureDigits(part) { parts[i] = " " + part + " " } } return "%" + strings.Join(parts, "%") + "%" } -func containsDigit(s string) bool { +func isPureDigits(s string) bool { + if s == "" { + return false + } for _, r := range s { - if r >= '0' && r <= '9' { - return true + if r < '0' || r > '9' { + return false } } - return false + return true } diff --git a/internal/adapters/arcgis/client_test.go b/internal/adapters/arcgis/client_test.go index b3b817a..f243db3 100644 --- a/internal/adapters/arcgis/client_test.go +++ b/internal/adapters/arcgis/client_test.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "net/http/httptest" + "strings" "testing" "time" ) @@ -92,3 +93,18 @@ func TestQueryStripsDistrictSuffix(t *testing.T) { t.Errorf("house not parsed at the boundary: %+v", rows[0].Unit) } } + +// TestLikePattern guards the ordinal/house padding rule: padding an ordinal +// that starts the string breaks the portal match. +func TestLikePattern(t *testing.T) { + got := likePattern("3-я Механическая улица 24а") + if strings.Contains(got, " 3-я ") { + t.Errorf("ordinal must not be space-padded: %q", got) + } + if strings.Contains(got, " 24а ") { + t.Errorf("house with a letter must not be space-padded: %q", got) + } + if !strings.Contains(likePattern("Ленина улица 1"), "% 1 %") { + t.Errorf("pure numeric house must be space-padded: %q", likePattern("Ленина улица 1")) + } +}