feat: add GeoIP country lookup with embedded DB-IP Lite database (PLAN.md 4.3)
Embeds a DB-IP Lite country MMDB (~5MB) in the binary via go:embed, keeping the single-binary deployment story clean. Country codes are stored alongside login attempts and sessions, shown in the dashboard (Top IPs, Top Countries card, Recent/Active Sessions, session detail). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
44
internal/geoip/geoip_test.go
Normal file
44
internal/geoip/geoip_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package geoip
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestLookup(t *testing.T) {
|
||||
reader, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("New: %v", err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
tests := []struct {
|
||||
ip string
|
||||
want string
|
||||
}{
|
||||
{"8.8.8.8", "US"},
|
||||
{"1.1.1.1", "AU"},
|
||||
{"invalid", ""},
|
||||
{"", ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.ip, func(t *testing.T) {
|
||||
got := reader.Lookup(tt.ip)
|
||||
if got != tt.want {
|
||||
t.Errorf("Lookup(%q) = %q, want %q", tt.ip, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLookupPrivateIP(t *testing.T) {
|
||||
reader, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("New: %v", err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
// Private IPs should return empty string (no country).
|
||||
got := reader.Lookup("10.0.0.1")
|
||||
if got != "" {
|
||||
t.Errorf("Lookup(10.0.0.1) = %q, want empty", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user