Skip to content

Commit

Permalink
Merge branch 'develop' into enhancement/9889-refactor-rrm-setup-cta-b…
Browse files Browse the repository at this point in the history
…anner.
  • Loading branch information
jimmymadon committed Jan 9, 2025
2 parents 2606b6a + db29821 commit 753116d
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 112 deletions.
19 changes: 15 additions & 4 deletions assets/js/components/notifications/FirstPartyModeSetupBanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/**
* WordPress dependencies
*/
import { Fragment, useEffect } from '@wordpress/element';
import { Fragment, useCallback, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
Expand All @@ -36,6 +36,7 @@ import {
NOTIFICATION_GROUPS,
} from '../../googlesitekit/notifications/datastore/constants';
import { CORE_SITE } from '../../googlesitekit/datastore/site/constants';
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { CORE_UI } from '../../googlesitekit/datastore/ui/constants';
import Description from '../../googlesitekit/notifications/components/common/Description';
import LearnMoreLink from '../../googlesitekit/notifications/components/common/LearnMoreLink';
Expand All @@ -50,8 +51,7 @@ import {
useBreakpoint,
} from '../../hooks/useBreakpoint';
import useViewContext from '../../hooks/useViewContext';
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { trackEvent } from '../../util';
import { DAY_IN_SECONDS, trackEvent } from '../../util';

export const FPM_SHOW_SETUP_SUCCESS_NOTIFICATION =
'fpm-show-setup-success-notification';
Expand All @@ -67,6 +67,10 @@ export default function FirstPartyModeSetupBanner( { id, Notification } ) {

const { isTooltipVisible } = useTooltipState( id );

const usingProxy = useSelect( ( select ) =>
select( CORE_SITE ).isUsingProxy()
);

const isItemDismissed = useSelect( ( select ) =>
select( CORE_NOTIFICATIONS ).isNotificationDismissed( id )
);
Expand Down Expand Up @@ -104,6 +108,13 @@ export default function FirstPartyModeSetupBanner( { id, Notification } ) {
dismissNotification( id );
};

const { triggerSurvey } = useDispatch( CORE_USER );
const handleView = useCallback( () => {
if ( usingProxy ) {
triggerSurvey( 'view_fpm_setup_cta', { ttl: DAY_IN_SECONDS } );
}
}, [ triggerSurvey, usingProxy ] );

const onDismiss = () => {
showTooltip();
};
Expand Down Expand Up @@ -140,7 +151,7 @@ export default function FirstPartyModeSetupBanner( { id, Notification } ) {
};

return (
<Notification>
<Notification onView={ handleView }>
<NotificationWithSVG
id={ id }
title={ __(
Expand Down
19 changes: 14 additions & 5 deletions assets/js/googlesitekit/datastore/site/first-party-mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ import {
createReducer,
} from 'googlesitekit-data';
import { CORE_SITE } from './constants';
import { CORE_USER } from '../user/constants';
import { CORE_MODULES } from '../../modules/datastore/constants';
import { createFetchStore } from '../../data/create-fetch-store';
import { isFeatureEnabled } from '../../../features';
import { CORE_MODULES } from '../../modules/datastore/constants';

const SET_FIRST_PARTY_MODE_ENABLED = 'SET_FIRST_PARTY_MODE_ENABLED';
const RESET_FIRST_PARTY_MODE_SETTINGS = 'RESET_FIRST_PARTY_MODE_SETTINGS';
Expand Down Expand Up @@ -103,16 +104,24 @@ const baseActions = {
* Saves the first-party mode settings.
*
* @since 1.141.0
* @since n.e.x.t Added the survey trigger.
*
* @return {Object} Object with `response` and `error`.
*/
*saveFirstPartyModeSettings() {
const { select } = yield commonActions.getRegistry();
const { dispatch, select } = yield commonActions.getRegistry();
const settings = select( CORE_SITE ).getFirstPartyModeSettings();

return yield fetchSaveFirstPartyModeSettingsStore.actions.fetchSaveFirstPartyModeSettings(
settings
);
const results =
yield fetchSaveFirstPartyModeSettingsStore.actions.fetchSaveFirstPartyModeSettings(
settings
);

if ( results?.response?.isEnabled ) {
dispatch( CORE_USER ).triggerSurvey( 'fpm_setup_completed' );
}

return results;
},

/**
Expand Down
101 changes: 99 additions & 2 deletions assets/js/googlesitekit/datastore/site/first-party-mode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,26 @@
* limitations under the License.
*/

/**
* External dependencies
*/
import { waitFor } from '@testing-library/react';

/**
* Internal dependencies
*/
import API from 'googlesitekit-api';
import {
createTestRegistry,
muteFetch,
provideUserAuthentication,
subscribeUntil,
untilResolved,
waitForDefaultTimeouts,
} from '../../../../../tests/js/utils';
import { CORE_SITE } from './constants';
import { surveyTriggerEndpoint } from '../../../../../tests/js/mock-survey-endpoints';
import { CORE_USER } from '../user/constants';

describe( 'core/site First-party Mode', () => {
let registry;
Expand All @@ -48,6 +57,15 @@ describe( 'core/site First-party Mode', () => {
describe( 'actions', () => {
describe( 'saveFirstPartyModeSettings', () => {
it( 'saves the settings and returns the response', async () => {
provideUserAuthentication( registry );

registry.dispatch( CORE_USER ).receiveGetSurveyTimeouts( [] );

fetchMock.postOnce( surveyTriggerEndpoint, {
status: 200,
body: {},
} );

const updatedSettings = {
isEnabled: true,
isFPMHealthy: false,
Expand Down Expand Up @@ -88,6 +106,8 @@ describe( 'core/site First-party Mode', () => {
);

expect( response ).toEqual( updatedSettings );

await waitForDefaultTimeouts();
} );

it( 'returns an error if the request fails', async () => {
Expand Down Expand Up @@ -134,6 +154,83 @@ describe( 'core/site First-party Mode', () => {

expect( console ).toHaveErrored();
} );

it( 'should trigger the FPM setup completed survey when FPM setting is enabled', async () => {
provideUserAuthentication( registry );

registry.dispatch( CORE_USER ).receiveGetSurveyTimeouts( [] );

fetchMock.postOnce( surveyTriggerEndpoint, {
status: 200,
body: { triggerID: 'fpm_setup_completed' },
} );

fetchMock.postOnce( firstPartyModeSettingsEndpointRegExp, {
body: {
isEnabled: true,
isFPMHealthy: true,
isScriptAccessEnabled: true,
},
status: 200,
} );

registry
.dispatch( CORE_SITE )
.receiveGetFirstPartyModeSettings( {
isEnabled: false,
isFPMHealthy: true,
isScriptAccessEnabled: true,
} );

registry.dispatch( CORE_SITE ).setFirstPartyModeEnabled( true );

await registry
.dispatch( CORE_SITE )
.saveFirstPartyModeSettings();

// Verify survey was triggered when FPM setting is set to true.
await waitFor( () =>
expect( fetchMock ).toHaveFetched( surveyTriggerEndpoint, {
body: {
data: { triggerID: 'fpm_setup_completed' },
},
} )
);
} );

it( 'should not trigger the FPM setup completed survey when FPM setting is disabled', async () => {
fetchMock.postOnce( firstPartyModeSettingsEndpointRegExp, {
body: {
isEnabled: false,
isFPMHealthy: true,
isScriptAccessEnabled: true,
},
status: 200,
} );

registry
.dispatch( CORE_SITE )
.receiveGetFirstPartyModeSettings( {
isEnabled: true,
isFPMHealthy: true,
isScriptAccessEnabled: true,
} );

registry
.dispatch( CORE_SITE )
.setFirstPartyModeEnabled( false );

await registry
.dispatch( CORE_SITE )
.saveFirstPartyModeSettings();

// Verify survey was not triggered when FPM setting is set to false.
expect( fetchMock ).not.toHaveFetched( surveyTriggerEndpoint, {
body: {
data: { triggerID: 'fpm_setup_completed' },
},
} );
} );
} );

describe( 'setFirstPartyModeEnabled', () => {
Expand All @@ -142,8 +239,8 @@ describe( 'core/site First-party Mode', () => {
.dispatch( CORE_SITE )
.receiveGetFirstPartyModeSettings( {
isEnabled: false,
isFPMHealthy: false,
isScriptAccessEnabled: false,
isFPMHealthy: true,
isScriptAccessEnabled: true,
} );

expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export default function Notification( {
className,
gaTrackingEventArgs,
children,
onView,
} ) {
const ref = useRef();
const viewed = useHasBeenViewed( id );
Expand All @@ -53,9 +54,12 @@ export default function Notification( {
gaTrackingEventArgs?.label,
gaTrackingEventArgs?.value
);

onView?.();

setIsViewedOnce( true );
}
}, [ viewed, trackEvents, isViewedOnce, gaTrackingEventArgs ] );
}, [ viewed, trackEvents, isViewedOnce, gaTrackingEventArgs, onView ] );

return (
<section id={ id } ref={ ref } className={ className }>
Expand All @@ -81,4 +85,5 @@ Notification.propTypes = {
value: PropTypes.string,
} ),
children: PropTypes.node,
onView: PropTypes.func,
};
36 changes: 36 additions & 0 deletions assets/js/modules/ads/datastore/settings.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import API from 'googlesitekit-api';
import {
createTestRegistry,
provideNotifications,
provideUserAuthentication,
waitForDefaultTimeouts,
} from '../../../../../tests/js/utils';
import { surveyTriggerEndpoint } from '../../../../../tests/js/mock-survey-endpoints';
import { INVARIANT_SETTINGS_NOT_CHANGED } from '../../../googlesitekit/data/create-settings-store';
import { DEFAULT_NOTIFICATIONS } from '../../../googlesitekit/notifications/register-defaults';
import { FPM_SETUP_CTA_BANNER_NOTIFICATION } from '../../../googlesitekit/notifications/constants';
Expand Down Expand Up @@ -94,6 +97,15 @@ describe( 'modules/ads settings', () => {
} );

it( 'should send a POST request to the FPM settings endpoint when the toggle state is changed', async () => {
provideUserAuthentication( registry );

registry.dispatch( CORE_USER ).receiveGetSurveyTimeouts( [] );

fetchMock.postOnce( surveyTriggerEndpoint, {
status: 200,
body: {},
} );

registry.dispatch( CORE_SITE ).receiveGetFirstPartyModeSettings( {
isEnabled: false,
isFPMHealthy: true,
Expand Down Expand Up @@ -149,6 +161,8 @@ describe( 'modules/ads settings', () => {
},
},
} );

await waitForDefaultTimeouts();
} );

it( 'should handle an error when sending a POST request to the FPM settings endpoint', async () => {
Expand Down Expand Up @@ -196,6 +210,15 @@ describe( 'modules/ads settings', () => {
} );

it( 'should dismiss the FPM setup CTA banner when the FPM `isEnabled` setting is changed to `true`', async () => {
provideUserAuthentication( registry );

registry.dispatch( CORE_USER ).receiveGetSurveyTimeouts( [] );

fetchMock.postOnce( surveyTriggerEndpoint, {
status: 200,
body: {},
} );

provideNotifications(
registry,
{
Expand Down Expand Up @@ -254,9 +277,20 @@ describe( 'modules/ads settings', () => {
},
} );
expect( fetchMock ).toHaveFetchedTimes( 3 );

await waitForDefaultTimeouts();
} );

it( 'should handle an error when dismissing the FPM setup CTA banner', async () => {
provideUserAuthentication( registry );

registry.dispatch( CORE_USER ).receiveGetSurveyTimeouts( [] );

fetchMock.postOnce( surveyTriggerEndpoint, {
status: 200,
body: {},
} );

provideNotifications(
registry,
{
Expand Down Expand Up @@ -310,6 +344,8 @@ describe( 'modules/ads settings', () => {

expect( submitChangesError ).toEqual( error );
expect( console ).toHaveErrored();

await waitForDefaultTimeouts();
} );

it( 'should not dismiss the FPM setup CTA banner when the FPM `isEnabled` setting is changed to `false`', async () => {
Expand Down
Loading

0 comments on commit 753116d

Please sign in to comment.