109 lines
3.4 KiB
Go
109 lines
3.4 KiB
Go
package geo
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestResolverMapsIPAPIResponseToClientInfo(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/203.0.113.20/json/" {
|
|
t.Fatalf("path = %q, want /203.0.113.20/json/", r.URL.Path)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{
|
|
"ip":"203.0.113.20",
|
|
"country_name":"China",
|
|
"region":"Beijing",
|
|
"city":"Beijing",
|
|
"asn":"AS64512",
|
|
"org":"Example Mobile"
|
|
}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
resolver := New(server.URL, time.Second)
|
|
info, err := resolver.Resolve(context.Background(), "203.0.113.20")
|
|
if err != nil {
|
|
t.Fatalf("Resolve returned error: %v", err)
|
|
}
|
|
|
|
if info.IP != "203.0.113.20" || info.Country != "China" || info.Region != "Beijing" || info.City != "Beijing" {
|
|
t.Fatalf("location info = %#v, want mapped country/region/city", info)
|
|
}
|
|
if info.ISP != "Example Mobile" || info.ASN != "AS64512" || info.Source != "ipapi.co" {
|
|
t.Fatalf("network info = %#v, want mapped org/asn/source", info)
|
|
}
|
|
}
|
|
|
|
func TestResolverMapsAlternateProviderNetworkFields(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{
|
|
"query":"203.0.113.21",
|
|
"country":"China",
|
|
"region_name":"Shanghai",
|
|
"city":"Shanghai",
|
|
"as":"AS64513",
|
|
"isp":"Example Unicom"
|
|
}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
resolver := New(server.URL, time.Second)
|
|
info, err := resolver.Resolve(context.Background(), "203.0.113.21")
|
|
if err != nil {
|
|
t.Fatalf("Resolve returned error: %v", err)
|
|
}
|
|
|
|
if info.IP != "203.0.113.21" || info.Country != "China" || info.Region != "Shanghai" {
|
|
t.Fatalf("location info = %#v, want alternate provider fields", info)
|
|
}
|
|
if info.ISP != "Example Unicom" || info.ASN != "AS64513" {
|
|
t.Fatalf("network info = %#v, want alternate isp/as fields", info)
|
|
}
|
|
}
|
|
|
|
func TestChainFallsBackWhenPrimaryResolverFails(t *testing.T) {
|
|
primary := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusTooManyRequests)
|
|
_, _ = w.Write([]byte(`{"error":true,"reason":"rate limited"}`))
|
|
}))
|
|
defer primary.Close()
|
|
fallback := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{
|
|
"ip":"39.181.21.1",
|
|
"region":"Shanghai",
|
|
"city":"Shanghai",
|
|
"org":"AS56041 China Mobile communications corporation"
|
|
}`))
|
|
}))
|
|
defer fallback.Close()
|
|
|
|
resolve := Chain(New(primary.URL, time.Second), New(fallback.URL, time.Second))
|
|
info, err := resolve(context.Background(), "39.181.21.1")
|
|
if err != nil {
|
|
t.Fatalf("resolve returned error: %v", err)
|
|
}
|
|
if info.ISP != "AS56041 China Mobile communications corporation" || info.Region != "Shanghai" {
|
|
t.Fatalf("info = %#v, want fallback network metadata", info)
|
|
}
|
|
}
|
|
|
|
func TestResolverReturnsErrorForProviderFailure(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusTooManyRequests)
|
|
_, _ = w.Write([]byte(`{"error":true,"reason":"rate limited"}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
resolver := New(server.URL, time.Second)
|
|
if _, err := resolver.Resolve(context.Background(), "203.0.113.20"); err == nil {
|
|
t.Fatal("Resolve succeeded, want error")
|
|
}
|
|
}
|