Skip to content

Fix dashboard status widget not showing after task list completion#63522

Merged
kraftbj merged 9 commits intotrunkfrom
fix/55137-dashboard-status-widget-task-list-complete
Mar 20, 2026
Merged

Fix dashboard status widget not showing after task list completion#63522
kraftbj merged 9 commits intotrunkfrom
fix/55137-dashboard-status-widget-task-list-complete

Conversation

@jamesckemp
Copy link
Copy Markdown
Collaborator

@jamesckemp jamesckemp commented Mar 3, 2026

Submission Review Guidelines:

Changes proposed in this Pull Request:

After completing the onboarding task list, the Dashboard Status widget disappears because WC_Admin_Dashboard::status_widget() checks get_option( 'woocommerce_task_list_complete' ), but this option was removed and its value is now stored in woocommerce_task_list_complete_or_hidden (an option managed by TaskLists). The old option name is never populated, so the widget never renders.

This PR adds a DeprecatedOptions bridge in OnboardingTasks that registers woocommerce_task_list_complete as a deprecated option, mapping reads to the underlying woocommerce_task_list_complete_or_hidden option via pre_option_ and default_option_ filters. This restores the widget without modifying the legacy dashboard code.

This issue was discovered while testing the colour contrast fix in #63521.

Closes #55137.

How to test the changes in this Pull Request:

Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:

  1. Set up a WooCommerce store and complete the onboarding task list (or manually set the woocommerce_task_list_complete_or_hidden option to "yes" in the database).
  2. Navigate to WP Admin → Dashboard.
  3. Verify that the WooCommerce Status widget is visible and displays product, order, and stock data.
  4. Confirm that get_option( 'woocommerce_task_list_complete' ) returns "yes" when woocommerce_task_list_complete_or_hidden is "yes".

Testing that has already taken place:

  • PHPUnit tests added covering the DeprecatedOptions bridge (WC_Admin_Dashboard_Test).
  • Manual verification that the status widget appears after task list completion.

Milestone

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Significance

  • Patch

Type

  • Fix - Fixes an existing bug

Message

Fix dashboard status widget not appearing after completing the onboarding task list.

@github-actions github-actions Bot added the plugin: woocommerce Issues related to the WooCommerce Core plugin. label Mar 3, 2026
@jamesckemp jamesckemp marked this pull request as ready for review March 3, 2026 12:04
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 3, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Routes reads/writes for deprecated task-list options through DeprecatedOptions (init now final static and typed), removes several PHPStan baseline entries for DeprecatedOptions, and adds unit tests verifying WC_Admin_Dashboard widget visibility for task-list complete/hidden states and capability checks.

Changes

Cohort / File(s) Summary
PHPStan baseline
plugins/woocommerce/phpstan-baseline.neon
Removed multiple baseline entries for DeprecatedOptions.php (return-type and missing-return warnings); one baseline entry for calling is_connected() on a non-object remains.
Deprecated options handler
plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php
init() changed to final public static function init(): void; registers pre_option_* and pre_update_option_* filters for woocommerce_task_list_complete, woocommerce_task_list_hidden, and woocommerce_extended_task_list_hidden. get_deprecated_options() now returns values derived from task-list metadata; update_deprecated_options() synchronizes metadata, deletes deprecated keys, and returns prior values. Docblocks/type annotations widened to mixed.
Dashboard widget tests
plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php
Added WC_Admin_Dashboard_Test with setup/teardown, a reflection helper, and four tests covering widget visibility when task list is complete, hidden, neither, and when current user lacks capabilities.
Changelog
plugins/woocommerce/changelog/fix-55137-dashboard-status-widget-task-list-complete
Added patch-level fix note documenting the DeprecatedOptions bridge for woocommerce_task_list_complete.

Sequence Diagram

sequenceDiagram
    participant WP as WordPress Hook System
    participant DepOpts as DeprecatedOptions
    participant Meta as TaskList Metadata
    participant Dashboard as WC_Admin_Dashboard

    WP->>DepOpts: pre_option_woocommerce_task_list_complete
    activate DepOpts
    DepOpts->>Meta: read woocommerce_task_list_completed_lists
    Meta-->>DepOpts: completed lists
    alt 'setup' present
        DepOpts-->>WP: return 'yes'
    else
        DepOpts-->>WP: return 'no'
    end
    deactivate DepOpts

    WP->>DepOpts: pre_update_option_woocommerce_task_list_complete(value)
    activate DepOpts
    DepOpts->>Meta: add/remove 'setup' in completed lists
    DepOpts->>Meta: delete deprecated option key
    DepOpts-->>WP: return previous value
    deactivate DepOpts

    WP->>Dashboard: option values (possibly provided via DepOpts)
    activate Dashboard
    Dashboard->>Dashboard: should_display_widget() checks completion/hidden and user capabilities
    Dashboard-->>WP: widget visibility decision
    deactivate Dashboard
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: fixing the dashboard status widget visibility after task list completion, which is the primary objective of this PR.
Description check ✅ Passed The description is directly related to the changeset, explaining the problem, solution approach, testing instructions, and implementation details.
Linked Issues check ✅ Passed The PR fulfills the linked issue #55137 by implementing a DeprecatedOptions bridge that maps reads of woocommerce_task_list_complete to the new woocommerce_task_list_complete_or_hidden option, ensuring the dashboard widget displays after task list completion.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the dashboard widget visibility: the DeprecatedOptions bridge implementation, baseline cleanup, test coverage, and changelog entry are all in scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/55137-dashboard-status-widget-task-list-complete
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]

This comment was marked as resolved.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

Test using WordPress Playground

The changes in this pull request can be previewed and tested using a WordPress Playground instance.
WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Test this pull request with WordPress Playground.

Note that this URL is valid for 30 days from when this comment was last updated. You can update it by closing/reopening the PR or pushing a new commit.

@jamesckemp jamesckemp force-pushed the fix/55137-dashboard-status-widget-task-list-complete branch from c8aa094 to 02c8487 Compare March 3, 2026 14:13
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php (1)

122-147: Consider cleaning up the subscriber user in tearDown.

The subscriber user created at lines 131-138 is not explicitly deleted. While WordPress test framework may handle transactional cleanup, explicitly deleting or tracking test users for cleanup improves test isolation.

Option: Store and clean up subscriber user
 	public function tearDown(): void {
 		delete_option( 'woocommerce_task_list_completed_lists' );
 		delete_option( 'woocommerce_task_list_hidden' );
 		delete_option( 'woocommerce_task_list_hidden_lists' );
 		delete_option( 'woocommerce_task_list_complete' );
 		remove_all_filters( 'pre_option_woocommerce_task_list_complete' );
 		remove_all_filters( 'pre_option_woocommerce_task_list_hidden' );
+		wp_set_current_user( 0 );

 		parent::tearDown();
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php`
around lines 122 - 147, The test creates a subscriber user in
test_widget_does_not_show_without_capabilities() ($subscriber) but never deletes
it; update the test class (e.g., add a tearDown method or track created users in
a property like $this->created_users) to call wp_delete_user($subscriber) (or
loop over $this->created_users) after each test so the subscriber created in
test_widget_does_not_show_without_capabilities() is removed and test isolation
is preserved; reference the $subscriber variable and the test method name when
adding cleanup.
plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php (1)

85-85: Remove unused $update variable assignment.

The hide() / unhide() calls are needed for their side effects, but the return value is never used. This applies here and at line 93.

Proposed fix
-				$update = 'yes' === $value ? $task_list->hide() : $task_list->unhide();
+				'yes' === $value ? $task_list->hide() : $task_list->unhide();

Apply the same pattern at line 93.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php`
at line 85, In DeprecatedOptions (class DeprecatedOptions) remove the unused
assignment to $update and call the side-effecting methods directly — replace
"$update = 'yes' === $value ? $task_list->hide() : $task_list->unhide();" with a
direct conditional that invokes $task_list->hide() or $task_list->unhide()
without assigning the result; do the same for the second occurrence of this
pattern elsewhere in the file (the other hide()/unhide() call).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php`:
- Line 85: In DeprecatedOptions (class DeprecatedOptions) remove the unused
assignment to $update and call the side-effecting methods directly — replace
"$update = 'yes' === $value ? $task_list->hide() : $task_list->unhide();" with a
direct conditional that invokes $task_list->hide() or $task_list->unhide()
without assigning the result; do the same for the second occurrence of this
pattern elsewhere in the file (the other hide()/unhide() call).

In
`@plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php`:
- Around line 122-147: The test creates a subscriber user in
test_widget_does_not_show_without_capabilities() ($subscriber) but never deletes
it; update the test class (e.g., add a tearDown method or track created users in
a property like $this->created_users) to call wp_delete_user($subscriber) (or
loop over $this->created_users) after each test so the subscriber created in
test_widget_does_not_show_without_capabilities() is removed and test isolation
is preserved; reference the $subscriber variable and the test method name when
adding cleanup.

ℹ️ Review info

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81a5acf and 02c8487.

📒 Files selected for processing (3)
  • plugins/woocommerce/phpstan-baseline.neon
  • plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php
  • plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php
💤 Files with no reviewable changes (1)
  • plugins/woocommerce/phpstan-baseline.neon

- Use add_filter instead of add_action for pre_update_option_* hooks
- Add void return type to init(), mixed types to filter callbacks
- Return $old_value to skip DB writes instead of false (which stored literal false)
- Add is_array() guards before in_array() calls for defensive safety
- Add default cases to switch statements for complete code paths
- Remove 6 resolved PHPStan baseline entries for DeprecatedOptions.php
- Rename misleading $author variable to $subscriber in dashboard test
@jamesckemp jamesckemp force-pushed the fix/55137-dashboard-status-widget-task-list-complete branch from 02c8487 to ff2cefd Compare March 3, 2026 17:07
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php (1)

85-85: Remove unused $update local variable.

The assigned value is never used; call hide()/unhide() directly to avoid dead stores and keep PHPMD clean.

Suggested cleanup
-				$update = 'yes' === $value ? $task_list->hide() : $task_list->unhide();
+				'yes' === $value ? $task_list->hide() : $task_list->unhide();
...
-				$update = 'yes' === $value ? $task_list->hide() : $task_list->unhide();
+				'yes' === $value ? $task_list->hide() : $task_list->unhide();

Also applies to: 93-93

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php`
at line 85, Remove the unused local variable $update in DeprecatedOptions.php by
replacing the assignment $update = 'yes' === $value ? $task_list->hide() :
$task_list->unhide(); with a direct conditional call so you invoke
$task_list->hide() or $task_list->unhide() without assigning the result; do the
same for the similar statement at the other occurrence (line shown as 93) to
eliminate the dead store and satisfy PHPMD.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php`:
- Line 85: Remove the unused local variable $update in DeprecatedOptions.php by
replacing the assignment $update = 'yes' === $value ? $task_list->hide() :
$task_list->unhide(); with a direct conditional call so you invoke
$task_list->hide() or $task_list->unhide() without assigning the result; do the
same for the similar statement at the other occurrence (line shown as 93) to
eliminate the dead store and satisfy PHPMD.

ℹ️ Review info

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02c8487 and ff2cefd.

📒 Files selected for processing (3)
  • plugins/woocommerce/phpstan-baseline.neon
  • plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php
  • plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php
💤 Files with no reviewable changes (1)
  • plugins/woocommerce/phpstan-baseline.neon
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php

@jamesckemp jamesckemp requested a review from PanosSynetos March 3, 2026 23:03
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

Testing Guidelines

Hi @kraftbj ,

Apart from reviewing the code changes, please make sure to review the testing instructions (Guide) and verify that relevant tests (E2E, Unit, Integration, etc.) have been added or updated as needed.

Reminder: PR reviewers are required to document testing performed. This includes:

  • 🖼️ Screenshots or screen recordings.
  • 📝 List of functionality tested / steps followed.
  • 🌐 Site details (environment attributes such as hosting type, plugins, theme, store size, store age, and relevant settings).
  • 🔍 Any analysis performed, such as assessing potential impacts on environment attributes and other plugins, conducting performance profiling, or using LLM/AI-based analysis.

⚠️ Within the testing details you provide, please ensure that no sensitive information (such as API keys, passwords, user data, etc.) is included in this public issue.

@jamesckemp jamesckemp added this to the 10.7.0 milestone Mar 3, 2026
Add final and @internal to init() for PHPCS InternalInjectionMethod
rule. Use $sut convention in dashboard tests. Add changelog entry.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php (1)

87-97: Remove unused $update assignments in hidden/unhidden branches.

Line 87 and Line 95 assign $update but never use it. This adds noise and can be simplified.

Refactor suggestion
-				$update = 'yes' === $value ? $task_list->hide() : $task_list->unhide();
+				if ( 'yes' === $value ) {
+					$task_list->hide();
+				} else {
+					$task_list->unhide();
+				}
 				delete_option( 'woocommerce_task_list_hidden' );
 				return $old_value;
@@
-				$update = 'yes' === $value ? $task_list->hide() : $task_list->unhide();
+				if ( 'yes' === $value ) {
+					$task_list->hide();
+				} else {
+					$task_list->unhide();
+				}
 				delete_option( 'woocommerce_extended_task_list_hidden' );
 				return $old_value;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php`
around lines 87 - 97, Remove the unused $update assignments in the branches that
call TaskLists::get_list('default'/'extended') and then call $task_list->hide()
or $task_list->unhide(); the result is not used, so delete the `$update =`
assignment and just call `$task_list->hide()` or `$task_list->unhide()` directly
before calling delete_option('woocommerce_task_list_hidden') /
delete_option('woocommerce_extended_task_list_hidden') and returning $old_value;
ensure you update both cases that reference $task_list, hide(), unhide(), and
the corresponding delete_option calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php`:
- Around line 77-130: The tests currently stub
pre_option_woocommerce_task_list_* filters and bypass the DeprecatedOptions
bridge; update the three tests (test_widget_shows_when_task_list_complete,
test_widget_shows_when_task_list_hidden, and
test_widget_does_not_show_without_capabilities) to set the real underlying
option arrays (update_option('woocommerce_task_list_completed_lists', ...) and
update_option('woocommerce_task_list_hidden_lists', ...)) that DeprecatedOptions
maps from, then assert via get_option('woocommerce_task_list_complete') /
get_option('woocommerce_task_list_hidden') that the bridge returns the expected
values and finally call invoke_should_display_widget($this->sut) to verify
widget visibility; keep invoke_should_display_widget and the DeprecatedOptions
mapping logic intact so regressions in the bridge are caught.

---

Nitpick comments:
In
`@plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php`:
- Around line 87-97: Remove the unused $update assignments in the branches that
call TaskLists::get_list('default'/'extended') and then call $task_list->hide()
or $task_list->unhide(); the result is not used, so delete the `$update =`
assignment and just call `$task_list->hide()` or `$task_list->unhide()` directly
before calling delete_option('woocommerce_task_list_hidden') /
delete_option('woocommerce_extended_task_list_hidden') and returning $old_value;
ensure you update both cases that reference $task_list, hide(), unhide(), and
the corresponding delete_option calls.

ℹ️ Review info

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff2cefd and d59a090.

📒 Files selected for processing (3)
  • plugins/woocommerce/changelog/fix-55137-dashboard-status-widget-task-list-complete
  • plugins/woocommerce/src/Admin/Features/OnboardingTasks/DeprecatedOptions.php
  • plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php
✅ Files skipped from review due to trivial changes (1)
  • plugins/woocommerce/changelog/fix-55137-dashboard-status-widget-task-list-complete

Comment thread plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php (1)

77-84: ⚠️ Potential issue | 🟠 Major

Tests bypass the DeprecatedOptions bridge they intend to protect.

Three tests (test_widget_shows_when_task_list_complete, test_widget_shows_when_task_list_hidden, test_widget_does_not_show_without_capabilities) add their own pre_option_* filters that return 'yes' directly, which circumvents the DeprecatedOptions::get_deprecated_options() mapping logic. These tests will pass even if the bridge is broken.

To actually test the bridge, set the underlying options instead:

// For "task list complete":
update_option( 'woocommerce_task_list_completed_lists', array( 'setup' ) );

// For "task list hidden":
update_option( 'woocommerce_task_list_hidden_lists', array( 'setup' ) );

Then assert via get_option( 'woocommerce_task_list_complete' ) returning 'yes' before checking widget visibility. This ensures regressions in the bridge are caught.

,

Also applies to: 89-96, 114-132

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php`
around lines 77 - 84, The tests (test_widget_shows_when_task_list_complete,
test_widget_shows_when_task_list_hidden,
test_widget_does_not_show_without_capabilities) currently bypass the
DeprecatedOptions bridge by adding pre_option_* filters; instead set the
underlying options using update_option('woocommerce_task_list_completed_lists',
array('setup')) for the "complete" case and
update_option('woocommerce_task_list_hidden_lists', array('setup')) for the
"hidden" case, then assert get_option('woocommerce_task_list_complete') returns
'yes' (or the expected value) before calling
invoke_should_display_widget($this->sut) so the
DeprecatedOptions::get_deprecated_options() mapping is exercised and regressions
are caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php`:
- Around line 77-84: The tests (test_widget_shows_when_task_list_complete,
test_widget_shows_when_task_list_hidden,
test_widget_does_not_show_without_capabilities) currently bypass the
DeprecatedOptions bridge by adding pre_option_* filters; instead set the
underlying options using update_option('woocommerce_task_list_completed_lists',
array('setup')) for the "complete" case and
update_option('woocommerce_task_list_hidden_lists', array('setup')) for the
"hidden" case, then assert get_option('woocommerce_task_list_complete') returns
'yes' (or the expected value) before calling
invoke_should_display_widget($this->sut) so the
DeprecatedOptions::get_deprecated_options() mapping is exercised and regressions
are caught.

ℹ️ Review info

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d59a090 and 1671e96.

📒 Files selected for processing (1)
  • plugins/woocommerce/tests/php/includes/admin/class-wc-admin-dashboard-test.php

@jamesckemp
Copy link
Copy Markdown
Collaborator Author

Response for CodeRabbit's concerns:

These tests intentionally use pre_option_* filters because they're testing should_display_widget logic, not the bridge itself.

The suggested update_option approach doesn't work in the test environment — WC_INSTALLING is permanently true (set by WC_Install::install() in the bootstrap and never unset), which causes the bridge's init() guard clause to bail out. As a result, get_option('woocommerce_task_list_complete') returns false regardless of what's set in the underlying options, and the tests pass for the wrong reason.

You're right that bridge regressions aren't caught here — but that's a case for a dedicated DeprecatedOptionsTest, not for coupling the dashboard widget tests to the bridge.

@jamesckemp jamesckemp requested review from kraftbj and removed request for PanosSynetos March 10, 2026 11:43
@jamesckemp jamesckemp assigned kraftbj and unassigned PanosSynetos Mar 10, 2026
kraftbj added 5 commits March 19, 2026 13:25
…a loss

- Tests now use DeprecatedOptions::init() and set the underlying modern
  options (woocommerce_task_list_completed_lists / hidden_lists) instead
  of adding pre_option filters that bypass the bridge entirely.
- Add two direct bridge tests: one verifying the option mapping and one
  for non-array (corrupt) option data.
- Move delete_option inside the is_array guard in update_deprecated_options
  so a corrupt completed_lists value does not cause silent data loss.
WC_INSTALLING is permanently true in the test environment (set by
WC_Install::install() in the bootstrap), so the DeprecatedOptions
bridge bails out when called through get_option(). The widget tests
correctly use pre_option filters to test should_display_widget logic
in isolation.

The two bridge-specific tests now call DeprecatedOptions::get_deprecated_options()
directly, bypassing the WC_INSTALLING guard while still verifying the
mapping logic and corrupt-data handling.
WC_INSTALLING is permanently true in the test bootstrap, and the
DeprecatedOptions::get_deprecated_options guard checks this constant
even on direct calls. Bridge testing is not possible in this environment.
The widget tests via pre_option filters adequately cover the fix.
@kraftbj kraftbj merged commit e6e7b48 into trunk Mar 20, 2026
37 checks passed
@kraftbj kraftbj deleted the fix/55137-dashboard-status-widget-task-list-complete branch March 20, 2026 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WooCommerce Status Dashboard Widget doesn't get enabled when setup tasklist is complete

3 participants