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
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* `modules/sign-in-with-google` data store: compatibility-checks.
*
* Site Kit by Google, Copyright 2025 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 { get } from 'googlesitekit-api';
import {
commonActions,
combineStores,
createReducer,
} from 'googlesitekit-data';
import { createFetchStore } from '@/js/googlesitekit/data/create-fetch-store';
import { MODULES_SIGN_IN_WITH_GOOGLE } from './constants';

const fetchGetCompatibilityChecksStore = createFetchStore( {
baseName: 'getCompatibilityChecks',
controlCallback: () => {
return get(
'modules',
'sign-in-with-google',
'compatibility-checks',
null,
{
useCache: false,
}
);
},
reducerCallback: createReducer( ( state, compatibilityChecks ) => {
state.compatibilityChecks = compatibilityChecks;
} ),
} );

const baseInitialState = {
compatibilityChecks: undefined,
};

const baseResolvers = {
*getCompatibilityChecks() {
const registry = yield commonActions.getRegistry();

const checks = registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();

if ( checks ) {
return;
}

yield fetchGetCompatibilityChecksStore.actions.fetchGetCompatibilityChecks();
},
};

const baseSelectors = {
/**
* Gets the compatibility checks data.
*
* @since n.e.x.t
*
* @param {Object} state Data store's state.
* @return {Object|undefined} Compatibility checks data, or `undefined` if not loaded.
*/
getCompatibilityChecks: ( state ) => {
return state.compatibilityChecks;
},
};

const store = combineStores( fetchGetCompatibilityChecksStore, {
initialState: baseInitialState,
resolvers: baseResolvers,
selectors: baseSelectors,
} );

export const initialState = store.initialState;
export const actions = store.actions;
export const controls = store.controls;
export const reducer = store.reducer;
export const resolvers = store.resolvers;
export const selectors = store.selectors;

export default store;
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/**
* `modules/sign-in-with-google` data store: compatibility-checks tests.
*
* Site Kit by Google, Copyright 2025 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 { setUsingCache } from 'googlesitekit-api';
import {
createTestRegistry,
untilResolved,
} from '../../../../../tests/js/utils';
import { MODULES_SIGN_IN_WITH_GOOGLE } from './constants';

describe( 'modules/sign-in-with-google compatibility-checks', () => {
let registry;

const compatibilityChecksFixture = [ true, false ]; // The value doesn't really matter.

beforeAll( () => {
setUsingCache( false );
} );

beforeEach( () => {
registry = createTestRegistry();
} );

afterAll( () => {
setUsingCache( true );
} );

describe( 'selectors', () => {
describe( 'getCompatibilityChecks', () => {
const endpoint = new RegExp(
'^/google-site-kit/v1/modules/sign-in-with-google/data/compatibility-checks'
);

it( 'uses a resolver to make a network request', async () => {
fetchMock.getOnce( endpoint, {
body: compatibilityChecksFixture,
status: 200,
} );

const initialCompatibilityChecks = registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();
expect( initialCompatibilityChecks ).toBeUndefined();

await untilResolved(
registry,
MODULES_SIGN_IN_WITH_GOOGLE
).getCompatibilityChecks();

const compatibilityChecks = registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();
expect( fetchMock ).toHaveFetchedTimes( 1 );
expect( compatibilityChecks ).toEqual(
compatibilityChecksFixture
);
} );

it( 'does not make a network request if compatibility checks are already present', async () => {
registry
.dispatch( MODULES_SIGN_IN_WITH_GOOGLE )
.receiveGetCompatibilityChecks(
compatibilityChecksFixture
);

const compatibilityChecks = registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();

await untilResolved(
registry,
MODULES_SIGN_IN_WITH_GOOGLE
).getCompatibilityChecks();

expect( fetchMock ).not.toHaveFetched();
expect( compatibilityChecks ).toEqual(
compatibilityChecksFixture
);
} );

it( 'dispatches an error if the request fails', async () => {
const response = {
code: 'internal_server_error',
message: 'Internal server error',
data: { status: 500 },
};

fetchMock.getOnce( endpoint, {
body: response,
status: 500,
} );

registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();
await untilResolved(
registry,
MODULES_SIGN_IN_WITH_GOOGLE
).getCompatibilityChecks();

expect( fetchMock ).toHaveFetchedTimes( 1 );

const compatibilityChecks = registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();
expect( compatibilityChecks ).toBeUndefined();
expect( console ).toHaveErrored();
} );

it( 'returns undefined when no compatibility checks data is available', async () => {
fetchMock.getOnce( endpoint, {
body: compatibilityChecksFixture,
status: 200,
} );

const compatibilityChecks = registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();

expect( compatibilityChecks ).toBeUndefined();

// Wait for the resolver to complete to avoid interfering with subsequent tests.
await untilResolved(
registry,
MODULES_SIGN_IN_WITH_GOOGLE
).getCompatibilityChecks();
} );

it( 'returns the compatibility checks data when available', async () => {
registry
.dispatch( MODULES_SIGN_IN_WITH_GOOGLE )
.receiveGetCompatibilityChecks(
compatibilityChecksFixture
);

const compatibilityChecks = registry
.select( MODULES_SIGN_IN_WITH_GOOGLE )
.getCompatibilityChecks();

await untilResolved(
registry,
MODULES_SIGN_IN_WITH_GOOGLE
).getCompatibilityChecks();

expect( fetchMock ).not.toHaveFetched();
expect( compatibilityChecks ).toEqual(
compatibilityChecksFixture
);
} );
} );
} );
} );
8 changes: 7 additions & 1 deletion assets/js/modules/sign-in-with-google/datastore/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@
import { combineStores } from 'googlesitekit-data';
import { MODULES_SIGN_IN_WITH_GOOGLE } from './constants';
import baseModuleStore from './base';
import compatibilityChecks from './compatibility-checks';
import service from './service';
import moduleData from './module-data';

const store = combineStores( baseModuleStore, service, moduleData );
const store = combineStores(
baseModuleStore,
compatibilityChecks,
service,
moduleData
);

export const initialState = store.initialState;
export const actions = store.actions;
Expand Down
25 changes: 24 additions & 1 deletion includes/Modules/Sign_In_With_Google.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
use Google\Site_Kit\Modules\Sign_In_With_Google\Tag_Matchers;
use Google\Site_Kit\Modules\Sign_In_With_Google\Web_Tag;
use Google\Site_Kit\Modules\Sign_In_With_Google\WooCommerce_Authenticator;
use Google\Site_Kit\Modules\Sign_In_With_Google\Compatibility_Checks\Compatibility_Checks;
use Google\Site_Kit\Modules\Sign_In_With_Google\Compatibility_Checks\WP_Login_Accessible_Check;
use Google\Site_Kit\Modules\Sign_In_With_Google\Compatibility_Checks\WP_COM_Check;
use Google\Site_Kit\Modules\Sign_In_With_Google\Compatibility_Checks\Conflicting_Plugins_Check;
use Google\Site_Kit\Modules\Sign_In_With_Google\Datapoint\Compatibility_Checks as Compatibility_Checks_Datapoint;
use WP_Error;
use WP_User;

Expand Down Expand Up @@ -367,6 +372,24 @@ public function is_connected() {
return parent::is_connected();
}

/**
* Gets the datapoint definitions for the module.
*
* @since n.e.x.t
*
* @return array List of datapoint definitions.
*/
protected function get_datapoint_definitions() {
$checks = new Compatibility_Checks();
$checks->add_check( new WP_Login_Accessible_Check() );
$checks->add_check( new WP_COM_Check() );
$checks->add_check( new Conflicting_Plugins_Check() );

return array(
'GET:compatibility-checks' => new Compatibility_Checks_Datapoint( array( 'checks' => $checks ) ),
);
}

/**
* Renders the placeholder Sign in with Google div for the WooCommerce
* login form.
Expand Down Expand Up @@ -726,4 +749,4 @@ public function get_inline_data( $modules_data ) {
protected function is_woocommerce_active() {
return class_exists( 'WooCommerce' );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,6 @@ public function add_check( Compatibility_Check $check ) {
$this->checks[] = $check;
}

/**
* Registers all compatibility checks.
*
* @since n.e.x.t
*/
public function register_checks() {
$this->add_check( new WP_Login_Accessible_Check() );
$this->add_check( new WP_COM_Check() );
$this->add_check( new Conflicting_Plugins_Check() );
}

/**
* Runs all compatibility checks.
*
Expand Down
Loading
Loading