package ip import ( "context" "net/http" "net/http/httptest" "strings" "testing" "time" ) func TestGetIPOK(t *testing.T) { t.Parallel() mockSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("198.51.100.42")) })) defer mockSrv.Close() clt := concreteIPGetter{ httpClt: mockSrv.Client(), remoteAddress: mockSrv.URL, timeout: 1 * time.Second, } ctx, cancel := context.WithCancel(context.Background()) defer cancel() val, err := clt.GetCurrentPublicIP(ctx) if err != nil { t.Fatalf("Unexpected error %s", err.Error()) } if val.String() != "198.51.100.42" { t.Fatalf("Unexpected public IP %v", val) } } func TestGetIPServerErr(t *testing.T) { t.Parallel() mockSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer mockSrv.Close() clt := concreteIPGetter{ httpClt: mockSrv.Client(), remoteAddress: mockSrv.URL, timeout: 1 * time.Second, } ctx, cancel := context.WithCancel(context.Background()) defer cancel() _, err := clt.GetCurrentPublicIP(ctx) if err == nil { t.Fatal("Unexpected nil error") } else if err.Error() != "invalid returncode 500" { t.Fatalf("Unexpected error %s", err.Error()) } } func TestGetIPUnreachable(t *testing.T) { t.Parallel() mockSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { })) mockSrv.Close() clt := concreteIPGetter{ httpClt: mockSrv.Client(), remoteAddress: mockSrv.URL, timeout: 1 * time.Second, } ctx, cancel := context.WithCancel(context.Background()) defer cancel() _, err := clt.GetCurrentPublicIP(ctx) if err == nil { t.Fatal("Unexpected nil error") } else if !strings.Contains(err.Error(), "connect: connection refused") { t.Fatalf("Unexpected error %s", err.Error()) } } func TestGetIPInvalidResponse(t *testing.T) { t.Parallel() mockSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("toto")) })) defer mockSrv.Close() clt := concreteIPGetter{ httpClt: mockSrv.Client(), remoteAddress: mockSrv.URL, timeout: 1 * time.Second, } ctx, cancel := context.WithCancel(context.Background()) defer cancel() _, err := clt.GetCurrentPublicIP(ctx) if err == nil { t.Fatal("Unexpected nil error") } else if err.Error() != `got an invalid public IP "toto"` { t.Fatalf("Unexpected error %s", err.Error()) } } func TestGetIPTimeout(t *testing.T) { t.Parallel() mockSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { time.Sleep(100 * time.Millisecond) w.WriteHeader(http.StatusOK) w.Write([]byte("toto")) })) defer mockSrv.Close() clt := concreteIPGetter{ httpClt: mockSrv.Client(), remoteAddress: mockSrv.URL, timeout: 1 * time.Millisecond, } ctx, cancel := context.WithCancel(context.Background()) defer cancel() _, err := clt.GetCurrentPublicIP(ctx) if err == nil { t.Fatal("Unexpected nil error") } else if !strings.Contains(err.Error(), "context deadline exceeded") { t.Fatalf("Unexpected error %s", err.Error()) } }