Skip to content

Commit

Permalink
Initial groundwork for generating test mode Stripe Connect URLs (#3320)
Browse files Browse the repository at this point in the history
* Add support for sending test mode requests to api.woocommerce.com

* Update the account connection UI to support test and live account connections

* Translate connect button text and make it consistent with other connect UI

* Remove legacy oauth function

* Update Woo Connect Server enpoints for test/sandbox mode

* Add Connect a test account button to onboarding page

* Update JS tests for Connect account buttons

* Pass the account ID to the oauth init request if its connected to an application

* Add tests for get_cached_account_data() with param

* Fix unit tests

* Include check for is_null

* Remove extra line added by mistake

* Add $mode param function doc block comments

* When caching an account in a specific mode, ensure we set the correct secret

* Add unit tests for WC_Stripe_API

* fix unit test

---------

Co-authored-by: Diego Curbelo <[email protected]>
  • Loading branch information
james-allan and diegocurbelo authored Aug 2, 2024
1 parent 55daf17 commit 5ca67d4
Show file tree
Hide file tree
Showing 12 changed files with 409 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,26 @@ describe( 'ConnectStripeAccount', () => {
).toBeInTheDocument();
} );

it( 'should render both the Connect Account and Enter keys buttons when the Stripe OAuth link is provided', () => {
it( 'should render both the "Create or connect an account" and "Create or connect a test account" buttons when both Stripe OAuth links are provided', () => {
render(
<ConnectStripeAccount
oauthUrl="https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_1234&scope=read_write&state=1234"
testOauthUrl="https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_5678&scope=read_write&state=5678"
/>
);

expect( screen.queryByText( 'Terms of service.' ) ).toBeInTheDocument();

expect(
screen.getByText( 'Create or connect an account' )
).toBeInTheDocument();

expect(
screen.getByText( 'Create or connect a test account instead' )
).toBeInTheDocument();
} );

it( 'should render only the "Create or connect an account" button when only the Stripe OAuth link is provided', () => {
render(
<ConnectStripeAccount oauthUrl="https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_1234&scope=read_write&state=1234" />
);
Expand All @@ -38,7 +57,32 @@ describe( 'ConnectStripeAccount', () => {
).toBeInTheDocument();

expect(
screen.queryByText( 'Enter account keys (advanced)' )
screen.queryByText( 'Create or connect a test account' )
).not.toBeInTheDocument();

expect(
screen.queryByText( 'Create or connect a test account instead' )
).not.toBeInTheDocument();
} );

it( 'should render only the "Create or connect a test account" button when only the Stripe Test OAuth link is provided', () => {
render(
<ConnectStripeAccount testOauthUrl="https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_5678&scope=read_write&state=5678" />
);

expect( screen.queryByText( 'Terms of service.' ) ).toBeInTheDocument();

expect(
screen.getByText( 'Create or connect a test account' )
).toBeInTheDocument();

// It should not have the "instead" word at the end
expect(
screen.queryByText( 'Create or connect a test account instead' )
).not.toBeInTheDocument();

expect(
screen.queryByText( 'Create or connect an account' )
).not.toBeInTheDocument();
} );

Expand All @@ -60,6 +104,11 @@ describe( 'ConnectStripeAccount', () => {
);
userEvent.click( connectAccountButton );

expect( recordEvent ).toHaveBeenCalledWith(
'wcstripe_create_or_connect_account_click',
{}
);

expect( window.location.assign ).toHaveBeenCalledWith( oauthUrl );

// Set the original function back to keep further tests working as expected.
Expand All @@ -68,19 +117,42 @@ describe( 'ConnectStripeAccount', () => {
} );
} );

it( 'should record a "wcstripe_create_or_connect_account_click" Track event when clicking on the Connect account button', () => {
it( 'should redirect to the Stripe Test OAuth link when clicking on the "Create or connect a test account" button', () => {
// Keep the original function at hand.
const assign = window.location.assign;

Object.defineProperty( window, 'location', {
value: { assign: jest.fn() },
} );

const oauthUrl =
'https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_1234&scope=read_write&state=1234';

const testOauthUrl =
'https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_5678&scope=read_write&state=5678';

render(
<ConnectStripeAccount oauthUrl="https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_1234&scope=read_write&state=1234" />
<ConnectStripeAccount
oauthUrl={ oauthUrl }
testOauthUrl={ testOauthUrl }
/>
);

const connectAccountButton = screen.getByText(
'Create or connect an account'
const connectTestAccountButton = screen.getByText(
'Create or connect a test account instead'
);
userEvent.click( connectAccountButton );
userEvent.click( connectTestAccountButton );

expect( recordEvent ).toHaveBeenCalledWith(
'wcstripe_create_or_connect_account_click',
'wcstripe_create_or_connect_test_account_click',
{}
);

expect( window.location.assign ).toHaveBeenCalledWith( testOauthUrl );

// Set the original function back to keep further tests working as expected.
Object.defineProperty( window, 'location', {
value: { assign },
} );
} );
} );
87 changes: 56 additions & 31 deletions client/settings/connect-stripe-account/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,17 @@ const ButtonWrapper = styled.div`
}
`;

const ConnectStripeAccount = ( { oauthUrl } ) => {
const ConnectStripeAccount = ( { oauthUrl, testOauthUrl } ) => {
const handleCreateOrConnectAccount = () => {
recordEvent( 'wcstripe_create_or_connect_account_click', {} );
window.location.assign( oauthUrl );
};

const handleCreateOrConnectTestAccount = () => {
recordEvent( 'wcstripe_create_or_connect_test_account_click', {} );
window.location.assign( testOauthUrl );
};

return (
<CardWrapper>
<StripeBanner />
Expand All @@ -70,38 +75,58 @@ const ConnectStripeAccount = ( { oauthUrl } ) => {
) }
</InformationText>

{ oauthUrl && (
<TermsOfServiceText>
{ interpolateComponents( {
mixedString: __(
'By clicking "Create or connect an account", you agree to the {{tosLink}}Terms of service.{{/tosLink}}',
'woocommerce-gateway-stripe'
),
components: {
tosLink: (
// eslint-disable-next-line jsx-a11y/anchor-has-content
<a
target="_blank"
rel="noreferrer"
href="https://wordpress.com/tos"
/>
{ oauthUrl || testOauthUrl ? (
<>
<TermsOfServiceText>
{ interpolateComponents( {
mixedString: __(
'By clicking "Create or connect an account", you agree to the {{tosLink}}Terms of service.{{/tosLink}}',
'woocommerce-gateway-stripe'
),
},
} ) }
</TermsOfServiceText>
) }
{ oauthUrl ? (
<ButtonWrapper>
<Button
variant="primary"
onClick={ handleCreateOrConnectAccount }
>
{ __(
'Create or connect an account',
'woocommerce-gateway-stripe'
components: {
tosLink: (
// eslint-disable-next-line jsx-a11y/anchor-has-content
<a
target="_blank"
rel="noreferrer"
href="https://wordpress.com/tos"
/>
),
},
} ) }
</TermsOfServiceText>
<ButtonWrapper>
{ oauthUrl && (
<Button
variant="primary"
onClick={ handleCreateOrConnectAccount }
>
{ __(
'Create or connect an account',
'woocommerce-gateway-stripe'
) }
</Button>
) }
{ testOauthUrl && (
<Button
variant={
oauthUrl ? 'secondary' : 'primary'
}
onClick={ handleCreateOrConnectTestAccount }
>
{ oauthUrl
? __(
'Create or connect a test account instead',
'woocommerce-gateway-stripe'
)
: __(
'Create or connect a test account',
'woocommerce-gateway-stripe'
) }
</Button>
) }
</Button>
</ButtonWrapper>
</ButtonWrapper>
</>
) : (
<InlineNotice isDismissible={ false } status="error">
{ interpolateComponents( {
Expand Down
1 change: 1 addition & 0 deletions client/settings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ if ( newAccountContainer ) {
ReactDOM.render(
<ConnectStripeAccount
oauthUrl={ wc_stripe_settings_params.stripe_oauth_url }
testOauthUrl={ wc_stripe_settings_params.stripe_test_oauth_url }
/>,
newAccountContainer
);
Expand Down
17 changes: 15 additions & 2 deletions client/settings/stripe-auth-account/stripe-auth-actions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* global wc_stripe_settings_params */
import { __ } from '@wordpress/i18n';
import { React } from 'react';
import { Button } from '@wordpress/components';
import ConfigureWebhookButton from './configure-webhook-button';
Expand All @@ -17,9 +18,21 @@ const StripeAuthActions = ( { testMode, displayWebhookConfigure } ) => {
<div className="woocommerce-stripe-auth__actions">
<Button
variant="primary"
href={ wc_stripe_settings_params.stripe_oauth_url }
href={
testMode
? wc_stripe_settings_params.stripe_test_oauth_url
: wc_stripe_settings_params.stripe_oauth_url
}
text={
testMode ? 'Connect a test account' : 'Connect an account'
testMode
? __(
'Create or connect a test account',
'woocommerce-gateway-stripe'
)
: __(
'Create or connect an account',
'woocommerce-gateway-stripe'
)
}
/>
{ displayWebhookConfigure && (
Expand Down
8 changes: 5 additions & 3 deletions includes/admin/class-wc-stripe-settings-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,10 @@ public function admin_scripts( $hook_suffix ) {
);

$oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url();
if ( is_wp_error( $oauth_url ) ) {
$oauth_url = '';
}
$oauth_url = is_wp_error( $oauth_url ) ? '' : $oauth_url;

$test_oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url( '', 'test' );
$test_oauth_url = is_wp_error( $test_oauth_url ) ? '' : $test_oauth_url;

$message = sprintf(
/* translators: 1) Html strong opening tag 2) Html strong closing tag */
Expand All @@ -146,6 +147,7 @@ public function admin_scripts( $hook_suffix ) {
'i18n_out_of_sync' => $message,
'is_upe_checkout_enabled' => WC_Stripe_Feature_Flags::is_upe_checkout_enabled(),
'stripe_oauth_url' => $oauth_url,
'stripe_test_oauth_url' => $test_oauth_url,
'show_customization_notice' => get_option( 'wc_stripe_show_customization_notice', 'yes' ) === 'yes' ? true : false,
'is_test_mode' => $this->gateway->is_in_test_mode(),
'plugin_version' => WC_STRIPE_VERSION,
Expand Down
14 changes: 0 additions & 14 deletions includes/class-wc-gateway-stripe.php
Original file line number Diff line number Diff line change
Expand Up @@ -1122,20 +1122,6 @@ public function get_required_settings_keys() {
return [ 'publishable_key', 'secret_key' ];
}

/**
* Get the connection URL.
*
* @return string Connection URL.
*/
public function get_connection_url( $return_url = '' ) {
$api = new WC_Stripe_Connect_API();
$connect = new WC_Stripe_Connect( $api );

$url = $connect->get_oauth_url( $return_url );

return is_wp_error( $url ) ? null : $url;
}

/**
* Get help text to display during quick setup.
*
Expand Down
Loading

0 comments on commit 5ca67d4

Please sign in to comment.