Make the home page's AS name search work (closes #151)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The AS Name Search card on the home page said the search was coming soon. It now asks the new GET /api/v1/search/as?q=<text>, which searches the AS list built into asinfo, and lists the matches as links to their AS pages. The answer holds the query, the number of matches and the first 50 of them; an empty q answers 400. asinfo.Search now ignores case, uses strings.Contains instead of its own substring loop, and returns its matches in AS number order. A number, or AS and a number, typed into the card still opens that AS's page. The card builds the list with textContent, since the names come from outside data. Model: opus-5-5
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package asinfo_test
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -162,20 +163,54 @@ func TestSearch(t *testing.T) {
|
||||
tt.query, len(results), tt.wantMin)
|
||||
}
|
||||
|
||||
// Verify all results contain the query
|
||||
if tt.query != "" {
|
||||
for _, r := range results {
|
||||
if !strings.Contains(r.Handle, tt.query) &&
|
||||
!strings.Contains(r.Description, tt.query) {
|
||||
t.Errorf("Search result ASN %d doesn't contain query %q",
|
||||
r.ASN, tt.query)
|
||||
}
|
||||
// Verify all results contain the query, ignoring case
|
||||
query := strings.ToLower(tt.query)
|
||||
for _, r := range results {
|
||||
if !strings.Contains(strings.ToLower(r.Handle), query) &&
|
||||
!strings.Contains(strings.ToLower(r.Description), query) {
|
||||
t.Errorf("Search result ASN %d doesn't contain query %q",
|
||||
r.ASN, tt.query)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestSearchIgnoresCase searches for Cloudflare's handle in lower case and its
|
||||
// description in upper case, and expects both searches to find AS13335.
|
||||
func TestSearchIgnoresCase(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const cloudflareASN = 13335 // handle CLOUDFLARENET, "Cloudflare, Inc."
|
||||
|
||||
isCloudflare := func(info asinfo.Info) bool {
|
||||
return info.ASN == cloudflareASN
|
||||
}
|
||||
|
||||
for _, query := range []string{"cloudflarenet", "CLOUDFLARE, INC."} {
|
||||
if !slices.ContainsFunc(asinfo.Search(query), isCloudflare) {
|
||||
t.Errorf("Search(%q) did not find AS%d", query, cloudflareASN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestSearchOrdersByASN expects the matches of a search with many of them to
|
||||
// come in AS number order.
|
||||
func TestSearchOrdersByASN(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const query = "University"
|
||||
|
||||
results := asinfo.Search(query)
|
||||
|
||||
for i := 1; i < len(results); i++ {
|
||||
if results[i-1].ASN >= results[i].ASN {
|
||||
t.Fatalf("Search(%q): AS%d comes after AS%d",
|
||||
query, results[i].ASN, results[i-1].ASN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataIntegrity(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user