Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughOrder line cleanup now computes signatures (purchasableId + meta + qty) for cart and order lines and deletes order lines whose signature is not present in the cart. A private signature helper was added and tests were updated to assert persisted DB state, including a new case for identical purchasable_ids with differing meta/qty. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (6)
tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php (3)
95-102: Scope DB assertions to the current order to avoid false positives.Include order_id in the where clauses for precision.
- assertDatabaseHas((new OrderLine)->getTable(), [ - 'purchasable_id' => $purchasable->id, - ]); + assertDatabaseHas((new OrderLine)->getTable(), [ + 'order_id' => $order->id, + 'purchasable_id' => $purchasable->id, + ]); - assertDatabaseMissing((new OrderLine)->getTable(), [ - 'purchasable_id' => $purchasableB->id, - ]); + assertDatabaseMissing((new OrderLine)->getTable(), [ + 'order_id' => $order->id, + 'purchasable_id' => $purchasableB->id, + ]);
106-106: Clarify test title.Make the intent explicit: differing quantity or meta.
- test('will remove lines with same purchasable ids when different', function () { + test('removes lines with same purchasable_id when quantity or meta differ', function () {
204-214: Prefer JSON path assertions over raw JSON string equality.Asserting meta via a JSON path is more robust across drivers than string-matching json_encode output.
Option A (simple): use JSON path columns if supported in your test DB driver.
- assertDatabaseHas((new OrderLine)->getTable(), [ - 'purchasable_id' => $purchasableB->id, - 'quantity' => 5, - 'meta' => json_encode(['foo' => 'bar']), - ]); + assertDatabaseHas((new OrderLine)->getTable(), [ + 'purchasable_id' => $purchasableB->id, + 'quantity' => 5, + 'meta->foo' => 'bar', + ]); - assertDatabaseMissing((new OrderLine)->getTable(), [ - 'purchasable_id' => $purchasableB->id, - 'quantity' => 15, - 'meta' => json_encode(['bar' => 'baz']), - ]); + assertDatabaseMissing((new OrderLine)->getTable(), [ + 'purchasable_id' => $purchasableB->id, + 'quantity' => 15, + 'meta->bar' => 'baz', + ]);If SQLite JSON1 or your driver doesn’t support meta->key in where, keep your current approach or switch to a query using whereJsonContains for those checks.
packages/core/src/Pipelines/Order/Creation/CleanUpOrderLines.php (3)
20-23: Build a set for O(1) membership checks.Converting the signatures array into a hash set avoids repeated linear in_array scans.
- // Build a set of "signatures" that uniquely identify each cart line - $cartSignatures = $cart->lines->map(function ($line) { - return $this->signature($line->purchasable_id, (array) $line->meta, $line->quantity); - })->toArray(); + // Build a set of "signatures" that uniquely identify each cart line + $cartSignatures = $cart->lines->map(function ($line) { + return $this->signature($line->purchasable_id, (array) $line->meta, $line->quantity); + })->toArray(); + $cartSignatureSet = array_flip($cartSignatures);
25-35: Use the set for membership checks (avoid in_array).Switch to isset on the flipped set for faster lookups.
- $order->productLines->each(function ($orderLine) use ($cartSignatures) { + $order->productLines->each(function ($orderLine) use ($cartSignatureSet) { $sig = $this->signature( $orderLine->purchasable_id, (array) $orderLine->meta, $orderLine->quantity, ); - if (! in_array($sig, $cartSignatures, true)) { + if (! isset($cartSignatureSet[$sig])) { $orderLine->delete(); } });
40-47: Normalize meta recursively for stable signatures.Sorting only top-level keys can produce mismatches if meta has nested structures. Normalize recursively before encoding.
- private function signature(string $purchasableId, array $meta, int $qty): string + private function signature(string $purchasableId, array $meta, int $qty): string { - return md5(json_encode([ - 'id' => $purchasableId, - 'meta' => collect($meta)->sortKeys()->toArray(), - 'qty' => $qty, - ])); + return md5(json_encode([ + 'id' => (string) $purchasableId, + 'meta' => $this->normalizeMeta($meta), + 'qty' => (int) $qty, + ], JSON_UNESCAPED_SLASHES)); }Add this helper within the class:
private function normalizeMeta(mixed $value): mixed { if (is_array($value)) { // Normalize associative arrays by key; preserve order for indexed arrays $isAssoc = array_keys($value) !== range(0, count($value) - 1); if ($isAssoc) { ksort($value); } foreach ($value as $k => $v) { $value[$k] = $this->normalizeMeta($v); } return $value; } if ($value instanceof \ArrayObject) { return $this->normalizeMeta((array) $value); } return $value; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/core/src/Pipelines/Order/Creation/CleanUpOrderLines.php(2 hunks)tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/core/src/Pipelines/Order/Creation/CleanUpOrderLines.php (2)
packages/core/src/Models/Order.php (3)
cart(93-96)lines(98-101)productLines(118-121)packages/core/src/Models/Cart.php (1)
lines(212-215)
tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php (3)
packages/core/src/Models/OrderLine.php (1)
OrderLine(39-99)packages/core/src/Base/Traits/HasModelExtending.php (1)
getTable(66-71)packages/core/src/Pipelines/Order/Creation/CleanUpOrderLines.php (2)
CleanUpOrderLines(10-48)handle(15-38)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: core - PHP 8.4 - L12.* ↑ E
- GitHub Check: search - PHP 8.4 - L12.* ↑ E
- GitHub Check: admin - PHP 8.4 - L12.* ↑ E
- GitHub Check: stripe - PHP 8.4 - L11.* ↑
- GitHub Check: stripe - PHP 8.4 - L12.* ↑ E
- GitHub Check: admin - PHP 8.4 - L11.* ↑
- GitHub Check: core - PHP 8.4 - L11.* ↑ E
- GitHub Check: admin - PHP 8.4 - L11.* ↑ E
- GitHub Check: core - PHP 8.4 - L11.* ↑
- GitHub Check: search - PHP 8.3 - L12.* ↑
- GitHub Check: shipping - PHP 8.4 - L11.* ↑
- GitHub Check: admin - PHP 8.3 - L12.* ↑
- GitHub Check: admin - PHP 8.3 - L12.* ↑ E
- GitHub Check: admin - PHP 8.3 - L11.* ↑
- GitHub Check: core - PHP 8.3 - L11.* ↑
- GitHub Check: core - PHP 8.3 - L12.* ↑ E
- GitHub Check: core - PHP 8.3 - L12.* ↑
- GitHub Check: admin - PHP 8.3 - L11.* ↑ E
- GitHub Check: core - PHP 8.3 - L11.* ↑ E
- GitHub Check: fix-code-style
🔇 Additional comments (1)
tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php (1)
16-16: Good switch to DB assertions.Importing Pest’s assertDatabaseHas/assertDatabaseMissing is appropriate for validating persisted state.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php (1)
207-212: Prefer JSON path assertions over raw JSON encoding for metaUsing meta->key paths is more driver-agnostic (MySQL/Postgres/SQLite) and resilient to JSON normalization differences than comparing serialized JSON strings.
Apply this diff:
- assertDatabaseHas((new OrderLine)->getTable(), [ - 'order_id' => $order->id, - 'purchasable_id' => $purchasableB->id, - 'quantity' => 5, - 'meta' => json_encode(['foo' => 'bar']), - ]); + assertDatabaseHas((new OrderLine)->getTable(), [ + 'order_id' => $order->id, + 'purchasable_id' => $purchasableB->id, + 'quantity' => 5, + 'meta->foo' => 'bar', + ]); - assertDatabaseMissing((new OrderLine)->getTable(), [ - 'order_id' => $order->id, - 'purchasable_id' => $purchasableB->id, - 'quantity' => 15, - 'meta' => json_encode(['bar' => 'baz']), - ]); + assertDatabaseMissing((new OrderLine)->getTable(), [ + 'order_id' => $order->id, + 'purchasable_id' => $purchasableB->id, + 'quantity' => 15, + 'meta->bar' => 'baz', + ]);Also applies to: 214-219
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php (6)
packages/core/src/Models/OrderLine.php (1)
OrderLine(39-99)packages/core/src/Base/Traits/HasModelExtending.php (1)
getTable(66-71)packages/core/src/Models/Cart.php (1)
Cart(62-620)packages/core/src/DataTypes/ShippingOption.php (1)
ShippingOption(9-148)packages/core/src/Models/CartAddress.php (1)
CartAddress(42-140)packages/core/src/Pipelines/Order/Creation/CleanUpOrderLines.php (2)
CleanUpOrderLines(9-47)handle(14-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: core - PHP 8.4 - L12.* ↑
- GitHub Check: core - PHP 8.4 - L12.* ↑ E
- GitHub Check: core - PHP 8.4 - L11.* ↑ E
🔇 Additional comments (2)
tests/core/Unit/Pipelines/Order/Creation/CleanUpOrderLinesTest.php (2)
17-19: LGTM: Using Pest DB assertions improves test robustnessImporting Pest’s assertDatabaseHas/assertDatabaseMissing is appropriate and aligns with the updated persistence-focused assertions.
97-106: LGTM: Correctly asserts persisted delta after cleanupThese DB assertions accurately verify that only the expected product line remains and the stray line is removed.
| $purchasableIds = $cart->lines->pluck('purchasable_id'); | ||
| // Build a set of "signatures" that uniquely identify each cart line | ||
| $cartSignatures = $cart->lines->map(function ($line) { | ||
| return $this->signature($line->purchasable_id, (array) $line->meta, $line->quantity); |
There was a problem hiding this comment.
should include purchasable_type in signature too
There was a problem hiding this comment.
@alecritson can you do a PR to add that in? I think it makes sense.
This PR adds additional logic to the
CleanUpOrderLinespipeline to catch any duplicate purchasable lines which may have slipped through the net due to differing quantities/meta values.Summary by CodeRabbit
Bug Fixes
Tests