fix(checkout): prevent epoch membership expiration - #1692
Conversation
📝 WalkthroughWalkthroughCheckout now assigns correct expiration dates to recurring memberships and removes only sufficiently old draft or pending payments. Tests cover recent-payment preservation, recurring expiration dates, and cancellation of expired pending payments and memberships. ChangesCheckout lifecycle handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
🔨 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! Login credentials: |
🔨 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! Login credentials: |
🔨 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! Login credentials: |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/WP_Ultimo/Checkout/Checkout_Test.php (1)
4130-4150: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winAssert against the persisted membership.
wu_create_membership()saves the membership but returns the same in-memory object. These assertions do not verify the value after the persistence read path. Retrieve the membership withwu_get_membership()before checking its expiration, event payload, and formatted output.Proposed test update
$this->assertInstanceOf(\WP_Ultimo\Models\Membership::class, $result); - $this->assertSame($expected_expiration, $result->get_date_expiration()); - $this->assertStringStartsNotWith('1970-', $result->get_date_expiration()); + $persisted_membership = wu_get_membership($result->get_id()); + $this->assertInstanceOf(\WP_Ultimo\Models\Membership::class, $persisted_membership); + $this->assertSame($expected_expiration, $persisted_membership->get_date_expiration()); + $this->assertStringStartsNotWith('1970-', $persisted_membership->get_date_expiration()); - $event_payload = wu_generate_event_payload('membership', $result); + $event_payload = wu_generate_event_payload('membership', $persisted_membership); $this->assertSame($expected_expiration, $event_payload['membership_date_expiration']); $this->assertSame( date_i18n(get_option('date_format'), wu_date($expected_expiration)->format('U')), - $result->get_formatted_date('date_expiration') + $persisted_membership->get_formatted_date('date_expiration') ); - $result->delete(); + $persisted_membership->delete();🤖 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/Checkout/Checkout_Test.php` around lines 4130 - 4150, After the successful wu_create_membership() invocation, retrieve the persisted membership through wu_get_membership() using the created membership’s identifier, then run the expiration, event payload, and formatted-date assertions against that reloaded object instead of the original $result. Keep the existing WP_Error skip and cleanup behavior unchanged.
🤖 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.
Nitpick comments:
In `@tests/WP_Ultimo/Checkout/Checkout_Test.php`:
- Around line 4130-4150: After the successful wu_create_membership() invocation,
retrieve the persisted membership through wu_get_membership() using the created
membership’s identifier, then run the expiration, event payload, and
formatted-date assertions against that reloaded object instead of the original
$result. Keep the existing WP_Error skip and cleanup behavior unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0ab4cede-993d-4b69-9b11-fa914b2d7e02
📒 Files selected for processing (2)
inc/checkout/class-checkout.phptests/WP_Ultimo/Checkout/Checkout_Test.php
Summary
Root cause
Recurring carts without trials report a billing start timestamp of
0. Formatting that value directly persisted a January 1970 membership expiration, which then propagated to email event payloads and customer views.Verification
vendor/bin/phpunit --no-coverage --filter 'WP_Ultimo\\Checkout\\Checkout_Test'— 204 tests, 349 assertions, 1 skipvendor/bin/phpcs inc/checkout/class-checkout.php tests/WP_Ultimo/Checkout/Checkout_Test.phpvendor/bin/phpstan analyse inc/checkout/class-checkout.php tests/WP_Ultimo/Checkout/Checkout_Test.php --no-progressgit diff --checkaidevops.sh v3.32.219 plugin for OpenCode v1.18.9 with gpt-5.6-sol spent 2h 16m and 440,196 tokens on this with the user in an interactive session.
Summary by CodeRabbit
Bug Fixes
Tests