Repository: PagerDuty/go-pagerduty
Pull request #503 (2023-12-13 22:07:32)

[CSGI-2365] Add client User Agent overwrite capability

## Test cases introduced...

```sh
$ go test -count=1 -v -run TestClient_UserAgent
=== RUN   TestClient_UserAgentDefault
--- PASS: TestClient_UserAgentDefault (0.00s)
=== RUN   TestClient_UserAgentOverwrite
--- PASS: TestClient_UserAgentOverwrite (0.00s)
PASS
ok      github.com/PagerDuty/go-pagerduty       0.667s

```


Patch:
diff --git a/client.go b/client.go
index 709a044..6891c59 100644
--- a/client.go
+++ b/client.go
@@ -285,6 +285,8 @@ type Client struct {
 	// PagerDuty API. You can use either *http.Client here, or your own
 	// implementation.
 	HTTPClient HTTPClient
+
+	userAgent string
 }
 
 // NewClient creates an API client using an account/user API token
@@ -322,6 +324,14 @@ func WithAPIEndpoint(endpoint string) ClientOptions {
 	}
 }
 
+// WithTerraformProvider configures the client to be used as the PagerDuty
+// Terraform provider
+func WithTerraformProvider(version string) ClientOptions {
+	return func(c *Client) {
+		c.userAgent = fmt.Sprintf("(%s %s) Terraform/%s", runtime.GOOS, runtime.GOARCH, version)
+	}
+}
+
 // WithV2EventsAPIEndpoint allows for a custom V2 Events API endpoint to be passed into the client
 func WithV2EventsAPIEndpoint(endpoint string) ClientOptions {
 	return func(c *Client) {
@@ -498,7 +508,13 @@ func (c *Client) prepRequest(req *http.Request, authRequired bool, headers map[s
 		}
 	}
 
-	req.Header.Set("User-Agent", userAgentHeader)
+	var userAgent string
+	if c.userAgent != "" {
+		userAgent = c.userAgent
+	} else {
+		userAgent = userAgentHeader
+	}
+	req.Header.Set("User-Agent", userAgent)
 	req.Header.Set("Content-Type", contentTypeHeader)
 }
 


Test patch:
diff --git a/client_test.go b/client_test.go
index e95e4ad..e7e3aff 100644
--- a/client_test.go
+++ b/client_test.go
@@ -9,6 +9,7 @@ import (
 	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
+	"runtime"
 	"strings"
 	"sync/atomic"
 	"testing"
@@ -687,6 +688,54 @@ func TestClient_Do(t *testing.T) {
 	}
 }
 
+func TestClient_UserAgentDefault(t *testing.T) {
+	setup()
+	defer teardown()
+
+	defaultUserAgent := userAgentHeader
+	mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		userAgentHeader := r.Header.Get("User-Agent")
+		if userAgentHeader != defaultUserAgent {
+			t.Fatalf("want %q, but got %q", defaultUserAgent, userAgentHeader)
+		}
+		w.WriteHeader(http.StatusOK)
+	})
+
+	client := defaultTestClient(server.URL, "foo")
+
+	_, err := client.do(context.Background(), "GET", "/foo", nil, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestClient_UserAgentOverwrite(t *testing.T) {
+	setup()
+	defer teardown()
+
+	terraformVersion := "terraform-version-for-testing"
+	newUserAgent := fmt.Sprintf("(%s %s) Terraform/%s", runtime.GOOS, runtime.GOARCH, terraformVersion)
+	mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		userAgentHeader := r.Header.Get("User-Agent")
+		if userAgentHeader != newUserAgent {
+			t.Fatalf("want %q, but got %q", newUserAgent, userAgentHeader)
+		}
+		w.WriteHeader(http.StatusOK)
+	})
+
+	client := NewClient("foo",
+		WithAPIEndpoint(server.URL),
+		WithTerraformProvider(terraformVersion),
+	)
+
+	_, err := client.do(context.Background(), "GET", "/foo", nil, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 func TestNullAPIErrorObject_UnmarshalJSON(t *testing.T) {
 	tests := []struct {
 		name string