Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
105 changes: 81 additions & 24 deletions src/modules/sync/hooks/use-sync-dialog-texts.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,103 @@
import { sprintf } from '@wordpress/i18n';
import { useI18n } from '@wordpress/react-i18n';
import { useMemo } from 'react';
import { getEnvironmentLabel } from 'src/modules/sync/lib/environment-utils';
import { EnvironmentType } from 'src/modules/sync/lib/environment-utils';

export const useSyncDialogTexts = ( type: 'pull' | 'push', envType: string ) => {
type TextByEnvironment = {
[ key in EnvironmentType ]: {
title: string;
description: string;
};
};

type SyncDialogTexts = {
title: string;
description: string;
fromLabel: string;
toLabel: string;
subtitleSelector: string;
envSync: string;
submit: string;
};

export const useSyncDialogTexts = (
type: 'pull' | 'push',
siteEnv: EnvironmentType
): SyncDialogTexts => {
const { __ } = useI18n();

return useMemo( () => {
const envLabel = getEnvironmentLabel( envType );

if ( type === 'pull' ) {
const textByEnvironment: TextByEnvironment = {
production: {
title: __( 'Pull from Production' ),
description: __(
"Pulling will overwrite your Studio site's selected files and database with a copy from your production site. Unchecked items will not be changed."
),
},
staging: {
title: __( 'Pull from Staging' ),
description: __(
"Pulling will overwrite your Studio site's selected files and database with a copy from your staging site. Unchecked items will not be changed."
),
},
development: {
title: __( 'Pull from Development' ),
description: __(
"Pulling will overwrite your Studio site's selected files and database with a copy from your development site. Unchecked items will not be changed."
),
},
local: {
title: __( 'Pull from remote Local' ),
description: __(
"Pulling will overwrite your Studio site's selected files and database with a copy from your remote site with local environment. Unchecked items will not be changed."
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't sound very clear.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for linking those, makes sense.

),
},
};
return {
/* translators: %s is the environment name (e.g., "Production", "Staging", "Sandbox") */
title: sprintf( __( 'Pull from %s' ), envLabel ),
/* translators: %s is the environment type (e.g., "production", "staging", "sandbox") */
description: sprintf(
__(
"Pulling will overwrite your Studio site's selected files and database with a copy from your %s site. Unchecked items will not be changed."
),
envType
),
title: textByEnvironment[ siteEnv ].title,
description: textByEnvironment[ siteEnv ].description,
fromLabel: __( 'Pull' ),
toLabel: __( 'To' ),
subtitleSelector: __( 'What would you like to pull?' ),
envSync: __( 'Read more about <a>environment pull <ArrowIcon /></a>' ),
submit: __( 'Pull' ),
};
} else {
const textByEnvironment: TextByEnvironment = {
production: {
title: __( 'Push to Production' ),
description: __(
"Pushing will overwrite your production site's selected files and database with content from your Studio site. Unchecked items will not be changed. The production site will be backed up before any changes are applied."
),
},
staging: {
title: __( 'Push to Staging' ),
description: __(
"Pushing will overwrite your staging site's selected files and database with content from your Studio site. Unchecked items will not be changed. The staging site will be backed up before any changes are applied."
),
},
development: {
title: __( 'Push to Development' ),
description: __(
"Pushing will overwrite your development site's selected files and database with content from your Studio site. Unchecked items will not be changed. The development site will be backed up before any changes are applied."
),
},
local: {
title: __( 'Push to remote Local' ),
description: __(
"Pushing will overwrite your remote site's selected files and database with content from your Studio site. Unchecked items will not be changed. The remote site will be backed up before any changes are applied."
),
},
};
return {
/* translators: %s is the environment name (e.g., "Production", "Staging", "Sandbox") */
title: sprintf( __( 'Push to %s' ), envLabel ),
/* translators: first %1s is the environment type, which is used twice in the sentence (e.g., "production", "staging", "sandbox") */
description: sprintf(
__(
"Pushing will overwrite your %s site's selected files and database with content from your local site. Unchecked items will not be changed. The %1s site will be backed up before any changes are applied."
),
envType
),
title: textByEnvironment[ siteEnv ].title,
description: textByEnvironment[ siteEnv ].description,
fromLabel: __( 'Push' ),
toLabel: __( 'To' ),
subtitleSelector: __( 'What would you like to push?' ),
envSync: __( 'Read more about <a>environment push <ArrowIcon /></a>' ),
submit: __( 'Push' ),
};
}
}, [ envType, type, __ ] );
}, [ type, __, siteEnv ] );
};
12 changes: 7 additions & 5 deletions src/modules/sync/lib/environment-utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { __ } from '@wordpress/i18n';
import { z } from 'zod';
import { SyncSite } from 'src/hooks/use-fetch-wpcom-sites/types';

export const getSiteEnvironment = ( connectedSite: SyncSite ): string => {
if ( connectedSite.isPressable ) {
return connectedSite.environmentType ?? 'production';
}
return connectedSite.isStaging ? 'staging' : 'production';
const EnvironmentSchema = z.enum( [ 'production', 'staging', 'development', 'local' ] );
export type EnvironmentType = z.infer< typeof EnvironmentSchema >;

export const getSiteEnvironment = ( site: SyncSite ): EnvironmentType => {
const parsed = EnvironmentSchema.safeParse( site.environmentType );
return parsed.success ? parsed.data : 'production';
};

export const getEnvironmentLabel = ( type: string ): string => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I was going to mention that this also would need to be updated but I see that it is being implemented in https://github.com/Automattic/studio/pull/1645/files 👍

Expand Down
64 changes: 52 additions & 12 deletions src/modules/sync/tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ describe( 'ContentTabSync', () => {
isStaging: false,
stagingSiteIds: [ 7 ],
syncSupport: 'already-connected',
environmentType: 'production',
};
const fakeStagingSite = {
id: 7,
Expand All @@ -225,6 +226,7 @@ describe( 'ContentTabSync', () => {
isStaging: true,
stagingSiteIds: [],
syncSupport: 'already-connected',
environmentType: 'staging',
};
( useAuth as jest.Mock ).mockReturnValue( { isAuthenticated: true, authenticate: jest.fn() } );

Expand Down Expand Up @@ -332,7 +334,7 @@ describe( 'ContentTabSync', () => {
expect( connectButton ).toBeInTheDocument();
} );

it( 'displays environment badges for Pressable sites with production, staging and sandbox environments', () => {
it( 'displays environment badges for Pressable sites with production, staging and development environments', () => {
const fakePressableProductionSite = {
id: 6,
name: 'My Pressable Production site',
Expand All @@ -353,13 +355,13 @@ describe( 'ContentTabSync', () => {
stagingSiteIds: [],
syncSupport: 'already-connected',
};
const fakePressableSandboxSite = {
const fakePressableDevelopmentSite = {
id: 8,
name: 'My Pressable Sandbox site',
url: 'https://sandbox-pressable-site.com',
name: 'My Pressable Development site',
url: 'https://development-pressable-site.com',
isStaging: false,
isPressable: true,
environmentType: 'sandbox',
environmentType: 'development',
stagingSiteIds: [],
syncSupport: 'already-connected',
};
Expand All @@ -368,7 +370,7 @@ describe( 'ContentTabSync', () => {
connectedSites: [
fakePressableProductionSite,
fakePressableStagingSite,
fakePressableSandboxSite,
fakePressableDevelopmentSite,
],
syncSites: [ fakePressableProductionSite ],
pullSite: jest.fn(),
Expand All @@ -387,11 +389,11 @@ describe( 'ContentTabSync', () => {

expect( screen.getByText( fakePressableProductionSite.name ) ).toBeInTheDocument();
expect( screen.getByText( fakePressableStagingSite.name ) ).toBeInTheDocument();
expect( screen.getByText( fakePressableSandboxSite.name ) ).toBeInTheDocument();
expect( screen.getByText( fakePressableDevelopmentSite.name ) ).toBeInTheDocument();

expect( screen.getByText( 'Production' ) ).toBeInTheDocument();
expect( screen.getByText( 'Staging' ) ).toBeInTheDocument();
expect( screen.getByText( 'Sandbox' ) ).toBeInTheDocument();
expect( screen.getByText( 'Development' ) ).toBeInTheDocument();
} );
it( 'displays the progress bar when the site is being pushed', () => {
( useAuth as jest.Mock ).mockReturnValue( { isAuthenticated: true, authenticate: jest.fn() } );
Expand Down Expand Up @@ -420,7 +422,7 @@ describe( 'ContentTabSync', () => {
expect( screen.getByRole( 'progressbar' ) ).toBeInTheDocument();
} );

it( 'opens sync pullSite dialog with sandbox environment label', async () => {
it( 'opens sync pullSite dialog with development environment label', async () => {
const mockPullSite = jest.fn();
( useAuth as jest.Mock ).mockReturnValue( { isAuthenticated: true, authenticate: jest.fn() } );
const fakeSyncSite = {
Expand All @@ -429,7 +431,7 @@ describe( 'ContentTabSync', () => {
url: 'https:/developer.wordpress.com/studio/',
syncSupport: 'already-connected',
isPressable: true,
environmentType: 'sandbox',
environmentType: 'development',
};
( useSyncSites as jest.Mock ).mockReturnValue( {
connectedSites: [ fakeSyncSite ],
Expand All @@ -452,9 +454,47 @@ describe( 'ContentTabSync', () => {
expect( pullButton ).toBeInTheDocument();
fireEvent.click( pullButton );

await screen.findByText( 'Pull from Sandbox' );
await screen.findByText( 'Pull from Development' );
await screen.findByText(
"Pulling will overwrite your Studio site's selected files and database with a copy from your development site. Unchecked items will not be changed."
);
} );

it( 'opens sync pullSite dialog and displays production when the environment is not supported', async () => {
const mockPullSite = jest.fn();
( useAuth as jest.Mock ).mockReturnValue( { isAuthenticated: true, authenticate: jest.fn() } );
const fakeSyncSite = {
id: 6,
name: 'My simple business site that needs a transfer',
url: 'https:/developer.wordpress.com/studio/',
syncSupport: 'already-connected',
isPressable: true,
environmentType: 'non-supported-environment-example-or-sandbox',
};
( useSyncSites as jest.Mock ).mockReturnValue( {
connectedSites: [ fakeSyncSite ],
syncSites: [ fakeSyncSite ],
pullSite: mockPullSite,
isAnySitePulling: false,
isAnySitePushing: false,
getPullState: jest.fn(),
getPushState: jest.fn(),
refetchSites: jest.fn(),
getLastSyncTimeText: jest.fn().mockReturnValue( 'You have not pulled this site yet.' ),
isSiteIdPulling: jest.fn(),
isSiteIdPushing: jest.fn(),
clearTimeout: jest.fn(),
} );

renderWithProvider( <ContentTabSync selectedSite={ selectedSite } /> );

const pullButton = screen.getByRole( 'button', { name: /Pull/i } );
expect( pullButton ).toBeInTheDocument();
fireEvent.click( pullButton );

await screen.findByText( 'Pull from Production' );
await screen.findByText(
"Pulling will overwrite your Studio site's selected files and database with a copy from your sandbox site. Unchecked items will not be changed."
"Pulling will overwrite your Studio site's selected files and database with a copy from your production site. Unchecked items will not be changed."
);
} );

Expand Down