Commit 36c0b0f5270 for woocommerce
commit 36c0b0f5270637857961b938c05e6fc1d47335af
Author: Michal Iwanow <4765119+mcliwanow@users.noreply.github.com>
Date: Wed Aug 5 13:14:13 2026 +0200
Add tests for remote inbox notifications marketplace suggestions gate (#67040)
* Add remote inbox notifications marketplace suggestions gating tests
* Add changelog entry for remote inbox notifications gating tests
* Remove changelog entry, tests-only change
* Update remote inbox notifications gate tests for review feedback
---------
Co-authored-by: Akeda Bagus <akeda.bagus@automattic.com>
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/RemoteInboxNotificationsTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/RemoteInboxNotificationsTest.php
new file mode 100644
index 00000000000..419d2e68a1f
--- /dev/null
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/RemoteInboxNotificationsTest.php
@@ -0,0 +1,160 @@
+<?php
+declare( strict_types = 1 );
+
+namespace Automattic\WooCommerce\Tests\Internal\Admin;
+
+use Automattic\WooCommerce\Admin\RemoteInboxNotifications\RemoteInboxNotificationsEngine;
+use Automattic\WooCommerce\Internal\Admin\Events;
+use Automattic\WooCommerce\Internal\Admin\RemoteInboxNotifications;
+use WC_Unit_Test_Case;
+
+/**
+ * Tests for the marketplace suggestions gating of remote inbox notifications.
+ *
+ * @covers \Automattic\WooCommerce\Internal\Admin\RemoteInboxNotifications
+ * @covers \Automattic\WooCommerce\Internal\Admin\Events::is_remote_inbox_notifications_enabled
+ */
+class RemoteInboxNotificationsTest extends WC_Unit_Test_Case {
+
+ /**
+ * Set up test fixtures.
+ */
+ public function setUp(): void {
+ parent::setUp();
+
+ // The engine is initialized by the plugin bootstrap; detach its hooks so
+ // each test observes initialization from scratch. No manual restore is
+ // needed: parent::tearDown() puts the full wp_filter map back to the
+ // snapshot WP_UnitTestCase_Base::_backup_hooks() took before the first
+ // test, which reattaches these hooks and discards any callbacks that
+ // RemoteInboxNotificationsEngine::init() registered during the test.
+ $this->detach_engine_hooks();
+ }
+
+ /**
+ * Tear down test fixtures.
+ */
+ public function tearDown(): void {
+ delete_option( RemoteInboxNotifications::TOGGLE_OPTION_NAME );
+
+ parent::tearDown();
+ }
+
+ /**
+ * @testdox The feature loader should initialize the engine only when marketplace suggestions are enabled.
+ * @dataProvider marketplace_suggestions_option_provider
+ *
+ * @param string|null $option_value Marketplace suggestions option value, or null when absent.
+ * @param bool $expected_value Whether the engine is expected to be initialized.
+ */
+ public function test_engine_initialization_respects_marketplace_suggestions_option( ?string $option_value, bool $expected_value ): void {
+ $this->set_marketplace_suggestions_option( $option_value );
+
+ new RemoteInboxNotifications();
+
+ $this->assert_engine_initialized( $expected_value );
+ }
+
+ /**
+ * @testdox The daily cron gate should agree with the marketplace suggestions option.
+ * @dataProvider marketplace_suggestions_option_provider
+ *
+ * Events::is_remote_inbox_notifications_enabled() duplicates the option check the feature
+ * loader performs; running both gates against the same provider pins them to the same behavior.
+ *
+ * @param string|null $option_value Marketplace suggestions option value, or null when absent.
+ * @param bool $expected_value Expected gate value.
+ */
+ public function test_daily_cron_gate_respects_marketplace_suggestions_option( ?string $option_value, bool $expected_value ): void {
+ $this->set_marketplace_suggestions_option( $option_value );
+
+ $this->assertSame(
+ $expected_value,
+ $this->is_daily_cron_gate_enabled(),
+ 'The daily cron gate should match the configured marketplace suggestions option.'
+ );
+ }
+
+ /**
+ * Values for the marketplace suggestions option tests.
+ *
+ * @return array<string, array{string|null, bool}>
+ */
+ public function marketplace_suggestions_option_provider(): array {
+ return array(
+ 'option absent' => array( null, true ),
+ 'option enabled' => array( 'yes', true ),
+ 'option disabled' => array( 'no', false ),
+ 'unexpected value' => array( 'invalid', false ),
+ 'truthy non-yes' => array( '1', false ),
+ );
+ }
+
+ /**
+ * Set or delete the marketplace suggestions option.
+ *
+ * @param string|null $value Option value, or null to delete the option.
+ */
+ private function set_marketplace_suggestions_option( ?string $value ): void {
+ if ( null === $value ) {
+ delete_option( RemoteInboxNotifications::TOGGLE_OPTION_NAME );
+ } else {
+ update_option( RemoteInboxNotifications::TOGGLE_OPTION_NAME, $value );
+ }
+ }
+
+ /**
+ * Engine hooks observed by these tests, keyed by hook name.
+ *
+ * @return array<string, array{class-string, string}>
+ */
+ private function get_engine_hooks(): array {
+ return array(
+ 'init' => array( RemoteInboxNotificationsEngine::class, 'on_init' ),
+ 'admin_init' => array( RemoteInboxNotificationsEngine::class, 'on_admin_init' ),
+ );
+ }
+
+ /**
+ * Detach the engine hooks at their currently registered priorities.
+ */
+ private function detach_engine_hooks(): void {
+ foreach ( $this->get_engine_hooks() as $hook => $callback ) {
+ $priority = has_action( $hook, $callback );
+
+ if ( false !== $priority ) {
+ remove_action( $hook, $callback, $priority );
+ }
+ }
+ }
+
+ /**
+ * Assert whether the engine registered its hooks.
+ *
+ * @param bool $expected Whether the engine is expected to be initialized.
+ */
+ private function assert_engine_initialized( bool $expected ): void {
+ foreach ( $this->get_engine_hooks() as $hook => $callback ) {
+ // has_action() returns the priority, which is the falsy int 0 for the init hook.
+ $is_registered = false !== has_action( $hook, $callback );
+
+ $this->assertSame(
+ $expected,
+ $is_registered,
+ $expected
+ ? "The engine should register its {$hook} hook."
+ : "The engine should not register its {$hook} hook."
+ );
+ }
+ }
+
+ /**
+ * Invoke the protected daily cron gate.
+ */
+ private function is_daily_cron_gate_enabled(): bool {
+ $method = new \ReflectionMethod( Events::class, 'is_remote_inbox_notifications_enabled' );
+ $method->setAccessible( true );
+
+ return $method->invoke( Events::instance() );
+ }
+}