Commit d86944bc064 for woocommerce

commit d86944bc0646232020880db719ec6c8c3ab1d46b
Author: Faisal Ahammad <faisalahammad24@gmail.com>
Date:   Mon Jul 13 16:31:12 2026 +0600

    fix(admin): check Action Scheduler wrapper in Daily Cron status report (#66188)

diff --git a/plugins/woocommerce/changelog/fix-66180-daily-cron-status-check b/plugins/woocommerce/changelog/fix-66180-daily-cron-status-check
new file mode 100644
index 00000000000..31cbad01cf5
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-66180-daily-cron-status-check
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix false "Daily Cron: Not scheduled" on Status page for fresh WooCommerce installs.
diff --git a/plugins/woocommerce/src/Internal/Admin/SystemStatusReport.php b/plugins/woocommerce/src/Internal/Admin/SystemStatusReport.php
index 6fc34f8b266..a59a9f0d9bf 100644
--- a/plugins/woocommerce/src/Internal/Admin/SystemStatusReport.php
+++ b/plugins/woocommerce/src/Internal/Admin/SystemStatusReport.php
@@ -77,7 +77,7 @@ class SystemStatusReport {
 		$enabled_features  = array_filter( $features );
 		$disabled_features = array_filter(
 			$features,
-			function( $feature ) {
+			function ( $feature ) {
 				return empty( $feature );
 			}
 		);
@@ -114,7 +114,9 @@ class SystemStatusReport {
 	 * Render daily cron row.
 	 */
 	public function render_daily_cron() {
-		$next_daily_cron = wp_next_scheduled( 'wc_admin_daily' );
+		$next_action_time = function_exists( 'as_next_scheduled_action' )
+			? as_next_scheduled_action( 'wc_admin_daily_wrapper', null, 'woocommerce' )
+			: false;
 		?>
 			<tr>
 				<td data-export-label="Daily Cron">
@@ -123,10 +125,14 @@ class SystemStatusReport {
 				<td class="help"><?php echo wc_help_tip( esc_html__( 'Is the daily cron job active, when does it next run?', 'woocommerce' ) ); /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped */ ?></td>
 				<td>
 					<?php
-					if ( empty( $next_daily_cron ) ) {
-						echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . esc_html__( 'Not scheduled', 'woocommerce' ) . '</mark>';
+					if ( $next_action_time ) {
+						$status_text = true === $next_action_time
+							? esc_html__( 'Currently running', 'woocommerce' )
+							/* translators: %s: Date and time the daily cron job is next scheduled to run. */
+							: sprintf( esc_html__( 'Next scheduled: %s', 'woocommerce' ), esc_html( date_i18n( 'Y-m-d H:i:s P', (int) $next_action_time ) ) );
+						echo '<mark class="yes"><span class="dashicons dashicons-yes"></span> ' . $status_text . '</mark>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $status_text built from esc_html()/esc_html__() above.
 					} else {
-						echo '<mark class="yes"><span class="dashicons dashicons-yes"></span> Next scheduled: ' . esc_html( date_i18n( 'Y-m-d H:i:s P', $next_daily_cron ) ) . '</mark>';
+						echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . esc_html__( 'Not scheduled', 'woocommerce' ) . '</mark>';
 					}
 					?>
 				</td>
@@ -213,5 +219,4 @@ class SystemStatusReport {
 			</tr>
 		<?php
 	}
-
 }
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/SystemStatusReportTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/SystemStatusReportTest.php
new file mode 100644
index 00000000000..dfa167fb8fb
--- /dev/null
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/SystemStatusReportTest.php
@@ -0,0 +1,69 @@
+<?php
+declare( strict_types = 1 );
+
+namespace Automattic\WooCommerce\Tests\Internal\Admin;
+
+use Automattic\WooCommerce\Internal\Admin\SystemStatusReport;
+use WC_Unit_Test_Case;
+
+/**
+ * Tests for the SystemStatusReport class.
+ */
+class SystemStatusReportTest extends WC_Unit_Test_Case {
+
+	/**
+	 * The System Under Test.
+	 *
+	 * @var SystemStatusReport
+	 */
+	private SystemStatusReport $sut;
+
+	/**
+	 * Set up test fixtures.
+	 */
+	public function setUp(): void {
+		parent::setUp();
+		$this->sut = SystemStatusReport::get_instance();
+		as_unschedule_all_actions( 'wc_admin_daily_wrapper' );
+	}
+
+	/**
+	 * Tear down test fixtures.
+	 */
+	public function tearDown(): void {
+		as_unschedule_all_actions( 'wc_admin_daily_wrapper' );
+		parent::tearDown();
+	}
+
+	/**
+	 * Test render_daily_cron across scheduled and not-scheduled Action Scheduler states.
+	 *
+	 * @testWith ["scheduled"]
+	 *           ["not-scheduled"]
+	 *
+	 * @param string $scenario Either 'scheduled' or 'not-scheduled'.
+	 */
+	public function test_render_daily_cron( string $scenario ): void {
+		$expected_date = '';
+
+		if ( 'scheduled' === $scenario ) {
+			$timestamp     = time() + DAY_IN_SECONDS;
+			$expected_date = esc_html( date_i18n( 'Y-m-d H:i:s P', $timestamp ) );
+
+			as_schedule_recurring_action( $timestamp, DAY_IN_SECONDS, 'wc_admin_daily_wrapper', array(), 'woocommerce', true );
+		}
+
+		ob_start();
+		$this->sut->render_daily_cron();
+		$output = ob_get_clean();
+
+		if ( 'scheduled' === $scenario ) {
+			$this->assertStringContainsString( 'Next scheduled:', $output );
+			$this->assertStringContainsString( $expected_date, $output );
+			$this->assertStringNotContainsString( 'Not scheduled', $output );
+		} else {
+			$this->assertStringContainsString( 'Not scheduled', $output );
+			$this->assertStringNotContainsString( 'Next scheduled:', $output );
+		}
+	}
+}