diff --git a/client.go b/client.go index 8fca904..0df52aa 100644 --- a/client.go +++ b/client.go @@ -15,6 +15,7 @@ import ( "io" "net/http" "net/url" + "time" ) // Client stores connection info needed talking to the NJTransit API. @@ -50,7 +51,12 @@ func (e *APIError) Unwrap() error { // baseURL: The root URL that the API is exposed on. // username / password: Authentication credentials for calling the API. func NewClient(baseURL, username, password string) *Client { - return &Client{&http.Client{}, baseURL, username, password} + return &Client{ + httpClient: &http.Client{Timeout: 30 * time.Second}, + baseURL: baseURL, + username: username, + password: password, + } } // NewCustomClient uses the supplied `http.Client` when talking to the API. diff --git a/client_test.go b/client_test.go index 11cc3bf..123ea2a 100644 --- a/client_test.go +++ b/client_test.go @@ -6,8 +6,54 @@ import ( "net/http" "net/http/httptest" "testing" + "time" ) +func TestNewClientDefaultTimeout(t *testing.T) { + c := NewClient("http://example.com", "user", "pass") + if c.httpClient.Timeout != 30*time.Second { + t.Errorf("NewClient() timeout = %v, want %v", c.httpClient.Timeout, 30*time.Second) + } +} + +func TestNewCustomClientNoDefaultTimeout(t *testing.T) { + customHTTP := &http.Client{Timeout: 5 * time.Second} + c := NewCustomClient(customHTTP, "http://example.com", "user", "pass") + if c.httpClient.Timeout != 5*time.Second { + t.Errorf("NewCustomClient() timeout = %v, want %v", c.httpClient.Timeout, 5*time.Second) + } +} + +func TestNewCustomClientZeroTimeout(t *testing.T) { + customHTTP := &http.Client{} + c := NewCustomClient(customHTTP, "http://example.com", "user", "pass") + if c.httpClient.Timeout != 0 { + t.Errorf("NewCustomClient() timeout = %v, want 0", c.httpClient.Timeout) + } +} + +func TestFetch(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Query().Get("username") != "user" { + t.Error("missing username") + } + if r.URL.Query().Get("password") != "pass" { + t.Error("missing password") + } + _, _ = w.Write([]byte("ok")) + })) + defer srv.Close() + + c := NewClient(srv.URL, "user", "pass") + body, err := c.fetch(context.Background(), "testEndpoint", nil) + if err != nil { + t.Fatalf("fetch() error = %v", err) + } + if string(body) != "ok" { + t.Errorf("fetch() = %q, want %q", string(body), "ok") + } +} + func TestFetchSuccess(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "testdata/getStationList.xml") @@ -148,4 +194,4 @@ func TestFetchTruncatedErrorBody(t *testing.T) { if apiErr.Body[1024:] != "..." { t.Errorf("expected body to end with '...', got suffix %q", apiErr.Body[1020:]) } -} \ No newline at end of file +}