Skip to content

test: executable regression tests for known production bugs (replaces #1312)#1313

Merged
superdav42 merged 4 commits into
mainfrom
kp/regression-tests
May 29, 2026
Merged

test: executable regression tests for known production bugs (replaces #1312)#1313
superdav42 merged 4 commits into
mainfrom
kp/regression-tests

Conversation

@kenedytorcatt
Copy link
Copy Markdown
Contributor

@kenedytorcatt kenedytorcatt commented May 29, 2026

Hi David — you were right that the grep guard in #1312 tests nothing (it never runs the code). This replaces it with real PHPUnit tests that execute the methods and assert the result, in your own framework.

Files (all under tests/, picked up by your existing phpunit.xml.dist):

File Bug Executes
tests/WP_Ultimo/Managers/Regression_Pending_Site_And_Subdomain_Test.php #4 pending site stuck (PR #1267) + #5 wu_add_subdomain guard under wildcard DNS (case Eva) Stale publishing flag → Membership_Manager::check_pending_site_created() resets it + returns stopped; no listener → Domain_Manager::handle_site_created() enqueues no job; with listener → it does
tests/unit/Cart_Should_Collect_Payment_Test.php trial must collect payment (else routes to free gateway, skips WooCommerce → dry site, no order/email) Real Cart::should_collect_payment() on a trial cart with allow_trial_without_payment_method=false → asserts true
tests/unit/Checkout_Step_Fields_Test.php multi-step registration blocked on Step 1 Real Checkout::get_checkout_variables() → asserts step_fields partitions fields per step

Each test has a doc-block with the real customer case. I couldn't run your live test DB here, so validated with php -l + modeled 1:1 on your passing tests (Domain_Manager_Test, Checkout_Request_Test). Please run in CI. No production code touched.

Closing #1312 in favor of this.

Summary by CodeRabbit

  • Tests
    • Added regression test coverage for checkout flows, verifying payment collection behavior for trials and recurring plans.
    • Added validation tests for multi-step checkout field partitioning and per-step form behavior.
    • Added integration tests for pending site publishing state and async domain job enqueueing during site creation.

Review Change Stack

Replaces the grep-based guard (PR #1312) with real PHPUnit tests that
execute the methods and assert the expected result, per maintainer feedback.

- Regression_Pending_Site_And_Subdomain_Test: bug #4 (pending site stuck,
  Membership_Manager::check_pending_site_created stale-flag reset wiring)
  + bug #5 (wu_add_subdomain enqueue guard under wildcard DNS, case Eva).
- Cart_Should_Collect_Payment_Test: a trial with allow_trial_without_payment_method
  off must still collect payment (route to woocommerce gateway, not free).
- Checkout_Step_Fields_Test: step_fields partitions fields per step so the
  multi-step registration does not demand all fields on Step 1.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

📝 Walkthrough

Walkthrough

This PR adds three new PHPUnit test files totaling 768 lines. Two test suites cover pending-site publishing state transitions and cart payment logic; a third validates checkout step-field organization for multi-step forms.

Changes

Test Coverage Addition

Layer / File(s) Summary
Pending Site & Subdomain Regression Tests
tests/WP_Ultimo/Managers/Regression_Pending_Site_And_Subdomain_Test.php
Regression tests for BUG 4 and BUG 5: verifies stale/fresh publishing flags are reset/preserved correctly and return publish_status=stopped/running; verifies Domain_Manager::handle_site_created() enqueues wu_add_subdomain async jobs only when listeners are registered. Includes setup/teardown logic for test customer and manager initialization.
Cart Payment Collection Tests
tests/unit/Cart_Should_Collect_Payment_Test.php
Tests Cart::should_collect_payment() across paid recurring plans, trials when payment is required, and the dangerous outage configuration where allow_trial_without_payment_method=true causes trials to skip payment. Includes helper to build carts with specific product types and guards against a May 2026 regression.
Checkout Step Field Partitioning Tests
tests/unit/Checkout_Step_Fields_Test.php
Validates that multi-step checkout forms partition fields correctly by step via get_checkout_variables() output. Builds a two-step fixture (account + payment) with scoped fields and asserts per-step field maps are separate and complete, preventing Vue validation issues.

Possibly related PRs

  • Ultimate-Multisite/ultimate-multisite#569: Both PRs extend test coverage for \WP_Ultimo\Checkout\Checkout—this PR's Checkout_Step_Fields_Test and PR #569's Checkout_Test both assert behavior derived from get_checkout_variables()/step-related output.
  • Ultimate-Multisite/ultimate-multisite#372: Both PRs concern the pending-site publishing flow: this PR adds regression tests around is_publishing/publish_status behavior, and PR #372 updates Membership::publish_pending_site() to reset is_publishing on failure (the state these tests assert).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

Poem

🐰 Three test files hop into view,
Guarding BUG 4 & 5 so true!
Cart steps dance, fields partition clean,
Regressions caught—no slip between! 🥕✨

🚥 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 accurately summarizes the main change: adding executable regression tests for known production bugs, replacing a grep-based approach.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 kp/regression-tests

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

🔨 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

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: 2

🧹 Nitpick comments (2)
tests/unit/Cart_Should_Collect_Payment_Test.php (2)

1-2: ⚡ Quick win

Add the required ABSPATH guard at file start.

This file should include the standard guard immediately after <?php.

Proposed fix
 <?php
+defined('ABSPATH') || exit;
 /**
  * Regression guard for WP_Ultimo\Checkout\Cart::should_collect_payment().

As per coding guidelines, "Every PHP file must start with defined('ABSPATH') || exit;".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/Cart_Should_Collect_Payment_Test.php` around lines 1 - 2, Add the
standard WordPress ABSPATH guard immediately after the opening PHP tag in the
tests/unit/Cart_Should_Collect_Payment_Test.php file: insert the check using
defined('ABSPATH') || exit; as the first statement following <?php so the file
exits when ABSPATH is not defined.

60-60: ⚡ Quick win

Remove spaces inside short array brackets.

Use compact short-array syntax for single-line arrays.

Proposed fix
-				'products'      => [ $product_id ],
+				'products'      => [$product_id],

As per coding guidelines, "Use short array syntax [] with no spaces inside brackets: ['key' => 'val']".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/Cart_Should_Collect_Payment_Test.php` at line 60, The array for
the 'products' key uses spaced short-array brackets ([ $product_id ])—remove the
inner spaces so it becomes compact short-array syntax ('products' =>
[$product_id]); update this occurrence in the Cart_Should_Collect_Payment_Test
(where $product_id is used) to follow the project's short-array-without-spaces
style for single-line arrays.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/Checkout_Step_Fields_Test.php`:
- Line 11: The test class Checkout_Step_Fields_Test currently extends
PHPUnit\Framework\TestCase and creates persistent data via
wu_create_checkout_form() (which triggers Checkout_Form->save() /
Base_Model::save()), so switch the test class to extend WP_UnitTestCase (or add
a tearDown() that deletes any created forms) to get per-test DB isolation and
avoid leaking step-fields-guard-form-* rows; update the class declaration for
Checkout_Step_Fields_Test to extend WP_UnitTestCase (or implement teardown logic
that deletes records created by wu_create_checkout_form()), and fix the lint
warning by removing the extra spaces around the is_wp_error() call at the
assertion currently written like "( is_wp_error($form) ... )".

In `@tests/WP_Ultimo/Managers/Regression_Pending_Site_And_Subdomain_Test.php`:
- Line 1: This test file is missing the required early-exit ABSPATH guard at the
top; open the test file and immediately after the opening PHP tag add the
standard WordPress guard statement defined('ABSPATH') || exit; so the file exits
early when ABSPATH is not defined (ensure it's the very first executable line),
then run tests to confirm no parsing errors.

---

Nitpick comments:
In `@tests/unit/Cart_Should_Collect_Payment_Test.php`:
- Around line 1-2: Add the standard WordPress ABSPATH guard immediately after
the opening PHP tag in the tests/unit/Cart_Should_Collect_Payment_Test.php file:
insert the check using defined('ABSPATH') || exit; as the first statement
following <?php so the file exits when ABSPATH is not defined.
- Line 60: The array for the 'products' key uses spaced short-array brackets ([
$product_id ])—remove the inner spaces so it becomes compact short-array syntax
('products' => [$product_id]); update this occurrence in the
Cart_Should_Collect_Payment_Test (where $product_id is used) to follow the
project's short-array-without-spaces style for single-line arrays.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c52709e9-6697-4d53-af85-3e4918f1a9a0

📥 Commits

Reviewing files that changed from the base of the PR and between 5b6876c and 2e158df.

📒 Files selected for processing (3)
  • tests/WP_Ultimo/Managers/Regression_Pending_Site_And_Subdomain_Test.php
  • tests/unit/Cart_Should_Collect_Payment_Test.php
  • tests/unit/Checkout_Step_Fields_Test.php


use PHPUnit\Framework\TestCase;

final class Checkout_Step_Fields_Test extends TestCase {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 1) What base class do sibling tests use, and is this the only TestCase one?
rg -nP --type=php 'class\s+\w+_Test\s+extends\s+\w+' -g 'tests/**'

# 2) Definition/signature of wu_create_checkout_form and the expected steps key.
ast-grep --pattern 'function wu_create_checkout_form($$$) { $$$ }'
rg -nP --type=php '\bwu_create_checkout_form\b' -C3

# 3) Which bootstrap does tests/unit use, and does it load the WP test suite?
fd -t f 'phpunit*.xml*'
rg -nP -C2 '(bootstrap|testsuite|directory)' -g 'phpunit*.xml*'
rg -nP --type=php "(require.*wp-tests|tests_add_filter|WP_UnitTestCase)" -g 'tests/**bootstrap*'

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 50001


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show relevant parts of the specific test file
echo "---- tests/unit/Checkout_Step_Fields_Test.php (head/tail around methods) ----"
sed -n '1,220p' tests/unit/Checkout_Step_Fields_Test.php

echo "---- tests/bootstrap.php ----"
sed -n '1,200p' tests/bootstrap.php

echo "---- tests/bootstrap.php: look for wp-phpunit bootstrap or WP test case setup ----"
rg -n "WP_UnitTestCase|wp-tests|tests_add_filter|define\\('ABSPATH'|require_once|load\\w*tests|set_up|tear_down" tests/bootstrap.php

echo "---- phpunit.xml.dist ----"
cat -n phpunit.xml.dist | sed -n '1,120p'

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 10107


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- tests/unit/Checkout_Step_Fields_Test.php ----"
sed -n '1,220p' tests/unit/Checkout_Step_Fields_Test.php

echo "---- tests/bootstrap.php ----"
sed -n '1,220p' tests/bootstrap.php

echo "---- bootstrap checks ----"
rg -n "WP_UnitTestCase|wp-tests|tests_add_filter|bootstrap|require_once|wp_die|wpdb|setUp|tearDown" tests/bootstrap.php || true

echo "---- phpunit.xml.dist ----"
cat -n phpunit.xml.dist | sed -n '1,140p'

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 10184


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Locate Checkout class and get_checkout_variables implementation ----"
rg -n --type=php 'class Checkout\b' -S inc tests
# likely file path; show matches for get_checkout_variables + step_fields
rg -n --type=php 'function get_checkout_variables' -S inc
rg -n --type=php '\bstep_fields\b' -S inc

echo "---- Show relevant part of get_checkout_variables (context) ----"
# take first few matches
rg -n --type=php 'function get_checkout_variables' -S inc | head -n 20 | while read -r line; do echo "$line"; done
# print around the method in the file(s) where it appears
files=$(rg -l --type=php 'function get_checkout_variables' inc | tr '\n' ' ')
for f in $files; do
  echo "=== $f ==="
  rg -n --type=php 'function get_checkout_variables' "$f" -C 4 || true
done

echo "---- Inspect Manager_Test_Trait to see if it handles isolation/cleanup ----"
ls -la tests/WP_Ultimo/Managers/Manager_Test_Trait.php
sed -n '1,260p' tests/WP_Ultimo/Managers/Manager_Test_Trait.php

echo "---- Check line 72 lint/whitespace in Checkout_Step_Fields_Test.php ----"
nl -ba tests/unit/Checkout_Step_Fields_Test.php | sed -n '60,95p'

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 4485


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Checkout::get_checkout_variables() step_fields building ----"
sed -n '2280,2385p' inc/checkout/class-checkout.php

echo "---- Checkout_Form::save() persistence check (look for INSERT/UPDATE/wpdb) ----"
rg -n --type=php "function save\\(" inc | head -n 20
checkout_form_file=$(rg -n --type=php "class Checkout_Form" inc | head -n 1 | cut -d: -f1)
echo "Checkout_Form file: $checkout_form_file"
sed -n '1,120p' "$checkout_form_file"
rg -n --type=php "function save\\(" "$checkout_form_file" -n
# show around save()
line_save=$(rg -n --type=php "function save\\(" "$checkout_form_file" | head -n 1 | cut -d: -f1)
start=$((line_save-60))
end=$((line_save+140))
sed -n "${start},${end}p" "$checkout_form_file"
rg -n --type=php "\\$wpdb->(insert|update|query)" "$checkout_form_file" || true
rg -n --type=php "\\binsert\\b|\\bupdate\\b" "$checkout_form_file" || true

echo "---- Find whitespace/static-analysis warning around spaces inside parentheses ----"
# Specifically look for pattern "( is_" (space right after "(")
rg -n "assert.*\( is_wp_error|\\( is_wp_error|\\(\\s+is_wp_error" tests/unit/Checkout_Step_Fields_Test.php || true
rg -n "assert.*\\(.* is_" tests/unit/Checkout_Step_Fields_Test.php || true
# Also show line numbers around the message string with is_wp_error
cat -n tests/unit/Checkout_Step_Fields_Test.php | sed -n '1,140p'

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 11488


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Does tests/unit/ use wu_create_checkout_form() elsewhere? ----"
rg -n --type=php "\bwu_create_checkout_form\b" tests/unit

echo "---- Inspect Checkout_Form::get_steps_to_show() ----"
rg -n --type=php "function get_steps_to_show" inc/models/class-checkout-form.php
line=$(rg -n --type=php "function get_steps_to_show" inc/models/class-checkout-form.php | head -n1 | cut -d: -f1)
start=$((line-40))
end=$((line+120))
sed -n "${start},${end}p" inc/models/class-checkout-form.php

echo "---- Inspect persistence path for Checkout_Form save(): where does Base_Model::save write to DB? ----"
rg -n --type=php "class Base_Model|function save\(" inc/models/class-base-model.php
base_save_line=$(rg -n --type=php "function save\\(" inc/models/class-base-model.php | head -n1 | cut -d: -f1)
start=$((base_save_line-40))
end=$((base_save_line+220))
sed -n "${start},${end}p" inc/models/class-base-model.php

echo "---- Search for wpdb usage in Base_Model save ----"
rg -n --type=php "\$wpdb->(insert|update|query|prepare)" inc/models/class-base-model.php

echo "---- Pinpoint whitespace/static-analysis warning in Checkout_Step_Fields_Test.php (line ~72) ----"
python3 - <<'PY'
import pathlib
p = pathlib.Path("tests/unit/Checkout_Step_Fields_Test.php")
lines = p.read_text(encoding="utf-8").splitlines()
for i in range(60, 90):
    if 1 <= i <= len(lines):
        print(f"{i:3d}: {lines[i-1]}")
PY

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 10267


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Checkout_Form_Query location ----"
rg -n --type=php 'class Checkout_Form_Query' inc

query_file=$(rg -n --type=php 'class Checkout_Form_Query' inc | head -n1 | cut -d: -f1)
echo "Query file: $query_file"

echo "---- Inspect Checkout_Form_Query add_item/update_item for $wpdb usage ----"
if [ -n "${query_file}" ] && [ -f "${query_file}" ]; then
  rg -n --type=php '\$wpdb->(insert|update|query|prepare|replace)' "$query_file" || true
  rg -n --type=php 'function (add_item|update_item)\b' "$query_file" -n || true
  # show around add_item/update_item implementations
  for fn in add_item update_item; do
    ln=$(rg -n --type=php "function $fn\\b" "$query_file" | head -n1 | cut -d: -f1 || true)
    if [ -n "$ln" ]; then
      start=$((ln-60)); end=$((ln+140))
      echo "=== $fn around line $ln ==="
      sed -n "${start},${end}p" "$query_file"
    fi
  done
fi

echo "---- Pinpoint warning around line 72 in tests/unit/Checkout_Step_Fields_Test.php ----"
python3 - <<'PY'
from pathlib import Path
p = Path("tests/unit/Checkout_Step_Fields_Test.php")
lines = p.read_text(encoding="utf-8").splitlines()
for i in range(65, 80):
    if i-1 < len(lines):
        print(f"{i:3d}: {lines[i-1]}")
PY

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 354


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Checkout_Form_Query: look for \$wpdb usage ----"
query_file="inc/database/checkout-forms/class-checkout-form-query.php"
sed -n '1,240p' "$query_file" | head -n 240
rg -n --type=php '\\$wpdb->(insert|update|query|prepare|replace)' "$query_file" || true
rg -n --type=php 'function (add_item|update_item)\b' "$query_file" || true
for fn in add_item update_item; do
  ln=$(rg -n --type=php "function $fn\\b" "$query_file" | head -n1 | cut -d: -f1 || true)
  if [ -n "$ln" ]; then
    start=$((ln-60)); end=$((ln+160))
    echo "=== $fn around line $ln ==="
    sed -n "${start},${end}p" "$query_file"
  fi
done

echo "---- wu_create_checkout_form definition (to show it calls Checkout_Form->save) ----"
fnfile="inc/functions/checkout-form.php"
rg -n --type=php 'function wu_create_checkout_form\\b' "$fnfile"
start=$(rg -n --type=php 'function wu_create_checkout_form\\b' "$fnfile" | head -n1 | cut -d: -f1)
sed -n "$((start-20)),$((start+60))p" "$fnfile"

echo "---- Exact whitespace warning line in Checkout_Step_Fields_Test.php ----"
python3 - <<'PY'
from pathlib import Path
p = Path("tests/unit/Checkout_Step_Fields_Test.php")
lines = p.read_text(encoding="utf-8").splitlines()
for idx, line in enumerate(lines, start=1):
    if " ( is_wp_error(" in line or "( is_wp_error(" in line:
        print(f"Found whitespace pattern on line {idx}: {line.strip()}")
PY

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 2002


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Inspect Query engine base class for \$wpdb usage (add_item/update_item) ----"
query_base=$(rg -n --type=php "class Query\\b" inc/database/engine -S | head -n1 | cut -d: -f1)
echo "Query base file: $query_base"
sed -n '1,260p' "$query_base"
rg -n --type=php '\\$wpdb->(insert|update|query|prepare|replace)' "$query_base" || true
for fn in add_item update_item; do
  ln=$(rg -n --type=php "function $fn\\b" "$query_base" | head -n1 | cut -d: -f1 || true)
  if [ -n "${ln}" ]; then
    start=$((ln-60)); end=$((ln+160))
    echo "=== $fn around line $ln ==="
    sed -n "${start},${end}p" "$query_base"
  fi
done

echo "---- Inspect wu_create_checkout_form implementation ----"
fnfile="inc/functions/checkout-form.php"
start=$(rg -n --type=php 'function wu_create_checkout_form\\b' "$fnfile" | head -n1 | cut -d: -f1)
echo "wu_create_checkout_form at line: $start"
sed -n "$((start-30)),$((start+60))p" "$fnfile"
rg -n --type=php 'new Checkout_Form|->save\\(' "$fnfile" -C 2 | head -n 50

echo "---- Exact line number of '( is_wp_error(' in Checkout_Step_Fields_Test.php ----"
python3 - <<'PY'
from pathlib import Path
p = Path("tests/unit/Checkout_Step_Fields_Test.php")
lines = p.read_text(encoding="utf-8").splitlines()
needle = "( is_wp_error("
for i, line in enumerate(lines, start=1):
    if needle in line:
        print(f"line {i}: {line.strip()}")
PY

echo "---- Print lines around that location for context ----"
python3 - <<'PY'
from pathlib import Path
p = Path("tests/unit/Checkout_Step_Fields_Test.php")
lines = p.read_text(encoding="utf-8").splitlines()
needle = "( is_wp_error("
for i, line in enumerate(lines, start=1):
    if needle in line:
        start=max(1,i-6); end=min(len(lines), i+6)
        for j in range(start,end+1):
            print(f"{j:4d}: {lines[j-1]}")
PY

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 7083


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Locate add_item/update_item implementations in inc/database/engine ----"
rg -n --type=php "function (add_item|update_item)\\b" inc/database/engine

echo "---- Locate add_item/update_item implementations in inc/database (any engine/query) ----"
rg -n --type=php "function (add_item|update_item)\\b" inc/database

echo "---- Does any inc/database engine/query base reference \$wpdb? ----"
rg -n --type=php "\\$wpdb->" inc/database || true
rg -n --type=php "get_db\\(" inc/database/engine || true

echo "---- Exact whitespace pattern '( is_wp_error(' in Checkout_Step_Fields_Test.php ----"
rg -n " \\( is_wp_error\\(" tests/unit/Checkout_Step_Fields_Test.php || true
rg -n "\\( is_wp_error\\(" tests/unit/Checkout_Step_Fields_Test.php || true
python3 - <<'PY'
from pathlib import Path
p = Path("tests/unit/Checkout_Step_Fields_Test.php")
lines = p.read_text(encoding="utf-8").splitlines()
for i,l in enumerate(lines, start=1):
    if "( is_wp_error" in l or " ( is_wp_error" in l:
        print(f"line {i}: {l.strip()}")
        for j in range(max(1,i-2), min(len(lines), i+2)+1):
            print(f"{j:3d}: {lines[j-1].rstrip()}")
PY

echo "---- Other tests/unit files calling wu_create_checkout_form / wu_create_* ----"
rg -n --type=php "\\bwu_create_checkout_form\\b" tests/unit
rg -n --type=php "\\bwu_create_[a-z0-9_]+\\b" tests/unit | head -n 50

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 158


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- tests/unit/* extending plain PHPUnit TestCase ----"
rg -n --type=php 'extends\s+TestCase' tests/unit

echo "---- For those files, check if they call wu_create_* (DB write risk) ----"
for f in $(rg -l --type=php 'extends\s+TestCase' tests/unit); do
  if rg -n --type=php '\bwu_create_' "$f" >/dev/null; then
    echo "FOUND wu_create_* in $f"
    rg -n --type=php '\bwu_create_' "$f"
  fi
done

echo "---- Locate whitespace lint: '( is_wp_error(' or similar ----"
rg -n '\(\s+is_wp_error' tests/unit/Checkout_Step_Fields_Test.php || true
python3 - <<'PY'
from pathlib import Path
p = Path("tests/unit/Checkout_Step_Fields_Test.php")
lines = p.read_text(encoding="utf-8").splitlines()
for i,line in enumerate(lines, start=1):
    if "( is_wp_error" in line:
        print(f"line {i}: {line.strip()}")
PY

echo "---- Confirm phpunit bootstrap loads WP test environment ----"
cat -n phpunit.xml.dist | sed -n '1,40p'
cat -n tests/bootstrap.php | sed -n '1,110p'

Repository: Ultimate-Multisite/ultimate-multisite

Length of output: 5690


Use WP_UnitTestCase (or clean up) to keep DB isolation for Checkout_Step_Fields_Test

tests/unit/Checkout_Step_Fields_Test.php extends PHPUnit\Framework\TestCase, but it seeds real data by calling wu_create_checkout_form() (which persists via Checkout_Form->save() / Base_Model::save()). Without WP_UnitTestCase’s per-test DB isolation (or an explicit tearDown() deleting the created form), this can leak step-fields-guard-form-* rows into the shared test DB across runs.

Bootstrap isn’t the issue here: phpunit.xml.dist uses tests/bootstrap.php, which loads the WP test environment and manually loads the plugin on muplugins_loaded, so wu_create_checkout_form() is available.

Minor: lint warning at tests/unit/Checkout_Step_Fields_Test.php line 72 has spaces in ( is_wp_error($form) ... )—remove the extra spaces.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/Checkout_Step_Fields_Test.php` at line 11, The test class
Checkout_Step_Fields_Test currently extends PHPUnit\Framework\TestCase and
creates persistent data via wu_create_checkout_form() (which triggers
Checkout_Form->save() / Base_Model::save()), so switch the test class to extend
WP_UnitTestCase (or add a tearDown() that deletes any created forms) to get
per-test DB isolation and avoid leaking step-fields-guard-form-* rows; update
the class declaration for Checkout_Step_Fields_Test to extend WP_UnitTestCase
(or implement teardown logic that deletes records created by
wu_create_checkout_form()), and fix the lint warning by removing the extra
spaces around the is_wp_error() call at the assertion currently written like "(
is_wp_error($form) ... )".

@@ -0,0 +1,401 @@
<?php
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add the required ABSPATH guard at file start.

This test file is missing the mandatory early-exit guard right after <?php (Line 1).

Proposed fix
 <?php
+defined('ABSPATH') || exit;
 /**
  * Regression tests for two production incidents in the checkout flow:

As per coding guidelines, "Every PHP file must start with defined('ABSPATH') || exit;".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<?php
<?php
defined('ABSPATH') || exit;
/**
* Regression tests for two production incidents in the checkout flow:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/WP_Ultimo/Managers/Regression_Pending_Site_And_Subdomain_Test.php` at
line 1, This test file is missing the required early-exit ABSPATH guard at the
top; open the test file and immediately after the opening PHP tag add the
standard WordPress guard statement defined('ABSPATH') || exit; so the file exits
early when ABSPATH is not defined (ensure it's the very first executable line),
then run tests to confirm no parsing errors.

@github-actions
Copy link
Copy Markdown

🔨 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

@github-actions
Copy link
Copy Markdown

🔨 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

@github-actions
Copy link
Copy Markdown

🔨 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 8834cfd into main May 29, 2026
8 of 11 checks passed
@superdav42 superdav42 added the review-feedback-scanned Merged PR already scanned for quality feedback label May 30, 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.

2 participants