Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into bug/9780-woocommer…
Browse files Browse the repository at this point in the history
…ce-myaccount-login.
  • Loading branch information
eugene-manuilov committed Jan 15, 2025
2 parents d6a4068 + 3413467 commit a4a77d1
Show file tree
Hide file tree
Showing 16 changed files with 567 additions and 27 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/zips.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ jobs:
needs: build-zips
timeout-minutes: 20
steps:
- name: Install SVN ( Subversion )
run: |
sudo apt-get update
sudo apt-get install subversion
- uses: actions/download-artifact@v4
with:
name: zip-files
Expand All @@ -242,7 +246,7 @@ jobs:
SVN_PASSWORD: no-op-password
SVN_USERNAME: no-op-username
VERSION: ${{ inputs.release_version }}

publish-to-wporg:
name: Publish to WordPress.org
runs-on: ubuntu-latest
Expand All @@ -251,6 +255,10 @@ jobs:
needs: build-zips
timeout-minutes: 20
steps:
- name: Install SVN ( Subversion )
run: |
sudo apt-get update
sudo apt-get install subversion
- uses: actions/download-artifact@v4
with:
name: zip-files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/
import { cloneDeep } from 'lodash';
import PropTypes from 'prop-types';
import classnames from 'classnames';

/**
* WordPress dependencies
Expand Down Expand Up @@ -148,7 +149,12 @@ export default function WPDashboardPopularPagesGA4( {

return (
/* TODO: decouple the styles from search-console class */
<div className="googlesitekit-search-console-widget">
<div
className={ classnames( 'googlesitekit-search-console-widget', {
'googlesitekit-search-console-widget--empty-data':
isGatheringData || ! rows?.length,
} ) }
>
<h3>
{ __( 'Top content over the last 28 days', 'google-site-kit' ) }
</h3>
Expand Down
5 changes: 5 additions & 0 deletions assets/js/modules/reader-revenue-manager/datastore/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,10 @@ export default Modules.createModuleStore( 'reader-revenue-manager', {
'publicationID',
'publicationOnboardingState',
'publicationOnboardingStateChanged',
'snippetMode',
'postTypes',
'productID',
'productIDs',
'paymentOption',
],
} );
57 changes: 57 additions & 0 deletions assets/js/modules/reader-revenue-manager/datastore/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ import {
INVARIANT_SETTINGS_NOT_CHANGED,
} from '../../../googlesitekit/data/create-settings-store';
import { createStrictSelect } from '../../../googlesitekit/data/utils';
import { isFeatureEnabled } from '../../../features';
import {
isValidPublicationID,
isValidOnboardingState,
isValidSnippetMode,
} from '../utils/validation';

// Invariant error messages.
Expand All @@ -42,6 +44,20 @@ export const INVARIANT_INVALID_PUBLICATION_ID =
export const INVARIANT_INVALID_PUBLICATION_ONBOARDING_STATE =
'a valid publication onboarding state is required';

export const INVARIANT_INVALID_SNIPPET_MODE =
'a valid snippet mode is required';

export const INVARIANT_INVALID_POST_TYPES =
'a valid post types array is required';

export const INVARIANT_INVALID_PRODUCT_ID = 'a valid product ID is required';

export const INVARIANT_INVALID_PRODUCT_IDS =
'a valid product IDs array is required';

export const INVARIANT_INVALID_PAYMENT_OPTION =
'a valid payment option is required';

export function validateCanSubmitChanges( select ) {
const strictSelect = createStrictSelect( select );
// Strict select will cause all selector functions to throw an error
Expand All @@ -52,13 +68,19 @@ export function validateCanSubmitChanges( select ) {
isDoingSubmitChanges,
getPublicationID,
getPublicationOnboardingState,
getSnippetMode,
getPostTypes,
getProductID,
getProductIDs,
getPaymentOption,
} = strictSelect( MODULES_READER_REVENUE_MANAGER );

invariant( ! isDoingSubmitChanges(), INVARIANT_DOING_SUBMIT_CHANGES );
invariant( haveSettingsChanged(), INVARIANT_SETTINGS_NOT_CHANGED );

const publicationID = getPublicationID();
const onboardingState = getPublicationOnboardingState();

invariant(
isValidPublicationID( publicationID ),
INVARIANT_INVALID_PUBLICATION_ID
Expand All @@ -68,4 +90,39 @@ export function validateCanSubmitChanges( select ) {
isValidOnboardingState( onboardingState ),
INVARIANT_INVALID_PUBLICATION_ONBOARDING_STATE
);

if ( isFeatureEnabled( 'rrmModuleV2' ) ) {
const snippetMode = getSnippetMode();
const postTypes = getPostTypes();
const productID = getProductID();
const productIDs = getProductIDs();
const paymentOption = getPaymentOption();

invariant(
isValidSnippetMode( snippetMode ),
INVARIANT_INVALID_SNIPPET_MODE
);

invariant(
Array.isArray( postTypes ) &&
postTypes.every( ( item ) => typeof item === 'string' ),
INVARIANT_INVALID_POST_TYPES
);

invariant(
typeof productID === 'string',
INVARIANT_INVALID_PRODUCT_ID
);

invariant(
Array.isArray( productIDs ) &&
productIDs.every( ( item ) => typeof item === 'string' ),
INVARIANT_INVALID_PRODUCT_IDS
);

invariant(
typeof paymentOption === 'string',
INVARIANT_INVALID_PAYMENT_OPTION
);
}
}
142 changes: 139 additions & 3 deletions assets/js/modules/reader-revenue-manager/datastore/settings.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@
*/
import API from 'googlesitekit-api';
import { createTestRegistry } from '../../../../../tests/js/utils';
import { enabledFeatures } from '../../../features';
import { MODULES_READER_REVENUE_MANAGER } from './constants';
import {
INVARIANT_INVALID_PAYMENT_OPTION,
INVARIANT_INVALID_POST_TYPES,
INVARIANT_INVALID_PRODUCT_ID,
INVARIANT_INVALID_PRODUCT_IDS,
INVARIANT_INVALID_PUBLICATION_ID,
INVARIANT_INVALID_PUBLICATION_ONBOARDING_STATE,
INVARIANT_INVALID_SNIPPET_MODE,
validateCanSubmitChanges,
} from './settings';

Expand All @@ -44,10 +50,21 @@ describe( 'modules/reader-revenue-manager settings', () => {
} );

describe( 'validateCanSubmitChanges', () => {
const validSettings = {
publicationID: 'ABCDEFGH',
publicationOnboardingState: 'ONBOARDING_ACTION_REQUIRED',
publicationOnboardingStateChanged: false,
snippetMode: 'post_types',
postTypes: [ 'post' ],
productID: 'valid-id',
productIDs: [ 'valid' ],
paymentOption: 'valid-option',
};

it( 'should throw invariant error for invalid publication ID of type number', () => {
const settings = {
...validSettings,
publicationID: 12345,
publicationOnboardingState: '',
};

registry
Expand All @@ -61,8 +78,8 @@ describe( 'modules/reader-revenue-manager settings', () => {

it( 'should throw invariant error for invalid publication ID with special chars', () => {
const settings = {
...validSettings,
publicationID: 'ABCD&*12345',
publicationOnboardingState: 'ONBOARDING_ACTION_REQUIRED',
};

registry
Expand All @@ -76,7 +93,7 @@ describe( 'modules/reader-revenue-manager settings', () => {

it( 'should throw invariant error for invalid publication onboarding state', () => {
const settings = {
publicationID: 'ABCDEFGH',
...validSettings,
publicationOnboardingState: 'invalid_state',
};

Expand All @@ -88,5 +105,124 @@ describe( 'modules/reader-revenue-manager settings', () => {
INVARIANT_INVALID_PUBLICATION_ONBOARDING_STATE
);
} );

it( 'should throw invariant error for invalid snippet mode', () => {
enabledFeatures.add( 'rrmModuleV2' );

const settings = {
...validSettings,
snippetMode: 'invalid-mode',
};

registry
.dispatch( MODULES_READER_REVENUE_MANAGER )
.setSettings( settings );

expect( () => validateCanSubmitChanges( registry.select ) ).toThrow(
INVARIANT_INVALID_SNIPPET_MODE
);
} );

it( 'should throw invariant error for invalid post types', () => {
enabledFeatures.add( 'rrmModuleV2' );

const settings = {
...validSettings,
postTypes: 'not-an-array',
};

registry
.dispatch( MODULES_READER_REVENUE_MANAGER )
.setSettings( settings );

expect( () => validateCanSubmitChanges( registry.select ) ).toThrow(
INVARIANT_INVALID_POST_TYPES
);
} );

it( 'should throw invariant error for post types with non-string elements', () => {
enabledFeatures.add( 'rrmModuleV2' );

const settings = {
...validSettings,
postTypes: [ 'post', 123, true ],
};

registry
.dispatch( MODULES_READER_REVENUE_MANAGER )
.setSettings( settings );

expect( () => validateCanSubmitChanges( registry.select ) ).toThrow(
INVARIANT_INVALID_POST_TYPES
);
} );

it( 'should throw invariant error for invalid product ID', () => {
enabledFeatures.add( 'rrmModuleV2' );

const settings = {
...validSettings,
productID: [ 'not-a-string' ],
};

registry
.dispatch( MODULES_READER_REVENUE_MANAGER )
.setSettings( settings );

expect( () => validateCanSubmitChanges( registry.select ) ).toThrow(
INVARIANT_INVALID_PRODUCT_ID
);
} );

it( 'should throw invariant error for invalid product IDs', () => {
enabledFeatures.add( 'rrmModuleV2' );

const settings = {
...validSettings,
productIDs: 'not-an-array',
};

registry
.dispatch( MODULES_READER_REVENUE_MANAGER )
.setSettings( settings );

expect( () => validateCanSubmitChanges( registry.select ) ).toThrow(
INVARIANT_INVALID_PRODUCT_IDS
);
} );

it( 'should throw invariant error for product IDs with non-string elements', () => {
enabledFeatures.add( 'rrmModuleV2' );

const settings = {
...validSettings,
productIDs: [ 'valid', 123, true ],
};

registry
.dispatch( MODULES_READER_REVENUE_MANAGER )
.setSettings( settings );

expect( () => validateCanSubmitChanges( registry.select ) ).toThrow(
INVARIANT_INVALID_PRODUCT_IDS
);
} );

it( 'should throw invariant error for invalid payment option', () => {
enabledFeatures.add( 'rrmModuleV2' );

const settings = {
...validSettings,
paymentOption: [ 'not-a-string' ],
};

registry
.dispatch( MODULES_READER_REVENUE_MANAGER )
.setSettings( settings );

expect( () => validateCanSubmitChanges( registry.select ) ).toThrow(
INVARIANT_INVALID_PAYMENT_OPTION
);
} );
} );
} );
13 changes: 13 additions & 0 deletions assets/js/modules/reader-revenue-manager/utils/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,16 @@ export const isURLUsingHTTPS = ( url ) => {
return false;
}
};

/**
* Validates if a value is one of the allowed snippet modes.
*
* @since n.e.x.t
*
* @param {string} mode Snippet mode to validate.
* @return {boolean} Whether the mode is valid.
*/
export function isValidSnippetMode( mode ) {
const validModes = [ 'post_types', 'per_post', 'sitewide' ];
return validModes.includes( mode );
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
/**
* Internal dependencies
*/
import { isValidPublicationID, isURLUsingHTTPS } from './validation';
import {
isValidPublicationID,
isValidSnippetMode,
isURLUsingHTTPS,
} from './validation';

describe( 'utility functions', () => {
describe( 'isValidPublicationID', () => {
Expand Down Expand Up @@ -66,4 +70,25 @@ describe( 'utility functions', () => {
}
);
} );

describe( 'isValidSnippetMode', () => {
it( 'should return TRUE when a valid snippet mode is passed', () => {
expect( isValidSnippetMode( 'post_types' ) ).toBe( true );
expect( isValidSnippetMode( 'per_post' ) ).toBe( true );
expect( isValidSnippetMode( 'sitewide' ) ).toBe( true );
} );

it.each( [
[ 'false', false ],
[ 'an integer', 12345 ],
[ 'an empty string', '' ],
[ 'an invalid mode string', 'invalid-mode' ],
[ 'null', null ],
[ 'undefined', undefined ],
[ 'an array', [] ],
[ 'an object', {} ],
] )( 'should return FALSE when %s is passed', ( _, snippetMode ) => {
expect( isValidSnippetMode( snippetMode ) ).toBe( false );
} );
} );
} );
Loading

0 comments on commit a4a77d1

Please sign in to comment.