Skip to content

fix(checkout): harden step validation scoping#1336

Merged
superdav42 merged 1 commit into
mainfrom
fix/checkout-validation-1332
Jun 3, 2026
Merged

fix(checkout): harden step validation scoping#1336
superdav42 merged 1 commit into
mainfrom
fix/checkout-validation-1332

Conversation

@superdav42
Copy link
Copy Markdown
Collaborator

@superdav42 superdav42 commented Jun 2, 2026

Summary

  • Hardens checkout client-side validation scoping so stale or missing wu_checkout.step_fields falls back to fields rendered on the current form step instead of validating every global rule.
  • Adds validation-rule aliases to step_fields for checkout field types whose rendered/value key differs from the builder field id (template_selectiontemplate_id, pricing_tableproducts).
  • Extends the step-fields regression test with an account → template/site → payment flow to guard against revalidating guest email/username/password on the template step.

Issue verification

  • Verified PR fix(checkout): restrict client-side validation to current step fields only #763 is already included in v2.12.0 (git tag --contains a3a6f7c... returned v2.12.0), so the issue body's release-status note was incorrect.
  • Browser Agent local reproduction with a guest multi-step checkout reached the later step with errors: []; the exact email/username/password client errors were not reproducible on current v2.12.0 code.
  • The same browser run showed the template step still used the raw template_selection field id in step_fields, while the JS validation rule key is template_id; this PR fixes that mismatch and adds a defensive fallback for stale step maps.

Verification

  • vendor/bin/phpunit --filter Checkout_Step_Fields_Test — passes (2 tests, 31 assertions; existing PHP 8.4 deprecation notices emitted by dependencies)
  • vendor/bin/phpcs inc/checkout/class-checkout.php tests/unit/Checkout_Step_Fields_Test.php — passes
  • node_modules/.bin/eslint assets/js/checkout.js --ignore-pattern '*.min.js' — passes (Browserslist age warning only)
  • git diff --check — passes

Resolves #1332


Summary by CodeRabbit

  • Bug Fixes

    • Enhanced checkout validation to more accurately handle multi-step forms, reducing blocking errors caused by fields previously submitted on earlier steps that are no longer visible on the current step.
  • Tests

    • Expanded test coverage for multi-step checkout field validation and step-specific field partitioning.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cd88d210-bd85-4872-9a3f-d445c63db9ce

📥 Commits

Reviewing files that changed from the base of the PR and between 0b7fe4e and 9ab69ff.

📒 Files selected for processing (3)
  • assets/js/checkout.js
  • inc/checkout/class-checkout.php
  • tests/unit/Checkout_Step_Fields_Test.php

📝 Walkthrough

Walkthrough

Checkout validation for multi-step forms now filters rules per-step: the backend maps rule keys per step (including type-specific rules like template_id), the frontend validates only rendered fields with a DOM-based fallback, and tests assert proper field partitioning. This unblocks guest users from advancing past early steps.

Changes

Multi-step checkout validation step-scoping

Layer / File(s) Summary
Backend step_fields mapping with per-field rules
inc/checkout/class-checkout.php
get_checkout_variables() now builds the step_fields map per-step by reading each field's id and applying type-specific rule mappings: template_selectiontemplate_id, pricing_tableproducts. The resulting map is de-duplicated and filtered, replacing the previous simple id-only extraction.
Frontend DOM-based validation fallback
assets/js/checkout.js
validate_client_side() collects currently rendered field names from the serialized form and applies a two-phase rule selection: it prefers PHP-provided step_fields for the active step, but falls back to validating only DOM-present fields when server data is missing or stale. This unblocks guests by preventing validation of fields submitted on earlier steps but no longer rendered.
Test fixture and multi-step field partitioning assertions
tests/unit/Checkout_Step_Fields_Test.php
Extended test fixture to three distinct steps (account with submit, new site with template_selection and submit, payment with order_summary and submit). Step 1 assertions verify it does not demand site/template-only or payment fields, and new site_fields assertions verify the site step validates its own fields without revalidating guest credentials. Partitioning test expands coverage to include all site/template fields alongside account/payment fields, confirming no single step captures the full field set.

Sequence Diagram

sequenceDiagram
  participant Guest as Guest User
  participant Account as Account Step
  participant Template as Template Step
  participant Checkout as Checkout (PHP)
  participant Validator as validate_client_side (JS)

  Guest->>Account: Fill email, username, password
  Account->>Validator: Submit form
  Validator->>Checkout: Request step_fields map
  Checkout->>Validator: Return {account: [email_address, username, ...], template: [site_title, template_id, ...]}
  Validator->>Validator: Validate only account fields (rendered in form)
  Validator->>Template: Advance to template step

  Guest->>Template: Select template
  Template->>Validator: Submit form (email/username/password no longer rendered)
  Validator->>Checkout: Validate step_fields for template step
  Validator->>Validator: Fallback: extract rendered fields from DOM
  Validator->>Validator: Validate only {site_title, template_id, ...} (no account fields)
  Validator->>Guest: Success - advance to payment
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Ultimate-Multisite/ultimate-multisite#763: Directly implements step-scoped client-side validation via step_fields mapping and DOM-based fallback, addressing the root cause of guest user blocking on template-selection steps.

Suggested labels

review-feedback-scanned, status:available

Poem

🐰 A guest once got trapped in the template stage,
Credentials demanded from an earlier page!
Now fields stay where cast—each step knows its own,
With fallback to DOM when the server won't phone.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(checkout): harden step validation scoping' directly and clearly summarizes the main change: improving client-side checkout validation to use only rendered fields when step configuration is unavailable.
Linked Issues check ✅ Passed The PR fully addresses issue #1332 by implementing fallback validation logic in assets/js/checkout.js and adding validation-rule aliases in inc/checkout/class-checkout.php to prevent re-validation of account fields on subsequent steps.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the reported issue: client-side fallback logic, validation rule aliases, and comprehensive test coverage for multi-step checkout validation.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/checkout-validation-1332

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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@superdav42 superdav42 force-pushed the fix/checkout-validation-1332 branch from 738671a to 9ab69ff Compare June 3, 2026 01:52
@superdav42
Copy link
Copy Markdown
Collaborator Author

MERGE_SUMMARY

Updated fix/checkout-validation-1332 onto current main and pushed the rebased checkout validation scoping fix.

Evidence:

  • bash bin/check-env.sh — passed; vendor, npm, WP-CLI, shared WordPress install, and /tmp/wordpress-tests-lib available.
  • WP_TESTS_DIR=/tmp/wordpress-tests-lib vendor/bin/phpunit --filter Checkout_Step_Fields_Test — passed (2 tests, 31 assertions; existing dependency deprecation notices only).
  • vendor/bin/phpcs inc/checkout/class-checkout.php tests/unit/Checkout_Step_Fields_Test.php — passed.
  • node_modules/.bin/eslint assets/js/checkout.js --ignore-pattern '*.min.js' — passed (Browserslist age warning only).
  • git diff --check — passed.

Branch evidence:

  • Rebased PR commit: 9ab69ff2 fix(checkout): harden step validation scoping.
  • PR diff remains limited to assets/js/checkout.js, inc/checkout/class-checkout.php, and tests/unit/Checkout_Step_Fields_Test.php.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@superdav42 superdav42 merged commit b26182b into main Jun 3, 2026
10 of 11 checks passed
@superdav42 superdav42 deleted the fix/checkout-validation-1332 branch June 3, 2026 11:18
@superdav42 superdav42 added the review-feedback-scanned Merged PR already scanned for quality feedback label Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-feedback-scanned Merged PR already scanned for quality feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.

checkout: email/username/password required errors fire on template-selection step for guest users

1 participant