Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions internal/http/authoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/saucelabs/saucectl/internal/authoring"
"github.com/saucelabs/saucectl/internal/iam"
"github.com/saucelabs/saucectl/internal/region"
"github.com/saucelabs/saucectl/internal/version"
)

// authoringBasePath is the AI Authoring API's prefix on the region's API host.
Expand Down Expand Up @@ -121,10 +122,17 @@ func (c *AuthoringService) newRequest(ctx context.Context, method, path string,
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("Accept", "application/json")
setRequestedBy(req.Header)
req.SetBasicAuth(c.Username, c.AccessKey)
return req, nil
}

// setRequestedBy identifies saucectl to the AI Authoring backend, which
// attributes requests by the requested-by header.
func setRequestedBy(h http.Header) {
h.Set("requested-by", "saucectl/"+version.Version)
}

// do sends the request with the given client and returns the response, or a
// decoded *authoring.APIError for any 4xx/5xx status. The caller must close the
// body of a returned response.
Expand Down Expand Up @@ -608,6 +616,7 @@ func (c *AuthoringService) IsAIAuthoringEnabled(ctx context.Context, orgID strin
return false, err
}
req.Header.Set("Accept", "application/json")
setRequestedBy(req.Header)
req.SetBasicAuth(c.Username, c.AccessKey)

resp, err := c.Client.Do(req)
Expand Down
13 changes: 11 additions & 2 deletions internal/http/authoring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/saucelabs/saucectl/internal/authoring"
"github.com/saucelabs/saucectl/internal/iam"
"github.com/saucelabs/saucectl/internal/region"
"github.com/saucelabs/saucectl/internal/version"
)

// newTestAuthoringService points a client at the test server with retries
Expand All @@ -37,11 +38,12 @@ func writeJSON(w http.ResponseWriter, status int, body string) {
}

func TestAuthoringService_BasicAuthAndEnvelope(t *testing.T) {
var gotPath, gotAuth, gotAccept string
var gotPath, gotAuth, gotAccept, gotRequestedBy string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotPath = r.URL.Path
gotAuth = r.Header.Get("Authorization")
gotAccept = r.Header.Get("Accept")
gotRequestedBy = r.Header.Get("requested-by")
writeJSON(w, 200, `{"data":{"id":"6a882c1dc8b4482c166e96c9","name":"test","tags":[],"revisions":[],"runSettings":{"scTunnelName":"","primaryTarget":{"capabilities":{"browserName":"chrome"},"isRdc":false},"runTargets":[]}}}`)
}))
defer srv.Close()
Expand All @@ -62,6 +64,9 @@ func TestAuthoringService_BasicAuthAndEnvelope(t *testing.T) {
if gotAccept != "application/json" {
t.Errorf("Accept = %q", gotAccept)
}
if want := "saucectl/" + version.Version; gotRequestedBy != want {
t.Errorf("requested-by = %q, want %q", gotRequestedBy, want)
}
if tc.Name != "test" {
t.Errorf("envelope not unwrapped: %+v", tc)
}
Expand Down Expand Up @@ -422,9 +427,10 @@ func TestAuthoringService_IsAIAuthoringEnabled(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var gotPath, gotQuery string
var gotPath, gotQuery, gotRequestedBy string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotPath, gotQuery = r.URL.Path, r.URL.RawQuery
gotRequestedBy = r.Header.Get("requested-by")
writeJSON(w, tt.status, tt.body)
}))
defer srv.Close()
Expand All @@ -441,6 +447,9 @@ func TestAuthoringService_IsAIAuthoringEnabled(t *testing.T) {
if gotPath != "/v2/entitlements/entities/org/org-1" || gotQuery != "entitlements=ai_authoring.enabled" {
t.Errorf("request = %s?%s; the entitlement API is not under the authoring base path", gotPath, gotQuery)
}
if want := "saucectl/" + version.Version; gotRequestedBy != want {
t.Errorf("requested-by = %q, want %q", gotRequestedBy, want)
}
})
}
}
Expand Down
Loading