fix(outages): do not space-pad ordinals in the portal LIKE pattern
likePattern padded every token containing a digit, including ordinals like "3-я". When the ordinal starts the address, " 3-я " never matches, so "3-я Механическая улица 24а" returned no outages. Pad only pure-numeric house tokens; precision is enforced by the local house filter regardless.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user