From 52b5f72a0ecb330cc5c54f7efcf76aeba377edf4 Mon Sep 17 00:00:00 2001 From: Ankit Gade Date: Thu, 9 Jan 2025 18:40:27 +0530 Subject: [PATCH 1/6] Add post meta setting to store post-level RRM settings. --- includes/Core/Storage/Post_Meta_Setting.php | 25 ++++--- includes/Modules/Reader_Revenue_Manager.php | 10 +++ .../Post_Product_ID.php | 68 +++++++++++++++++++ .../Post_Product_ID_Test.php | 9 +++ 4 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php create mode 100644 tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php diff --git a/includes/Core/Storage/Post_Meta_Setting.php b/includes/Core/Storage/Post_Meta_Setting.php index 7efb93180df..b1fec6804a8 100644 --- a/includes/Core/Storage/Post_Meta_Setting.php +++ b/includes/Core/Storage/Post_Meta_Setting.php @@ -19,12 +19,6 @@ */ abstract class Post_Meta_Setting { - /** - * The post meta key for this setting. - * Override in a sub-class. - */ - const META_KEY = ''; - /** * Post_Meta_Interface implementation. * @@ -44,6 +38,15 @@ public function __construct( Post_Meta_Interface $post_meta ) { $this->post_meta = $post_meta; } + /** + * Gets the meta key for the setting. + * + * @since n.e.x.t + * + * @return string Meta key. + */ + abstract protected function get_meta_key(): string; + /** * Registers the post setting in WordPress. * @@ -52,7 +55,7 @@ public function __construct( Post_Meta_Interface $post_meta ) { public function register() { register_meta( 'post', - static::META_KEY, + $this->get_meta_key(), array( 'type' => $this->get_type(), 'sanitize_callback' => $this->get_sanitize_callback(), @@ -127,7 +130,7 @@ protected function get_show_in_rest() { * @return bool True if the meta key exists, otherwise false. */ public function has( $post_id ) { - return metadata_exists( 'post', $post_id, static::META_KEY ); + return metadata_exists( 'post', $post_id, $this->get_meta_key() ); } /** @@ -143,7 +146,7 @@ public function get( $post_id ) { return $this->get_default(); } - return $this->post_meta->get( $post_id, static::META_KEY, true ); + return $this->post_meta->get( $post_id, $this->get_meta_key(), true ); } /** @@ -156,7 +159,7 @@ public function get( $post_id ) { * @return bool TRUE on success, otherwise FALSE. */ public function set( $post_id, $value ) { - return $this->post_meta->update( $post_id, static::META_KEY, $value ); + return $this->post_meta->update( $post_id, $this->get_meta_key(), $value ); } /** @@ -168,6 +171,6 @@ public function set( $post_id, $value ) { * @return bool TRUE on success, otherwise FALSE. */ public function delete( $post_id ) { - return $this->post_meta->delete( $post_id, static::META_KEY ); + return $this->post_meta->delete( $post_id, $this->get_meta_key() ); } } diff --git a/includes/Modules/Reader_Revenue_Manager.php b/includes/Modules/Reader_Revenue_Manager.php index c525a5892a7..c46f11dc6e1 100644 --- a/includes/Modules/Reader_Revenue_Manager.php +++ b/includes/Modules/Reader_Revenue_Manager.php @@ -30,9 +30,12 @@ use Google\Site_Kit\Core\REST_API\Data_Request; use Google\Site_Kit\Core\REST_API\Exception\Missing_Required_Param_Exception; use Google\Site_Kit\Core\Site_Health\Debug_Data; +use Google\Site_Kit\Core\Storage\Post_Meta; use Google\Site_Kit\Core\Tags\Guards\Tag_Environment_Type_Guard; use Google\Site_Kit\Core\Tags\Guards\Tag_Verify_Guard; +use Google\Site_Kit\Core\Util\Feature_Flags; use Google\Site_Kit\Core\Util\URL; +use Google\Site_Kit\Modules\Reader_Revenue_Manager\Post_Product_ID; use Google\Site_Kit\Modules\Reader_Revenue_Manager\Settings; use Google\Site_Kit\Modules\Reader_Revenue_Manager\Synchronize_OnboardingState; use Google\Site_Kit\Modules\Reader_Revenue_Manager\Tag_Guard; @@ -75,6 +78,13 @@ public function register() { ); $synchronize_onboarding_state->register(); + if ( Feature_Flags::enabled( 'rrmModuleV2' ) && $this->is_connected() ) { + $post_meta = new Post_Meta(); + $publication_id = $this->get_settings()->get()['publicationID']; + $post_product_id = new Post_Product_ID( $post_meta, $publication_id ); + $post_product_id->register(); + } + add_action( 'load-toplevel_page_googlesitekit-dashboard', array( $synchronize_onboarding_state, 'maybe_schedule_synchronize_onboarding_state' ) ); add_action( 'load-toplevel_page_googlesitekit-settings', array( $synchronize_onboarding_state, 'maybe_schedule_synchronize_onboarding_state' ) ); diff --git a/includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php b/includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php new file mode 100644 index 00000000000..26855a7cd58 --- /dev/null +++ b/includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php @@ -0,0 +1,68 @@ +publication_id = $publication_id; + } + + /** + * Gets the meta key for the setting. + * + * @since n.e.x.t + * + * @return string Meta key. + */ + protected function get_meta_key(): string { + return 'googlesitekit_rrm_' . $this->publication_id . ':productID'; + } + + /** + * Gets the `show_in_rest` value for this postmeta setting value. + * + * @since n.e.x.t + * + * @return bool|Array Any valid value for the `show_in_rest` + */ + protected function get_show_in_rest() { + return true; + } +} diff --git a/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php b/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php new file mode 100644 index 00000000000..cd98be22b1a --- /dev/null +++ b/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php @@ -0,0 +1,9 @@ + Date: Thu, 9 Jan 2025 21:18:06 +0530 Subject: [PATCH 2/6] Fix: RRM Banner appearing momentarily. --- .../ReaderRevenueManagerSetupCTABanner.js | 7 ++++ ...ReaderRevenueManagerSetupCTABanner.test.js | 35 +++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js index 2fe794c42b0..0630964bd0b 100644 --- a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js +++ b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js @@ -97,6 +97,12 @@ function ReaderRevenueManagerSetupCTABanner( { Widget, WidgetNull } ) { ) ); + const isDismissingPrompt = useSelect( ( select ) => + select( CORE_USER ).isDismissingPrompt( + READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY + ) + ); + const dismissCount = useSelect( ( select ) => select( CORE_USER ).getPromptDismissCount( READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY @@ -136,6 +142,7 @@ function ReaderRevenueManagerSetupCTABanner( { Widget, WidgetNull } ) { const showBanner = isDismissed === false && + ! isDismissingPrompt && canActivateRRMModule && dismissedPromptsLoaded === true; diff --git a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js index 29af046eac3..2bcbbaee9bb 100644 --- a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js +++ b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js @@ -137,6 +137,32 @@ describe( 'ReaderRevenueManagerSetupCTABanner', () => { expect( mockTrackEvent ).not.toHaveBeenCalled(); } ); + it( 'should not render the banner when it is being dismissed', async () => { + registry.dispatch( CORE_USER ).receiveGetDismissedPrompts( [] ); + + registry + .dispatch( CORE_USER ) + .setIsPromptDimissing( + READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY, + true + ); + + const { container, waitForRegistry } = render( + , + { + registry, + viewContext: VIEW_CONTEXT_MAIN_DASHBOARD, + } + ); + + await waitForRegistry(); + + expect( container ).toBeEmptyDOMElement(); + } ); + it( 'should call the "useActivateModuleCallback" hook when the setup CTA is clicked', async () => { mockSurveyEndpoints(); @@ -188,9 +214,12 @@ describe( 'ReaderRevenueManagerSetupCTABanner', () => { fetchMock.postOnce( RegExp( '^/google-site-kit/v1/core/user/data/dismiss-prompt' ), { - body: JSON.stringify( [ - READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY, - ] ), + body: { + [ READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY ]: { + expires: Date.now() / 1000 + WEEK_IN_SECONDS, + count: 1, + }, + }, status: 200, } ); From 85a28401af185e3b427879ab82bd2629237391b6 Mon Sep 17 00:00:00 2001 From: Ankit Gade Date: Thu, 9 Jan 2025 22:22:43 +0530 Subject: [PATCH 3/6] Revert RRM banner changes. --- .../ReaderRevenueManagerSetupCTABanner.js | 7 ---- ...ReaderRevenueManagerSetupCTABanner.test.js | 35 ++----------------- 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js index 0630964bd0b..2fe794c42b0 100644 --- a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js +++ b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.js @@ -97,12 +97,6 @@ function ReaderRevenueManagerSetupCTABanner( { Widget, WidgetNull } ) { ) ); - const isDismissingPrompt = useSelect( ( select ) => - select( CORE_USER ).isDismissingPrompt( - READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY - ) - ); - const dismissCount = useSelect( ( select ) => select( CORE_USER ).getPromptDismissCount( READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY @@ -142,7 +136,6 @@ function ReaderRevenueManagerSetupCTABanner( { Widget, WidgetNull } ) { const showBanner = isDismissed === false && - ! isDismissingPrompt && canActivateRRMModule && dismissedPromptsLoaded === true; diff --git a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js index 2bcbbaee9bb..29af046eac3 100644 --- a/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js +++ b/assets/js/modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner.test.js @@ -137,32 +137,6 @@ describe( 'ReaderRevenueManagerSetupCTABanner', () => { expect( mockTrackEvent ).not.toHaveBeenCalled(); } ); - it( 'should not render the banner when it is being dismissed', async () => { - registry.dispatch( CORE_USER ).receiveGetDismissedPrompts( [] ); - - registry - .dispatch( CORE_USER ) - .setIsPromptDimissing( - READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY, - true - ); - - const { container, waitForRegistry } = render( - , - { - registry, - viewContext: VIEW_CONTEXT_MAIN_DASHBOARD, - } - ); - - await waitForRegistry(); - - expect( container ).toBeEmptyDOMElement(); - } ); - it( 'should call the "useActivateModuleCallback" hook when the setup CTA is clicked', async () => { mockSurveyEndpoints(); @@ -214,12 +188,9 @@ describe( 'ReaderRevenueManagerSetupCTABanner', () => { fetchMock.postOnce( RegExp( '^/google-site-kit/v1/core/user/data/dismiss-prompt' ), { - body: { - [ READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY ]: { - expires: Date.now() / 1000 + WEEK_IN_SECONDS, - count: 1, - }, - }, + body: JSON.stringify( [ + READER_REVENUE_MANAGER_SETUP_BANNER_DISMISSED_KEY, + ] ), status: 200, } ); From 492cede30fbc5c7b216f98abc7d01ee5e696d3ff Mon Sep 17 00:00:00 2001 From: Ankit Gade Date: Fri, 10 Jan 2025 11:54:01 +0530 Subject: [PATCH 4/6] Add test for Post_Product_ID class. --- .../Post_Product_ID_Test.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php b/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php index cd98be22b1a..62a11f209d4 100644 --- a/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php +++ b/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php @@ -7,3 +7,38 @@ * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://sitekit.withgoogle.com */ + +namespace Google\Site_Kit\Tests\Modules\Reader_Revenue_Manager; + +use Google\Site_Kit\Core\Storage\Post_Meta; +use Google\Site_Kit\Modules\Reader_Revenue_Manager\Post_Product_ID; +use Google\Site_Kit\Tests\TestCase; + +class Post_Product_ID_Test extends TestCase { + + /** + * @var Post_Product_ID + */ + private $setting; + + public function set_up(): void { + parent::set_up(); + + $post_meta = new Post_Meta(); + $this->setting = new Post_Product_ID( $post_meta, 'test_publication_id' ); + $this->setting->register(); + } + + public function test_product_id_meta_registered() { + $registered = registered_meta_key_exists( 'post', 'googlesitekit_rrm_test_publication_id:productID' ); + + $this->assertTrue( $registered ); + } + + public function test_show_in_rest() { + $meta_key = 'googlesitekit_rrm_test_publication_id:productID'; + $show_in_rest = get_registered_meta_keys( 'post' )[ $meta_key ]['show_in_rest']; + + $this->assertTrue( $show_in_rest ); + } +} From 8e5ee2335ab52074d13c20d7baf7bb329355f803 Mon Sep 17 00:00:00 2001 From: Ankit Gade Date: Fri, 10 Jan 2025 12:19:30 +0530 Subject: [PATCH 5/6] Add tests for settings registration. --- .../Modules/Reader_Revenue_ManagerTest.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/phpunit/integration/Modules/Reader_Revenue_ManagerTest.php b/tests/phpunit/integration/Modules/Reader_Revenue_ManagerTest.php index bcf3d83e181..ebaf044293a 100644 --- a/tests/phpunit/integration/Modules/Reader_Revenue_ManagerTest.php +++ b/tests/phpunit/integration/Modules/Reader_Revenue_ManagerTest.php @@ -486,6 +486,56 @@ public function test_check_service_entity_access_no_access_unavailable_publicati $this->assertEquals( false, $access ); } + public function test_product_id_setting_registered() { + $publication_id = 'ABCDEFGH'; + $this->enable_feature( 'rrmModuleV2' ); + + $this->reader_revenue_manager->get_settings()->set( + array( + 'publicationID' => $publication_id, + ) + ); + + $this->reader_revenue_manager->register(); + + $registered = registered_meta_key_exists( 'post', 'googlesitekit_rrm_' . $publication_id . ':productID' ); + + $this->assertTrue( $registered ); + } + + public function test_publication_id_empty_product_id_setting_not_registered() { + $publication_id = 'ABCDEFGH'; + $this->enable_feature( 'rrmModuleV2' ); + + $this->reader_revenue_manager->get_settings()->set( + array( + 'publicationID' => '', + ) + ); + + $this->reader_revenue_manager->register(); + + $registered = registered_meta_key_exists( 'post', 'googlesitekit_rrm_' . $publication_id . ':productID' ); + + $this->assertFalse( $registered ); + } + + public function test_feature_disabled_product_id_setting_not_registered() { + $publication_id = 'ABCDEFGH'; + + $this->reader_revenue_manager->get_settings()->set( + array( + 'publicationID' => $publication_id, + ) + ); + + $this->reader_revenue_manager->register(); + + $registered = registered_meta_key_exists( 'post', 'googlesitekit_rrm_' . $publication_id . ':productID' ); + + $this->assertFalse( $registered ); + } + /** * @return Module_With_Scopes */ From 53437b859538c01834c6d10519beaf65531b4767 Mon Sep 17 00:00:00 2001 From: Ankit Gade Date: Mon, 13 Jan 2025 18:45:05 +0530 Subject: [PATCH 6/6] Address CR comments. --- includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php | 4 ++-- .../{Post_Product_ID_Test.php => Post_Product_IDTest.php} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename tests/phpunit/integration/Modules/Reader_Revenue_Manager/{Post_Product_ID_Test.php => Post_Product_IDTest.php} (97%) diff --git a/includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php b/includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php index 26855a7cd58..85cc1ddc7a6 100644 --- a/includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php +++ b/includes/Modules/Reader_Revenue_Manager/Post_Product_ID.php @@ -3,7 +3,7 @@ * Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Post_Product_ID * * @package Google\Site_Kit\Modules\Reader_Revenue_Manager - * @copyright 2024 Google LLC + * @copyright 2025 Google LLC * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://sitekit.withgoogle.com */ @@ -14,7 +14,7 @@ use Google\Site_Kit\Core\Storage\Post_Meta_Setting; /** - * Class for a associating product ID to post meta. + * Class for associating product ID to post meta. * * @since n.e.x.t * @access private diff --git a/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php b/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_IDTest.php similarity index 97% rename from tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php rename to tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_IDTest.php index 62a11f209d4..0ea60d18f2b 100644 --- a/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_ID_Test.php +++ b/tests/phpunit/integration/Modules/Reader_Revenue_Manager/Post_Product_IDTest.php @@ -3,7 +3,7 @@ * Class Google\Site_Kit\Tests\Modules\Reader_Revenue_Manager\Post_Product_ID_Test * * @package Google\Site_Kit\Tests\Modules\Reader_Revenue_Manager - * @copyright 2024 Google LLC + * @copyright 2025 Google LLC * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://sitekit.withgoogle.com */