package externalIpProvider import ( "net/http" "net/http/httptest" "testing" ) func TestNew(t *testing.T) { t.Run("returns external ip provider", testNew()) t.Run("returns error when url is empty", testNewEmptyUrl()) } func testNew() func(t *testing.T) { return func(t *testing.T) { provider, err := New(PlainExternalIpProviderConfig{ Url: "http://localhost", }) if err != nil { t.Fatalf("NewPlain() returned unexpected error: %v", err) } if provider == nil { t.Fatalf("NewPlain() returned nil provider") } } } func testNewEmptyUrl() func(t *testing.T) { return func(t *testing.T) { _, err := New(PlainExternalIpProviderConfig{}) if err == nil { t.Fatalf("NewPlain() returned unexpected error: %v", err) } } } func TestGetExternal(t *testing.T) { t.Run("returns external ip", testGetExternalIp()) t.Run("returns error when unable to parse ip", testGetExternalIpUnparsableIp()) t.Run("returns error when unexpected status code", testGetExternalIpUnexpectedStatusCode()) t.Run("returns error when unable to parse url", testGetExternalIpUnableToParseUrl()) t.Run("returns error when unable to get", testGetExternalIpUnableToGet()) } func testGetExternalIp() func(t *testing.T) { return func(t *testing.T) { mockServer := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("127.0.0.1")) }, )) defer mockServer.Close() provider, err := New(PlainExternalIpProviderConfig{ Url: mockServer.URL, }) if err != nil { t.Fatalf("NewPlain() returned unexpected error: %v", err) } ip, err := provider.GetExternalIp() if err != nil { t.Fatalf("GetExternalIp() returned unexpected error: %v", err) } if ip.String() != "127.0.0.1" { t.Fatalf("GetExternalIp() returned unexpected ip: %v instead of 127.0.0.1", ip) } } } func testGetExternalIpUnparsableIp() func(t *testing.T) { return func(t *testing.T) { mockServer := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("not an ip")) }, )) defer mockServer.Close() provider, err := New(PlainExternalIpProviderConfig{ Url: mockServer.URL, }) if err != nil { t.Fatalf("NewPlain() returned unexpected error: %v", err) } _, err = provider.GetExternalIp() if err == nil { t.Fatalf("GetExternalIp() returned unexpected error: %v", err) } } } func testGetExternalIpUnexpectedStatusCode() func(t *testing.T) { return func(t *testing.T) { mockServer := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) }, )) defer mockServer.Close() provider, err := New(PlainExternalIpProviderConfig{ Url: mockServer.URL, }) if err != nil { t.Fatalf("NewPlain() returned unexpected error: %v", err) } _, err = provider.GetExternalIp() if err == nil { t.Fatalf("GetExternalIp() returned unexpected error: %v", err) } } } func testGetExternalIpUnableToParseUrl() func(t *testing.T) { return func(t *testing.T) { provider, err := New(PlainExternalIpProviderConfig{ Url: "not a url !'ยง%&", }) if err != nil { t.Fatalf("NewPlain() returned unexpected error: %v", err) } _, err = provider.GetExternalIp() if err == nil { t.Fatalf("GetExternalIp() returned unexpected error: %v", err) } } } func testGetExternalIpUnableToGet() func(t *testing.T) { return func(t *testing.T) { // force error by using a non-responding url, beware of side effects provider, err := New(PlainExternalIpProviderConfig{ Url: "http://localhost:1234", }) if err != nil { t.Fatalf("NewPlain() returned unexpected error: %v", err) } _, err = provider.GetExternalIp() if err == nil { t.Fatalf("GetExternalIp() returned unexpected error: %v", err) } } }