Skip to content

Commit

Permalink
Merge pull request #8882 from google/enhancement/6819-google-tag-conf…
Browse files Browse the repository at this point in the history
…iguration-banner

Google tag configuration banner
  • Loading branch information
eugene-manuilov committed Jun 19, 2024
2 parents e7b8283 + 8e5b743 commit 0b4c6e5
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { mockLocation } from '../../../../tests/js/mock-browser-utils';
import BannerNotifications from './BannerNotifications';
import Header from '../Header';
import { MODULES_ANALYTICS_4 } from '../../modules/analytics-4/datastore/constants';

describe( 'BannerNotifications', () => {
mockLocation();
Expand Down Expand Up @@ -93,6 +94,9 @@ describe( 'BannerNotifications', () => {
registry.dispatch( CORE_USER ).receiveGetSurvey( { survey: null } );
registry.dispatch( CORE_SITE ).receiveGetNotifications( [] );
registry.dispatch( CORE_USER ).receiveNonces( [] );
registry
.dispatch( MODULES_ANALYTICS_4 )
.receiveHasMismatchGoogleTagID( false );
} );

it( 'should render the `authentication_success` notification if the `authentication_success` query param value is passed', async () => {
Expand Down
73 changes: 70 additions & 3 deletions assets/js/modules/analytics-4/datastore/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* External dependencies
*/
import invariant from 'invariant';
import { isBoolean } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -168,6 +169,35 @@ const fetchGetGoogleTagSettingsStore = createFetchStore( {
},
} );

const fetchSetGoogleTagIDMismatch = createFetchStore( {
baseName: 'setGoogleTagIDMismatch',
controlCallback( { hasMismatchedTag } ) {
return API.set(
'modules',
'analytics-4',
'set-google-tag-id-mismatch',
{
hasMismatchedTag,
}
);
},
reducerCallback( state, hasMismatchedTag ) {
return {
...state,
hasMismatchedTag: !! hasMismatchedTag,
};
},
argsToParams( hasMismatchedTag ) {
return { hasMismatchedTag };
},
validateParams( { hasMismatchedTag } = {} ) {
invariant(
isBoolean( hasMismatchedTag ),
'hasMismatchedTag must be boolean.'
);
},
} );

// Actions
const WAIT_FOR_PROPERTY_SUMMARIES = 'WAIT_FOR_PROPERTY_SUMMARIES';
const MATCHING_ACCOUNT_PROPERTY = 'MATCHING_ACCOUNT_PROPERTY';
Expand All @@ -177,7 +207,7 @@ const SET_IS_WEBDATASTREAM_AVAILABLE = 'SET_IS_WEBDATASTREAM_AVAILABLE';
const baseInitialState = {
properties: {},
propertiesByID: {},
hasMismatchedTag: false,
hasMismatchedTag: undefined,
isMatchingAccountProperty: false,
isWebDataStreamAvailable: true,
};
Expand Down Expand Up @@ -563,14 +593,28 @@ const baseActions = {
* Sets if GA4 has mismatched Google Tag ID.
*
* @since 1.96.0
* @since n.e.x.t Updated to send value to the endpoint.
*
* @param {boolean} hasMismatchedTag If GA4 has mismatched Google Tag.
* @return {Object} Redux-style action.
*/
*setHasMismatchedGoogleTagID( hasMismatchedTag ) {
yield fetchSetGoogleTagIDMismatch.actions.fetchSetGoogleTagIDMismatch(
hasMismatchedTag
);
},

/**
* Sets if GA4 has mismatched Google Tag ID.
*
* @since n.e.x.t
*
* @param {boolean} hasMismatchedTag If GA4 has mismatched Google Tag.
* @return {Object} Redux-style action.
*/
*receiveHasMismatchGoogleTagID( hasMismatchedTag ) {
return {
type: SET_HAS_MISMATCHED_TAG,
payload: { hasMismatchedTag },
payload: { hasMismatchedTag: !! hasMismatchedTag },
};
},

Expand Down Expand Up @@ -804,6 +848,28 @@ const baseResolvers = {
.dispatch( MODULES_ANALYTICS_4 )
.setPropertyCreateTime( property.createTime );
},
*hasMismatchedGoogleTagID() {
const registry = yield Data.commonActions.getRegistry();

const hasMismatchedTag = registry
.select( MODULES_ANALYTICS_4 )
.hasMismatchedGoogleTagID();

if ( hasMismatchedTag === undefined ) {
if ( ! global._googlesitekitModulesData ) {
global.console.error(
'Could not load modules/analytics-4 data.'
);
return;
}

const tagIDMismatch =
global._googlesitekitModulesData?.[ 'analytics-4' ]
?.tagIDMismatch;

yield actions.receiveHasMismatchGoogleTagID( tagIDMismatch );
}
},
};

const baseSelectors = {
Expand Down Expand Up @@ -922,6 +988,7 @@ const store = Data.combineStores(
fetchGetPropertiesStore,
fetchGetPropertyStore,
fetchGetGoogleTagSettingsStore,
fetchSetGoogleTagIDMismatch,
{
initialState: baseInitialState,
actions: baseActions,
Expand Down
77 changes: 69 additions & 8 deletions assets/js/modules/analytics-4/datastore/properties.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ describe( 'modules/analytics-4 properties', () => {
const containerDestinationsEndpoint = new RegExp(
'^/google-site-kit/v1/modules/analytics-4/data/container-destinations'
);
const setGoogleTagIDMismatchEndpoint = new RegExp(
'^/google-site-kit/v1/modules/analytics-4/data/set-google-tag-id-mismatch'
);

const containerDestinationsMock =
fixtures.containerDestinations[ 6065484567 ][ 98369876 ];
Expand Down Expand Up @@ -703,11 +706,19 @@ describe( 'modules/analytics-4 properties', () => {

describe( 'setHasMismatchedGoogleTagID', () => {
it( 'sets the value of hasMismatchedGoogleTagID', async () => {
fetchMock.post( setGoogleTagIDMismatchEndpoint, {
body: true,
status: 200,
} );

registry
.dispatch( MODULES_ANALYTICS_4 )
.receiveHasMismatchGoogleTagID( false );

const hasMismatchedGoogleTagID = registry
.select( MODULES_ANALYTICS_4 )
.hasMismatchedGoogleTagID();

// It is false by default.
expect( hasMismatchedGoogleTagID ).toBe( false );

await registry
Expand Down Expand Up @@ -975,6 +986,12 @@ describe( 'modules/analytics-4 properties', () => {
} );

it( 'should set `isWebDataStreamAvailable` to `false` when there is no Google Tag Container available', async () => {
global._googlesitekitModulesData = {
'analytics-4': {
tagIDMismatch: false,
},
};

provideUserAuthentication( registry, {
grantedScopes: [ TAGMANAGER_READ_SCOPE ],
} );
Expand Down Expand Up @@ -1059,11 +1076,25 @@ describe( 'modules/analytics-4 properties', () => {
.isWebDataStreamAvailable()
).toBe( false );

// Initially undefined.
expect(
registry
.select( MODULES_ANALYTICS_4 )
.hasMismatchedGoogleTagID()
).toBe( undefined );

await untilResolved(
registry,
MODULES_ANALYTICS_4
).hasMismatchedGoogleTagID();

expect(
registry
.select( MODULES_ANALYTICS_4 )
.hasMismatchedGoogleTagID()
).toBe( false );

delete global._googlesitekitModulesData;
} );

it( 'should check for mismatched Google Tag ID if Google Tag settings already exist', async () => {
Expand Down Expand Up @@ -1119,6 +1150,11 @@ describe( 'modules/analytics-4 properties', () => {
status: 200,
} );

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

await registry
.dispatch( MODULES_ANALYTICS_4 )
.syncGoogleTagSettings();
Expand All @@ -1127,7 +1163,7 @@ describe( 'modules/analytics-4 properties', () => {
.select( MODULES_ANALYTICS_4 )
.getGoogleTagLastSyncedAtMs();

expect( fetchMock ).toHaveFetchedTimes( 3 );
expect( fetchMock ).toHaveFetchedTimes( 4 );
expect( fetchMock ).toHaveFetched( containerLookupEndpoint, {
query: {
destinationID: measurementID,
Expand Down Expand Up @@ -1215,6 +1251,11 @@ describe( 'modules/analytics-4 properties', () => {
status: 200,
} );

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

await registry
.dispatch( MODULES_ANALYTICS_4 )
.syncGoogleTagSettings();
Expand Down Expand Up @@ -1625,23 +1666,43 @@ describe( 'modules/analytics-4 properties', () => {
} );

describe( 'hasMismatchedGoogleTagID', () => {
it( 'returns a specific key in state', () => {
it( 'should use a resolver to source value from global', async () => {
global._googlesitekitModulesData = {
'analytics-4': {
tagIDMismatch: false,
},
};

const initialHasMismatchedGoogleTagID = registry
.select( MODULES_ANALYTICS_4 )
.hasMismatchedGoogleTagID();

expect( initialHasMismatchedGoogleTagID ).toBeUndefined();

await untilResolved(
registry,
MODULES_ANALYTICS_4
).hasMismatchedGoogleTagID();

const hasMismatchedGoogleTagID = registry
.select( MODULES_ANALYTICS_4 )
.hasMismatchedGoogleTagID();

// It is false by default.
expect( hasMismatchedGoogleTagID ).toBe( false );
expect( hasMismatchedGoogleTagID ).toEqual( false );

delete global._googlesitekitModulesData;
} );

it( 'should not source data from global if the value is already present', () => {
registry
.dispatch( MODULES_ANALYTICS_4 )
.setHasMismatchedGoogleTagID( true );
.receiveHasMismatchGoogleTagID( true );

const updatedHasMismatchedGoogleTagID = registry
const hasMismatchedGoogleTagID = registry
.select( MODULES_ANALYTICS_4 )
.hasMismatchedGoogleTagID();

expect( updatedHasMismatchedGoogleTagID ).toBe( true );
expect( hasMismatchedGoogleTagID ).toBe( true );
} );
} );

Expand Down
42 changes: 41 additions & 1 deletion includes/Modules/Analytics_4.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,9 @@ function ( $new_value, $old_value ) {
2
);

add_filter( 'googlesitekit_inline_modules_data', $this->get_method_proxy( 'inline_custom_dimensions_data' ) );
add_filter( 'googlesitekit_inline_modules_data', $this->get_method_proxy( 'inline_custom_dimensions_data' ), 10 );

add_filter( 'googlesitekit_inline_modules_data', $this->get_method_proxy( 'inline_tag_id_mismatch' ), 15 );

if ( Feature_Flags::enabled( 'audienceSegmentation' ) ) {
add_filter( 'googlesitekit_inline_modules_data', $this->get_method_proxy( 'inline_resource_availability_dates_data' ) );
Expand Down Expand Up @@ -633,6 +635,9 @@ protected function get_datapoint_definitions() {
'POST:custom-dimension-data-available' => array(
'service' => '',
),
'POST:set-google-tag-id-mismatch' => array(
'service' => '',
),
);

if ( Feature_Flags::enabled( 'audienceSegmentation' ) ) {
Expand Down Expand Up @@ -1585,6 +1590,20 @@ protected function create_data_request( Data_Request $data ) {
return $analyticsadmin
->properties_conversionEvents // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
->listPropertiesConversionEvents( $property_id );
case 'POST:set-google-tag-id-mismatch':
if ( ! isset( $data['hasMismatchedTag'] ) ) {
throw new Missing_Required_Param_Exception( 'hasMismatchedTag' );
}

if ( false === $data['hasMismatchedTag'] ) {
return function() {
return $this->transients->delete( 'googlesitekit_inline_tag_id_mismatch' );
};
}

return function() use ( $data ) {
return $this->transients->set( 'googlesitekit_inline_tag_id_mismatch', $data['hasMismatchedTag'] );
};
}

return parent::create_data_request( $data );
Expand Down Expand Up @@ -2248,6 +2267,27 @@ private function inline_custom_dimensions_data( $modules_data ) {
return $modules_data;
}

/**
* Populates tag ID mismatch value to pass to JS via _googlesitekitModulesData.
*
* @since n.e.x.t
*
* @param array $modules_data Inline modules data.
* @return array Inline modules data.
*/
protected function inline_tag_id_mismatch( $modules_data ) {
if ( $this->is_connected() ) {
$tag_id_mismatch = $this->transients->get( 'googlesitekit_inline_tag_id_mismatch' );

// Add the data under the `analytics-4` key to make it clear it's scoped to this module.
// No need to check if `analytics-4` key is present, as this hook is added with higher
// priority than inline_custom_dimensions_data where this key is set.
$modules_data['analytics-4']['tagIDMismatch'] = $tag_id_mismatch;
}

return $modules_data;
}

/**
* Populates resource availability dates data to pass to JS via _googlesitekitModulesData.
*
Expand Down
Loading

0 comments on commit 0b4c6e5

Please sign in to comment.