github.com/stripe/stripe-go/v76@v76.25.0/oauth/client_test.go (about)

     1  package oauth
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"testing"
     8  
     9  	assert "github.com/stretchr/testify/require"
    10  	stripe "github.com/stripe/stripe-go/v76"
    11  	_ "github.com/stripe/stripe-go/v76/testing"
    12  )
    13  
    14  func TestAuthorizeURL(t *testing.T) {
    15  	url := AuthorizeURL(&stripe.AuthorizeURLParams{})
    16  
    17  	assert.Equal(t, url, "https://connect.stripe.com/oauth/authorize?")
    18  }
    19  
    20  func TestAuthorizeURLWithOptionalArgs(t *testing.T) {
    21  	url := AuthorizeURL(&stripe.AuthorizeURLParams{
    22  		ClientID:              stripe.String("ca_123"),
    23  		State:                 stripe.String("test-state"),
    24  		Scope:                 stripe.String("read_only"),
    25  		RedirectURI:           stripe.String("https://t.example.com"),
    26  		ResponseType:          stripe.String("test-code"),
    27  		StripeLanding:         stripe.String("register"),
    28  		AlwaysPrompt:          stripe.Bool(true),
    29  		Express:               stripe.Bool(true),
    30  		SuggestedCapabilities: stripe.StringSlice([]string{"card_payments"}),
    31  	})
    32  
    33  	assert.Contains(t, url, "https://connect.stripe.com/express/oauth/authorize?")
    34  	assert.Contains(t, url, "client_id=ca_123")
    35  	assert.Contains(t, url, "redirect_uri=https%3A%2F%2Ft.example.com")
    36  	assert.Contains(t, url, "response_type=test-code")
    37  	assert.Contains(t, url, "scope=read_only")
    38  	assert.Contains(t, url, "state=test-state")
    39  	assert.Contains(t, url, "stripe_landing=register")
    40  	assert.Contains(t, url, "always_prompt=true")
    41  	assert.Contains(t, url, "suggested_capabilities[0]=card_payments")
    42  }
    43  
    44  func TestAuthorizeURLWithStripeUser(t *testing.T) {
    45  	url := AuthorizeURL(&stripe.AuthorizeURLParams{
    46  		ResponseType: stripe.String("test-code"),
    47  		StripeUser: &stripe.OAuthStripeUserParams{
    48  			BlockKana:          stripe.String("block-kana"),
    49  			BlockKanji:         stripe.String("block-kanji"),
    50  			BuildingKana:       stripe.String("building-kana"),
    51  			BuildingKanji:      stripe.String("building-kanji"),
    52  			BusinessName:       stripe.String("b-name"),
    53  			BusinessType:       stripe.String("llc"),
    54  			City:               stripe.String("Elko"),
    55  			Country:            stripe.String("US"),
    56  			Currency:           stripe.String("USD"),
    57  			DOBDay:             stripe.Int64(15),
    58  			DOBMonth:           stripe.Int64(10),
    59  			DOBYear:            stripe.Int64(2019),
    60  			Email:              stripe.String("test@example.com"),
    61  			FirstName:          stripe.String("first-name"),
    62  			FirstNameKana:      stripe.String("first-name-kana"),
    63  			FirstNameKanji:     stripe.String("first-name-kanji"),
    64  			Gender:             stripe.String("female"),
    65  			LastName:           stripe.String("last-name"),
    66  			LastNameKana:       stripe.String("last-name-kana"),
    67  			LastNameKanji:      stripe.String("last-name-kanji"),
    68  			PhoneNumber:        stripe.String("999-999-9999"),
    69  			PhysicalProduct:    stripe.Bool(false),
    70  			ProductDescription: stripe.String("product-description"),
    71  			State:              stripe.String("NV"),
    72  			StreetAddress:      stripe.String("123 main"),
    73  			URL:                stripe.String("http://example.com"),
    74  			Zip:                stripe.String("12345"),
    75  		},
    76  	})
    77  
    78  	assert.Contains(t, url, "response_type=test-code")
    79  	assert.Contains(t, url, "stripe_user[block_kana]=block-kana")
    80  	assert.Contains(t, url, "stripe_user[block_kanji]=block-kanji")
    81  	assert.Contains(t, url, "stripe_user[building_kana]=building-kana")
    82  	assert.Contains(t, url, "stripe_user[building_kanji]=building-kanji")
    83  	assert.Contains(t, url, "stripe_user[business_name]=b-name")
    84  	assert.Contains(t, url, "stripe_user[business_type]=llc")
    85  	assert.Contains(t, url, "stripe_user[city]=Elko")
    86  	assert.Contains(t, url, "stripe_user[country]=US")
    87  	assert.Contains(t, url, "stripe_user[currency]=USD")
    88  	assert.Contains(t, url, "stripe_user[dob_day]=15")
    89  	assert.Contains(t, url, "stripe_user[dob_month]=10")
    90  	assert.Contains(t, url, "stripe_user[dob_year]=2019")
    91  	assert.Contains(t, url, "stripe_user[email]=test%40example.com")
    92  	assert.Contains(t, url, "stripe_user[first_name]=first-name")
    93  	assert.Contains(t, url, "stripe_user[first_name_kana]=first-name-kana")
    94  	assert.Contains(t, url, "stripe_user[first_name_kanji]=first-name-kanji")
    95  	assert.Contains(t, url, "stripe_user[gender]=female")
    96  	assert.Contains(t, url, "stripe_user[last_name]=last-name")
    97  	assert.Contains(t, url, "stripe_user[last_name_kana]=last-name-kana")
    98  	assert.Contains(t, url, "stripe_user[last_name_kanji]=last-name-kanji")
    99  	assert.Contains(t, url, "stripe_user[phone_number]=999-999-9999")
   100  	assert.Contains(t, url, "stripe_user[physical_product]=false")
   101  	assert.Contains(t, url, "stripe_user[product_description]=product-description")
   102  	assert.Contains(t, url, "stripe_user[state]=NV")
   103  	assert.Contains(t, url, "stripe_user[street_address]=123+main")
   104  	assert.Contains(t, url, "stripe_user[url]=http%3A%2F%2Fexample.com")
   105  	assert.Contains(t, url, "stripe_user[zip]=12345")
   106  }
   107  
   108  type roundTripFunc func(req *http.Request) *http.Response
   109  
   110  func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
   111  	return f(req), nil
   112  }
   113  
   114  func newTestClient(fn roundTripFunc) *http.Client {
   115  	return &http.Client{
   116  		Transport: roundTripFunc(fn),
   117  	}
   118  }
   119  
   120  func stubConnectBackend(httpClient *http.Client) {
   121  	mockBackend := stripe.GetBackendWithConfig(
   122  		stripe.ConnectBackend,
   123  		&stripe.BackendConfig{
   124  			URL:        stripe.String("https://localhost:12113"),
   125  			HTTPClient: httpClient,
   126  		},
   127  	)
   128  	stripe.SetBackend(stripe.ConnectBackend, mockBackend)
   129  }
   130  
   131  func TestNewOAuthToken(t *testing.T) {
   132  	stripe.Key = "sk_123"
   133  
   134  	// stripe-mock doesn't support connect URLs so this stubs out the server.
   135  	httpClient := newTestClient(func(req *http.Request) *http.Response {
   136  		buf := new(bytes.Buffer)
   137  		buf.ReadFrom(req.Body)
   138  		reqBody := buf.String()
   139  
   140  		assert.Contains(t, req.URL.String(), "https://localhost:12113/oauth/token")
   141  		assert.Contains(t, reqBody, "client_secret=sk_123")
   142  		assert.Contains(t, reqBody, "grant_type=authorization_code")
   143  		assert.Contains(t, reqBody, "code=code")
   144  		assert.Contains(t, reqBody, "assert_capabilities[0]=card_payments")
   145  
   146  		responseBody := `{
   147        "access_token":"sk_123",
   148        "livemode":false,
   149        "refresh_token":"rt_123",
   150        "token_type":"bearer",
   151        "stripe_publishable_key":"pk_123",
   152        "stripe_user_id":"acct_123",
   153        "scope":"read_write"
   154      }`
   155  		return &http.Response{
   156  			StatusCode: 200,
   157  			Body:       ioutil.NopCloser(bytes.NewBufferString(responseBody)),
   158  			Header:     make(http.Header),
   159  		}
   160  	})
   161  	stubConnectBackend(httpClient)
   162  
   163  	token, err := New(&stripe.OAuthTokenParams{
   164  		GrantType:          stripe.String("authorization_code"),
   165  		Code:               stripe.String("code"),
   166  		AssertCapabilities: stripe.StringSlice([]string{"card_payments"}),
   167  	})
   168  	assert.Nil(t, err)
   169  	assert.NotNil(t, token)
   170  	assert.Equal(t, token.AccessToken, "sk_123")
   171  	assert.Equal(t, token.Livemode, false)
   172  	assert.Equal(t, token.RefreshToken, "rt_123")
   173  	assert.Equal(t, token.TokenType, stripe.OAuthTokenTypeBearer)
   174  	assert.Equal(t, token.StripePublishableKey, "pk_123")
   175  	assert.Equal(t, token.StripeUserID, "acct_123")
   176  	assert.Equal(t, token.Scope, stripe.OAuthScopeTypeReadWrite)
   177  }
   178  
   179  func TestNewOAuthTokenWithCustomKey(t *testing.T) {
   180  	stripe.Key = "sk_123"
   181  	// stripe-mock doesn't support connect URLs so this stubs out the server.
   182  	httpClient := newTestClient(func(req *http.Request) *http.Response {
   183  		buf := new(bytes.Buffer)
   184  		buf.ReadFrom(req.Body)
   185  		reqBody := buf.String()
   186  		assert.Contains(t, reqBody, "client_secret=sk_999")
   187  
   188  		return &http.Response{
   189  			StatusCode: 200,
   190  			Body:       ioutil.NopCloser(bytes.NewBufferString(`{}`)),
   191  			Header:     make(http.Header),
   192  		}
   193  	})
   194  	stubConnectBackend(httpClient)
   195  
   196  	token, err := New(&stripe.OAuthTokenParams{
   197  		ClientSecret: stripe.String("sk_999"),
   198  	})
   199  	assert.Nil(t, err)
   200  	assert.NotNil(t, token)
   201  }
   202  
   203  func TestNewOAuthTokenWithError(t *testing.T) {
   204  	stripe.Key = "sk_123"
   205  	// stripe-mock doesn't support connect URLs so this stubs out the server.
   206  
   207  	responseBody := `{"error":"invalid_grant","error_description": "Authorization code does not exist"}`
   208  	httpClient := newTestClient(func(req *http.Request) *http.Response {
   209  		buf := new(bytes.Buffer)
   210  		buf.ReadFrom(req.Body)
   211  		reqBody := buf.String()
   212  		assert.Contains(t, reqBody, "client_secret=sk_999")
   213  
   214  		return &http.Response{
   215  			StatusCode: 400,
   216  			Body:       ioutil.NopCloser(bytes.NewBufferString(responseBody)),
   217  			Header:     make(http.Header),
   218  		}
   219  	})
   220  	stubConnectBackend(httpClient)
   221  
   222  	token, err := New(&stripe.OAuthTokenParams{
   223  		ClientSecret: stripe.String("sk_999"),
   224  	})
   225  
   226  	assert.NotNil(t, token)
   227  	assert.NotNil(t, err)
   228  
   229  	stripeErr := err.(*stripe.Error)
   230  	assert.Equal(t, 400, stripeErr.HTTPStatusCode)
   231  	assert.Equal(t, "Authorization code does not exist", stripeErr.OAuthErrorDescription)
   232  	assert.Equal(t, "invalid_grant", stripeErr.OAuthError)
   233  }
   234  
   235  func TestDeauthorize(t *testing.T) {
   236  	stripe.Key = "sk_123"
   237  
   238  	// stripe-mock doesn't support connect URLs so this stubs out the server.
   239  	httpClient := newTestClient(func(req *http.Request) *http.Response {
   240  		buf := new(bytes.Buffer)
   241  		buf.ReadFrom(req.Body)
   242  		reqBody := buf.String()
   243  		assert.Contains(t, req.URL.String(), "https://localhost:12113/oauth/deauthorize")
   244  		assert.Contains(t, reqBody, "client_id=sk_999")
   245  		assert.Contains(t, reqBody, "stripe_user_id=acct_123")
   246  
   247  		resBody := `{"stripe_user_id": "acct_123"}`
   248  		return &http.Response{
   249  			StatusCode: 200,
   250  			Body:       ioutil.NopCloser(bytes.NewBufferString(resBody)),
   251  			Header:     make(http.Header),
   252  		}
   253  	})
   254  	stubConnectBackend(httpClient)
   255  
   256  	deauthorization, err := Del(&stripe.DeauthorizeParams{
   257  		ClientID:     stripe.String("sk_999"),
   258  		StripeUserID: stripe.String("acct_123"),
   259  	})
   260  	assert.Nil(t, err)
   261  	assert.NotNil(t, deauthorization)
   262  	assert.Equal(t, deauthorization.StripeUserID, "acct_123")
   263  }