Skip to content

Commit

Permalink
Site Migration: Support application password steps on `/setup/migrati…
Browse files Browse the repository at this point in the history
…on` flow (#97903)

* Improve site-migration tests to support application password

* Add support to application password flow
  • Loading branch information
gabrielcaires authored Jan 6, 2025
1 parent 2810f77 commit aa90615
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 0 deletions.
78 changes: 78 additions & 0 deletions client/landing/stepper/declarative-flow/migration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const {
SITE_MIGRATION_ALREADY_WPCOM,
SITE_MIGRATION_OTHER_PLATFORM_DETECTED_IMPORT,
SITE_MIGRATION_SUPPORT_INSTRUCTIONS,
SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
SITE_MIGRATION_FALLBACK_CREDENTIALS,
} = STEPS;

const steps = [
Expand All @@ -51,6 +53,8 @@ const steps = [
SITE_MIGRATION_ALREADY_WPCOM,
SITE_MIGRATION_OTHER_PLATFORM_DETECTED_IMPORT,
SITE_MIGRATION_SUPPORT_INSTRUCTIONS,
SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
SITE_MIGRATION_FALLBACK_CREDENTIALS,
];

const plans: { [ key: string ]: string } = {
Expand Down Expand Up @@ -259,6 +263,8 @@ const useCreateStepHandlers = ( navigate: Navigate< StepperStep[] >, flowObject:
const action = getFromPropsOrUrl( 'action', props ) as
| 'skip'
| 'submit'
| 'application-passwords-approval'
| 'credentials-required'
| 'already-wpcom'
| 'site-is-not-using-wordpress';

Expand All @@ -268,6 +274,18 @@ const useCreateStepHandlers = ( navigate: Navigate< StepperStep[] >, flowObject:
} );
}

if ( action === 'application-passwords-approval' ) {
return navigateWithQueryParams(
SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
[ 'siteId', 'from', 'siteSlug', 'authorizationUrl' ],
props
);
}

if ( action === 'credentials-required' ) {
return navigateWithQueryParams( SITE_MIGRATION_FALLBACK_CREDENTIALS, [], props );
}

if ( action === 'site-is-not-using-wordpress' ) {
return navigateWithQueryParams(
SITE_MIGRATION_OTHER_PLATFORM_DETECTED_IMPORT,
Expand All @@ -292,6 +310,66 @@ const useCreateStepHandlers = ( navigate: Navigate< StepperStep[] >, flowObject:
return navigateWithQueryParams( MIGRATION_HOW_TO_MIGRATE, [], props );
},
},
[ SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug ]: {
submit: ( props?: ProvidedDependencies ) => {
const action = getFromPropsOrUrl( 'action', props ) as
| 'authorization'
| 'fallback-credentials';

const authorizationUrl = getFromPropsOrUrl( 'authorizationUrl', props ) as string;

if ( action === 'authorization' ) {
const currentUrl = window.location.href;
const successUrl = encodeURIComponent( currentUrl );
window.location.assign( authorizationUrl + `&success_url=${ successUrl }` );
return;
}

if ( action === 'fallback-credentials' ) {
return navigateWithQueryParams(
SITE_MIGRATION_FALLBACK_CREDENTIALS,
[ 'authorizationUrl', 'backTo' ],
{
...props,
backTo: SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug,
authorizationUrl,
},
{ replaceHistory: true }
);
}

return navigateWithQueryParams(
SITE_MIGRATION_ASSISTED_MIGRATION,
[ 'preventTicketCreation' ],
{ ...props, preventTicketCreation: true }
);
},
goBack: ( props?: ProvidedDependencies ) => {
return navigateWithQueryParams( SITE_MIGRATION_CREDENTIALS, [], props );
},
},
[ SITE_MIGRATION_FALLBACK_CREDENTIALS.slug ]: {
submit: ( props?: ProvidedDependencies ) => {
return navigateWithQueryParams(
SITE_MIGRATION_ASSISTED_MIGRATION,
[ 'preventTicketCreation' ],
{ ...props, preventTicketCreation: true }
);
},
goBack: ( props?: ProvidedDependencies ) => {
const backTo = getFromPropsOrUrl( 'backTo', props );

if ( backTo === SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug ) {
return navigateWithQueryParams(
SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
[ 'authorizationUrl', 'backTo' ],
props
);
}
return navigateWithQueryParams( SITE_MIGRATION_CREDENTIALS, [], props );
},
},

[ SITE_MIGRATION_ASSISTED_MIGRATION.slug ]: {
submit: ( props?: ProvidedDependencies ) => {
const hasError = getFromPropsOrUrl( 'hasError', props );
Expand Down
111 changes: 111 additions & 0 deletions client/landing/stepper/declarative-flow/migration/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,85 @@ describe( `${ flow.name }`, () => {
},
} );
} );

it( 'redirects users from SITE_MIGRATION_CREDENTIALS > SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION when the user site supports application passwords', () => {
const destination = runNavigation( {
from: STEPS.SITE_MIGRATION_CREDENTIALS,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
dependencies: { action: 'application-passwords-approval' },
} );

expect( destination ).toMatchDestination( {
step: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
} );
} );

it( 'redirects users from SITE_MIGRATION_CREDENTIALS > SITE_MIGRATION_FALLBACK_CREDENTIALS when the user site does not support application passwords', () => {
const destination = runNavigation( {
from: STEPS.SITE_MIGRATION_CREDENTIALS,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
dependencies: { action: 'credentials-required' },
} );

expect( destination ).toMatchDestination( {
step: STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
} );
} );
} );

describe( 'SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION STEP', () => {
it( 'redirects users from SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION to the application password authorization url', () => {
runNavigation( {
from: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
dependencies: {
action: 'authorization',
authorizationUrl: 'https://example.com/application_password_authorization.php',
},
} );

expect( window.location.assign ).toHaveBeenCalledWith(
'https://example.com/application_password_authorization.php&success_url=https%3A%2F%2Fexample.com%2F'
);
} );

it( 'redirects users from SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION > SITE_MIGRATION_CREDENTIALS when the user cancels the authorization', () => {
const destination = runNavigation( {
from: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
dependencies: { action: 'fallback-credentials' },
} );

expect( destination ).toMatchDestination( {
step: STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS,
query: {
siteId: 123,
siteSlug: 'example.wordpress.com',
backTo: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug,
},
} );
} );
} );

describe( 'SITE_MIGRATION_FALLBACK_CREDENTIALS STEP', () => {
it( 'redirects users from SITE_MIGRATION_FALLBACK_CREDENTIALS to SITE_MIGRATION_ASSISTED_MIGRATION', () => {
const destination = runNavigation( {
from: STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
dependencies: { action: 'submit' },
} );

expect( destination ).toMatchDestination( {
step: STEPS.SITE_MIGRATION_ASSISTED_MIGRATION,
query: {
siteId: 123,
siteSlug: 'example.wordpress.com',
preventTicketCreation: 'true',
},
} );
} );
} );

describe( 'SITE_MIGRATION_ALREADY_WPCOM STEP', () => {
Expand Down Expand Up @@ -563,6 +642,38 @@ describe( `${ flow.name }`, () => {
},
} );
} );

it( 'redirects back user from SITE_MIGRATION_FALLBACK_CREDENTIALS to SITE_MIGRATION_CREDENTIALS', () => {
const destination = runNavigationBack( {
from: STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
} );

expect( destination ).toMatchDestination( {
step: STEPS.SITE_MIGRATION_CREDENTIALS,
query: { siteId: 123, siteSlug: 'example.wordpress.com' },
} );
} );

it( 'redirects back user from SITE_MIGRATION_FALLBACK_CREDENTIALS to SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION when the backTo query param is set', () => {
const destination = runNavigationBack( {
from: STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS,
query: {
siteId: 123,
siteSlug: 'example.wordpress.com',
backTo: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug,
},
} );

expect( destination ).toMatchDestination( {
step: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION,
query: {
siteId: 123,
siteSlug: 'example.wordpress.com',
backTo: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug,
},
} );
} );
it( 'redirects back user from SITE_MIGRATION_OTHER_PLATFORM_DETECTED_IMPORT to SITE_MIGRATION_CREDENTIALS', () => {
const destination = runNavigationBack( {
from: STEPS.SITE_MIGRATION_OTHER_PLATFORM_DETECTED_IMPORT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,38 @@ describe( 'Site Migration Flow', () => {
} );
} );

it( 'redirects from site-migration-credentails step to SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION', () => {
const { runUseStepNavigationSubmit } = renderFlow( siteMigrationFlow );

runUseStepNavigationSubmit( {
currentStep: STEPS.SITE_MIGRATION_CREDENTIALS.slug,
dependencies: {
action: 'application-passwords-approval',
},
} );

expect( getFlowLocation() ).toEqual( {
path: `/${ STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug }?siteSlug=example.wordpress.com`,
state: null,
} );
} );

it( 'redirects from site-migration-credentails step to FALLBACK_CREDENTIALS when credentials are required', () => {
const { runUseStepNavigationSubmit } = renderFlow( siteMigrationFlow );

runUseStepNavigationSubmit( {
currentStep: STEPS.SITE_MIGRATION_CREDENTIALS.slug,
dependencies: {
action: 'credentials-required',
},
} );

expect( getFlowLocation() ).toEqual( {
path: `/${ STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS.slug }?siteSlug=example.wordpress.com`,
state: null,
} );
} );

it( 'redirects from site-migration-credentials step to site-migration-assisted-migration creating the ticket', () => {
const { runUseStepNavigationSubmit } = renderFlow( siteMigrationFlow );

Expand Down Expand Up @@ -606,6 +638,47 @@ describe( 'Site Migration Flow', () => {
} );
} );

it( 'redirects the user to the credentials step when going back from the application password authorization step', async () => {
const { runUseStepNavigationGoBack } = renderFlow( siteMigrationFlow );

runUseStepNavigationGoBack( {
currentStep: STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug,
} );

expect( getFlowLocation() ).toEqual( {
path: `/${ STEPS.SITE_MIGRATION_CREDENTIALS.slug }?siteSlug=example.wordpress.com`,
state: null,
} );
} );

it( 'redirects the user to the credentials step when going back from the fallback step', async () => {
const { runUseStepNavigationGoBack } = renderFlow( siteMigrationFlow );

runUseStepNavigationGoBack( {
currentStep: STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS.slug,
} );

expect( getFlowLocation() ).toEqual( {
path: `/${ STEPS.SITE_MIGRATION_CREDENTIALS.slug }?siteSlug=example.wordpress.com`,
state: null,
} );
} );

it( 'redirects the user to the application password authorization step when going back from the fallback step with the backTo query param', async () => {
const { runUseStepNavigationGoBack } = renderFlow( siteMigrationFlow );

runUseStepNavigationGoBack( {
currentStep: STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS.slug,
currentURL: `/setup/${ STEPS.SITE_MIGRATION_FALLBACK_CREDENTIALS.slug }?siteSlug=example.wordpress.com&backTo=${ STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug }`,
} );

//TODO: Check if really make sense to have this backTo url here
expect( getFlowLocation() ).toEqual( {
path: `/${ STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug }?siteSlug=example.wordpress.com&backTo=${ STEPS.SITE_MIGRATION_APPLICATION_PASSWORD_AUTHORIZATION.slug }`,
state: null,
} );
} );

it( 'redirects the user to the other platform detected import step when going back from the credentials step', async () => {
const { runUseStepNavigationGoBack } = renderFlow( siteMigrationFlow );

Expand Down

0 comments on commit aa90615

Please sign in to comment.