From 6ccf983ed571bc8a9c695cf3bebdf8cc01809f7b Mon Sep 17 00:00:00 2001 From: Brian Michalski Date: Mon, 29 Jun 2026 02:51:22 +0000 Subject: [PATCH 1/3] Configure a reasonable default HTTP timeout (#17) --- client.go | 3 ++- client_test.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 client_test.go diff --git a/client.go b/client.go index e3d3f82..7113169 100644 --- a/client.go +++ b/client.go @@ -13,6 +13,7 @@ import ( "io" "net/http" "net/url" + "time" ) // Client stores connection info needed talking to the NJTransit API. @@ -28,7 +29,7 @@ type Client struct { // 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{&http.Client{Timeout: 30 * time.Second}, baseURL, username, password} } // NewCustomClient uses the supplied `http.Client` when talking to the API. diff --git a/client_test.go b/client_test.go new file mode 100644 index 0000000..e4c9fde --- /dev/null +++ b/client_test.go @@ -0,0 +1,54 @@ +package njtapi + +import ( + "context" + "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") + } +} \ No newline at end of file From 9aab92be109aab838cd8fd039e42e39f8f8a0c9e Mon Sep 17 00:00:00 2001 From: Brian Michalski Date: Mon, 29 Jun 2026 03:00:03 +0000 Subject: [PATCH 2/3] Fix errcheck lint warning on w.Write --- client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client_test.go b/client_test.go index e4c9fde..5dbf7b9 100644 --- a/client_test.go +++ b/client_test.go @@ -39,7 +39,7 @@ func TestFetch(t *testing.T) { if r.URL.Query().Get("password") != "pass" { t.Error("missing password") } - w.Write([]byte("ok")) + _, _ = w.Write([]byte("ok")) })) defer srv.Close() From 488e4ab60ca01e027cfa67957f3770e609b3fe42 Mon Sep 17 00:00:00 2001 From: Brian Michalski Date: Mon, 29 Jun 2026 03:19:56 +0000 Subject: [PATCH 3/3] Use keyed fields in NewClient and add trailing newline --- client.go | 7 ++++++- client_test.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/client.go b/client.go index 7113169..847e890 100644 --- a/client.go +++ b/client.go @@ -29,7 +29,12 @@ type Client struct { // 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{Timeout: 30 * time.Second}, 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 5dbf7b9..2f19a1d 100644 --- a/client_test.go +++ b/client_test.go @@ -51,4 +51,4 @@ func TestFetch(t *testing.T) { if string(body) != "ok" { t.Errorf("fetch() = %q, want %q", string(body), "ok") } -} \ No newline at end of file +}