Skip to content

Commit

Permalink
Merge pull request #8701 from google/enhancement/8687-pax-date-range
Browse files Browse the repository at this point in the history
Enhancement/8687 pax date range
  • Loading branch information
tofumatt committed May 15, 2024
2 parents a9d6b00 + 296e040 commit ac4763c
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 3 deletions.
54 changes: 51 additions & 3 deletions assets/js/modules/ads/components/common/PAXEmbeddedApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@ import { __ } from '@wordpress/i18n';
* Internal dependencies
*/
import Data from 'googlesitekit-data';
import { CORE_USER } from '../../../../googlesitekit/datastore/user/constants';
import CTA from '../../../../components/notifications/CTA';
import PreviewBlock from '../../../../components/PreviewBlock';
import CTA from '../../../../components/notifications/CTA';
import { CORE_USER } from '../../../../googlesitekit/datastore/user/constants';
import { DATE_RANGE_OFFSET } from '../../../analytics-4/datastore/constants';
import { createPaxServices } from '../../pax/services';
import { useMemoOne } from 'use-memo-one';
import { formatPaxDate } from '../../pax/utils';

const { useRegistry, useSelect } = Data;
export default function PAXEmbeddedApp( {
displayMode = 'default',
Expand All @@ -64,6 +67,16 @@ export default function PAXEmbeddedApp( {
return createPaxServices( registry );
}, [ registry ] );

const paxDateRange = useSelect( ( select ) => {
if ( displayMode !== 'reporting' ) {
return null;
}

return select( CORE_USER ).getDateRangeDates( {
offsetDays: DATE_RANGE_OFFSET,
} );
} );

const isAdBlockerActive = useSelect( ( select ) =>
select( CORE_USER ).isAdBlockerActive()
);
Expand Down Expand Up @@ -93,6 +106,20 @@ export default function PAXEmbeddedApp( {
};
}, [ elementID, displayMode ] );

const setDateRangeForReportingMode = useCallback( () => {
if (
displayMode === 'reporting' &&
paxAppRef?.current &&
paxDateRange.startDate &&
paxDateRange.endDate
) {
paxAppRef.current.getServices().adsDateRangeService.update( {
startDate: formatPaxDate( paxDateRange.startDate ),
endDate: formatPaxDate( paxDateRange.endDate ),
} );
}
}, [ displayMode, paxDateRange.endDate, paxDateRange.startDate ] );

const launchPAXApp = useCallback( async () => {
if ( hasLaunchedPAXApp || paxAppRef.current ) {
return;
Expand All @@ -107,6 +134,8 @@ export default function PAXEmbeddedApp( {
paxServices
);

setDateRangeForReportingMode();

onLaunch?.( paxAppRef.current );
} catch ( error ) {
setLaunchError( error );
Expand All @@ -117,7 +146,13 @@ export default function PAXEmbeddedApp( {
}

setIsLoading( false );
}, [ hasLaunchedPAXApp, paxConfig, paxServices, onLaunch ] );
}, [
hasLaunchedPAXApp,
paxConfig,
paxServices,
setDateRangeForReportingMode,
onLaunch,
] );

useInterval(
() => {
Expand Down Expand Up @@ -149,6 +184,19 @@ export default function PAXEmbeddedApp( {
launchPAXApp,
] );

useEffect( () => {
setDateRangeForReportingMode();
}, [
setDateRangeForReportingMode,
// `setDateRangeForReportingMode` will change whenever the date range
// updates, causing this effect to run again, so the two date range
// dependencies are technically redundant, but are explicitly listed
// here to make the intent of the code clearer. (They're harmless
// to include and do not cause extra renders/requests.)
paxDateRange.startDate,
paxDateRange.endDate,
] );

return (
<div className="googlesitekit-pax-embedded-app">
{ !! launchError && ! isAdBlockerActive && (
Expand Down
34 changes: 34 additions & 0 deletions assets/js/modules/ads/pax/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import apiFetch from '@wordpress/api-fetch';
*/
import { CORE_SITE } from '../../../googlesitekit/datastore/site/constants';
import { MODULES_ADS } from '../datastore/constants';
import { formatPaxDate } from './utils';
import { CORE_USER } from '../../../googlesitekit/datastore/user/constants';
import { DATE_RANGE_OFFSET } from '../../analytics-4/datastore/constants';

const restFetchWpPages = async () => {
try {
Expand Down Expand Up @@ -59,6 +62,14 @@ export function createPaxServices( registry, _global = global ) {

return {
authenticationService: {
// Ignore the ESLint rule that requires `await` in the function body.
//
// We mark this function as `async` to make it clear that it returns a
// promise and in case, in the future, anything here wants to be async.
//
// Marking this function as `async` makes it clear that this will be
// allowed.
//
// eslint-disable-next-line require-await
get: async () => {
return { accessToken };
Expand Down Expand Up @@ -113,5 +124,28 @@ export function createPaxServices( registry, _global = global ) {
termsAndConditionsService: {
notify: async () => {},
},
partnerDateRangeService: {
// Ignore the ESLint rule that requires `await` in the function body.
//
// We mark this function as `async` to make it clear that it returns a
// promise and in case, in the future, anything here wants to be async.
//
// Marking this function as `async` makes it clear that this will be
// allowed.
//
// eslint-disable-next-line require-await
get: async () => {
const { startDate, endDate } = registry
.select( CORE_USER )
.getDateRangeDates( {
offsetDays: DATE_RANGE_OFFSET,
} );

return {
startDate: formatPaxDate( startDate ),
endDate: formatPaxDate( endDate ),
};
},
},
};
}
38 changes: 38 additions & 0 deletions assets/js/modules/ads/pax/services.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
createTestRegistry,
provideSiteInfo,
} from '../../../../../tests/js/utils';
import { CORE_USER } from '../../../googlesitekit/datastore/user/constants';
import { MODULES_ADS } from '../datastore/constants';
import { createPaxServices } from './services';

Expand Down Expand Up @@ -54,6 +55,9 @@ describe( 'PAX partner services', () => {
termsAndConditionsService: {
notify: expect.any( Function ),
},
partnerDateRangeService: expect.objectContaining( {
get: expect.any( Function ),
} ),
} );
} );

Expand Down Expand Up @@ -193,6 +197,40 @@ describe( 'PAX partner services', () => {
] );
} );
} );

describe( 'partnerDateRangeService', () => {
describe( 'get', () => {
it( 'should contain startDate and endDate properties', async () => {
const partnerDateRange =
await services.partnerDateRangeService.get();

expect( partnerDateRange ).toHaveProperty(
'startDate'
);
expect( partnerDateRange ).toHaveProperty( 'endDate' );
} );

it( 'should contain correct accessToken', async () => {
registry
.dispatch( CORE_USER )
.setReferenceDate( '2020-09-08' );

const partnerDateRange =
await services.partnerDateRangeService.get();

expect( partnerDateRange.startDate ).toEqual( {
day: 11,
month: 8,
year: 2020,
} );
expect( partnerDateRange.endDate ).toEqual( {
day: 7,
month: 9,
year: 2020,
} );
} );
} );
} );
} );

describe( 'getSupportedConversionTrackingTypes', () => {
Expand Down
44 changes: 44 additions & 0 deletions assets/js/modules/ads/pax/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* PAX utility functions.
*
* Site Kit by Google, Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Internal dependencies
*/
import { stringToDate } from '../../../util';

/**
* Returns formatted date object.
*
* @since n.e.x.t
*
* @param {string} dateString Date in 'YYYY-MM-DD' format.
* @return {Date} Date instance.
*/
export function formatPaxDate( dateString ) {
const dateObject = stringToDate( dateString );

return {
year: dateObject.getFullYear(),
// PAX uses a 1-indexed month value (to match the month string value).
//
// Our `stringToDate()` function returns 0-indexed month values,
// so we need to adjust the values for PAX.
month: dateObject.getMonth() + 1,
day: dateObject.getDate(),
};
}
50 changes: 50 additions & 0 deletions assets/js/modules/ads/pax/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* PAX utility functions tests.
*
* Site Kit by Google, Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Internal dependencies
*/
import { INVALID_DATE_STRING_ERROR } from '../../../util';
import { formatPaxDate } from './utils';

describe( 'formatPaxDate', () => {
it.each( [ null, NaN, '', '12345', '1900-00-00', 'not a date string' ] )(
'throws an error when given the invalid date string: %s',
( invalidDateString ) => {
expect( () => formatPaxDate( invalidDateString ) ).toThrow(
INVALID_DATE_STRING_ERROR
);
}
);

it( 'uses a one-indexed month', () => {
const date = formatPaxDate( '2019-01-31' );

expect( date.year ).toBe( 2019 );
expect( date.month ).toBe( 1 );
expect( date.day ).toBe( 31 );
} );

it( 'returns a valid date instance for the given date string', () => {
const date = formatPaxDate( '2019-10-31' );

expect( date.year ).toBe( 2019 );
expect( date.month ).toBe( 10 ); // 1-index based month
expect( date.day ).toBe( 31 );
} );
} );
8 changes: 8 additions & 0 deletions assets/js/util/date-range/string-to-date.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ describe( 'stringToDate', () => {
}
);

it( 'uses a zero-indexed month', () => {
const date = stringToDate( '2019-01-31' );

expect( date.getFullYear() ).toBe( 2019 );
expect( date.getMonth() ).toBe( 0 );
expect( date.getDate() ).toBe( 31 );
} );

it( 'returns a valid date instance for the given date string', () => {
const date = stringToDate( '2019-10-31' );

Expand Down

0 comments on commit ac4763c

Please sign in to comment.