google: clean up tests and add godoc comments

Change-Id: I54d2702a149d1eccd64f8ef2ed4b4617429c9358
This commit is contained in:
Patrick Jones 2020-11-17 16:40:37 -08:00
parent b1b1e51616
commit aa7010ab25
2 changed files with 26 additions and 19 deletions

View File

@ -16,6 +16,10 @@ import (
"strings" "strings"
) )
// ExchangeToken preforms a oauth2 token exchange with the provided endpoint.
// The first 4 fields are all mandatory. headers can be used to pass additional
// headers beyond the bare minimum required by the token exchange. options can
// be used to pass additional JSON-structured options to the remote server.
func ExchangeToken(ctx context.Context, endpoint string, request *STSTokenExchangeRequest, authentication ClientAuthentication, headers http.Header, options map[string]interface{}) (*STSTokenExchangeResponse, error) { func ExchangeToken(ctx context.Context, endpoint string, request *STSTokenExchangeRequest, authentication ClientAuthentication, headers http.Header, options map[string]interface{}) (*STSTokenExchangeResponse, error) {
client := oauth2.NewClient(ctx, nil) client := oauth2.NewClient(ctx, nil)
@ -63,9 +67,11 @@ func ExchangeToken(ctx context.Context, endpoint string, request *STSTokenExchan
} }
return &stsResp, nil return &stsResp, nil
} }
// STSTokenExchangeRequest contains fields necessary to make an oauth2 token exchange.
type STSTokenExchangeRequest struct { type STSTokenExchangeRequest struct {
ActingParty struct { ActingParty struct {
ActorToken string ActorToken string
@ -80,6 +86,7 @@ type STSTokenExchangeRequest struct {
SubjectTokenType string SubjectTokenType string
} }
// STSTokenExchangeResponse is used to decode the remote server's response during an oauth2 token exchange.
type STSTokenExchangeResponse struct { type STSTokenExchangeResponse struct {
AccessToken string `json:"access_token"` AccessToken string `json:"access_token"`
IssuedTokenType string `json:"issued_token_type"` IssuedTokenType string `json:"issued_token_type"`

View File

@ -47,7 +47,6 @@ var expectedToken = STSTokenExchangeResponse{
} }
func TestExchangeToken(t *testing.T) { func TestExchangeToken(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" { if r.Method != "POST" {
t.Errorf("Unexpected request method, %v is found", r.Method) t.Errorf("Unexpected request method, %v is found", r.Method)
@ -55,24 +54,23 @@ func TestExchangeToken(t *testing.T) {
if r.URL.String() != "/" { if r.URL.String() != "/" {
t.Errorf("Unexpected request URL, %v is found", r.URL) t.Errorf("Unexpected request URL, %v is found", r.URL)
} }
headerAuth := r.Header.Get("Authorization") if got, want := r.Header.Get("Authorization"), "Basic cmJyZ25vZ25yaG9uZ28zYmk0Z2I5Z2hnOWc6bm90c29zZWNyZXQ="; got != want {
if headerAuth != "Basic cmJyZ25vZ25yaG9uZ28zYmk0Z2I5Z2hnOWc6bm90c29zZWNyZXQ=" { t.Errorf("Unexpected authorization header, got %v, want %v", got, want)
t.Errorf("Unexpected autohrization header, %v is found", headerAuth)
} }
headerContentType := r.Header.Get("Content-Type") if got, want := r.Header.Get("Content-Type"), "application/x-www-form-urlencoded"; got != want{
if headerContentType != "application/x-www-form-urlencoded" { t.Errorf("Unexpected Content-Type header, got %v, want %v", got, want)
t.Errorf("Unexpected Content-Type header, %v is found", headerContentType)
} }
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
t.Errorf("Failed reading request body: %v.", err) t.Errorf("Failed reading request body: %v.", err)
} }
if string(body) != requestbody { if got, want := string(body), requestbody; got != want {
t.Errorf("Unexpected exchange payload, %v is found", string(body)) t.Errorf("Unexpected exchange payload, got %v but want %v", got, want)
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write([]byte(responseBody)) w.Write([]byte(responseBody))
})) }))
defer ts.Close()
headers := http.Header{} headers := http.Header{}
headers.Add("Content-Type", "application/x-www-form-urlencoded") headers.Add("Content-Type", "application/x-www-form-urlencoded")
@ -95,6 +93,7 @@ func TestExchangeToken_Err(t *testing.T) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write([]byte("what's wrong with this response?")) w.Write([]byte("what's wrong with this response?"))
})) }))
defer ts.Close()
headers := http.Header{} headers := http.Header{}
headers.Add("Content-Type", "application/x-www-form-urlencoded") headers.Add("Content-Type", "application/x-www-form-urlencoded")
@ -113,7 +112,7 @@ func TestExchangeToken_Opts(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
t.Errorf("Failed reading request body: %v.", err) t.Fatalf("Failed reading request body: %v.", err)
} }
data, err := url.ParseQuery(string(body)) data, err := url.ParseQuery(string(body))
if err != nil { if err != nil {
@ -128,7 +127,7 @@ func TestExchangeToken_Opts(t *testing.T) {
var opts map[string]interface{} var opts map[string]interface{}
err = json.Unmarshal([]byte(strOpts[0]), &opts) err = json.Unmarshal([]byte(strOpts[0]), &opts)
if len(opts) < 2 { if len(opts) < 2 {
t.Errorf("Too few options recieved.") t.Errorf("Too few options received.")
} }
val, ok := opts["one"] val, ok := opts["one"]
@ -139,11 +138,11 @@ func TestExchangeToken_Opts(t *testing.T) {
if !ok { if !ok {
t.Errorf("Failed to assert the first option parameter as type testOpts.") t.Errorf("Failed to assert the first option parameter as type testOpts.")
} else { } else {
if tOpts1["first"].(string) != optsValues[0][0] { if got, want := tOpts1["first"].(string), optsValues[0][0]; got != want {
t.Errorf("First value in first options field is incorrect; want %v but got %v", tOpts1["first"].(string), optsValues[0][0]) t.Errorf("First value in first options field is incorrect; got %v but want %v", got, want)
} }
if tOpts1["second"].(string) != optsValues[0][1] { if got, want := tOpts1["second"].(string), optsValues[0][1]; got != want {
t.Errorf("Second value in first options field is incorrect; want %v but got %v", tOpts1["second"].(string), optsValues[0][1]) t.Errorf("Second value in first options field is incorrect; got %v but want %v", got, want)
} }
} }
} }
@ -156,11 +155,11 @@ func TestExchangeToken_Opts(t *testing.T) {
if !ok { if !ok {
t.Errorf("Failed to assert the second option parameter as type testOpts.") t.Errorf("Failed to assert the second option parameter as type testOpts.")
} else { } else {
if tOpts2["first"].(string) != optsValues[1][0] { if got, want := tOpts2["first"].(string), optsValues[1][0]; got != want {
t.Errorf("First value in second options field is incorrect; want %v but got %v", tOpts2["first"].(string), optsValues[1][0]) t.Errorf("First value in second options field is incorrect; got %v but want %v", got, want)
} }
if tOpts2["second"].(string) != optsValues[1][1] { if got, want := tOpts2["second"].(string), optsValues[1][1]; got != want {
t.Errorf("Second value in second options field is incorrect; want %v but got %v", tOpts2["second"].(string), optsValues[1][1]) t.Errorf("Second value in second options field is incorrect; got %v but want %v", got, want)
} }
} }
} }
@ -170,6 +169,7 @@ func TestExchangeToken_Opts(t *testing.T) {
w.Write([]byte(responseBody)) w.Write([]byte(responseBody))
})) }))
defer ts.Close()
headers := http.Header{} headers := http.Header{}
headers.Add("Content-Type", "application/x-www-form-urlencoded") headers.Add("Content-Type", "application/x-www-form-urlencoded")