Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial groundwork for generating test mode Stripe Connect URLs #3320

Merged
Merged
Show file tree
Hide file tree
Changes from 7 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
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'
)
Copy link
Contributor Author

@james-allan james-allan Jul 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the previous PR these strings weren't translated (🙈) and in this PR I've also taken the opportunity to make the button text consistent with the text on the other connect UI.

Screenshot 2024-07-29 at 5 24 41 PM
Create or connect an account button

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a button (secondary if there is a valid live url) to connect a test account:
Screenshot 2024-07-30 at 1 04 46 AM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I had been working on this test button over here: #3318

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my PR I've taken into consideration the notice and the case if only 1 of the URLs is returned. I think we can probably merge this PR once it's good and then my PR can just be updated to improve on it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, nice work on #3318, those error notices over the buttons look awesome.

}
/>
{ 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
16 changes: 10 additions & 6 deletions includes/connect/class-wc-stripe-connect-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ class WC_Stripe_Connect_API {
/**
* Send request to Connect Server to initiate Stripe OAuth
*
* @param string $return_url return address.
* @param string $return_url The URL to return to after the OAuth is completed.
* @param string $mode Optional. The mode to connect to. 'live' or 'test'. Default is 'live'.
*
* @return array
* @return array|WP_Error The response from the server.
*/
public function get_stripe_oauth_init( $return_url ) {
public function get_stripe_oauth_init( $return_url, $mode = 'live' ) {

$current_user = wp_get_current_user();
$business_data = [];
Expand Down Expand Up @@ -55,7 +56,8 @@ public function get_stripe_oauth_init( $return_url ) {
'businessData' => $business_data,
james-allan marked this conversation as resolved.
Show resolved Hide resolved
];

return $this->request( 'POST', '/stripe/oauth-init', $request );
$path = 'test' === $mode ? '/stripe-sandbox/oauth-init' : '/stripe/oauth-init';
return $this->request( 'POST', $path, $request );
}

/**
Expand All @@ -65,11 +67,12 @@ public function get_stripe_oauth_init( $return_url ) {
*
* @return array
*/
public function get_stripe_oauth_keys( $code ) {
public function get_stripe_oauth_keys( $code, $mode = 'live' ) {

$request = [ 'code' => $code ];

return $this->request( 'POST', '/stripe/oauth-keys', $request );
$path = 'test' === $mode ? '/stripe-sandbox/oauth-keys' : '/stripe/oauth-keys';
return $this->request( 'POST', $path, $request );
}

/**
Expand All @@ -91,6 +94,7 @@ protected function request( $method, $path, $body = [] ) {
}

$url = trailingslashit( WOOCOMMERCE_CONNECT_SERVER_URL );

$url = apply_filters( 'wc_connect_server_url', $url );
$url = trailingslashit( $url ) . ltrim( $path, '/' );

Expand Down
Loading
Loading