Skip to content

Commit 0c140bd

Browse files
authored
Fix cart retrieval to prefer unmerged carts (and clarify active scope grouping) (lunarphp#2399)
1 parent a2dce80 commit 0c140bd

3 files changed

Lines changed: 87 additions & 3 deletions

File tree

packages/core/src/Managers/CartSessionManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ protected function fetchOrCreate(bool $create = false, bool $estimateShipping =
136136
);
137137

138138
if (! $cartId && $user = $this->authManager->user()) {
139-
$cartId = $user->carts()->active()->first()?->id;
139+
$cartId = $user->carts()->unmerged()->active()->latest('id')->value('id');
140140
}
141141

142142
if (! $cartId) {

packages/core/src/Models/Cart.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,12 @@ public function orders(): HasMany
256256

257257
public function scopeActive(Builder $query): Builder
258258
{
259-
return $query->whereDoesntHave('orders')->orWhereHas('orders', function ($query) {
260-
return $query->whereNull('placed_at');
259+
return $query->where(function ($q) {
260+
$q
261+
->whereDoesntHave('orders')
262+
->orWhereHas('orders', function ($sub) {
263+
$sub->whereNull('placed_at');
264+
});
261265
});
262266
}
263267

tests/core/Unit/Models/CartTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,3 +1163,83 @@
11631163
)->toBe($newOrder->id);
11641164

11651165
});
1166+
1167+
test('active scope correctly filters unmerged carts and isolates users', function () {
1168+
setAuthUserConfig();
1169+
1170+
$currency = Currency::factory()->create();
1171+
$channel = Channel::factory()->create();
1172+
1173+
$userA = StubUser::factory()->create();
1174+
$userB = StubUser::factory()->create();
1175+
1176+
$otherUsersCart = Cart::factory()->create([
1177+
'user_id' => $userB->id,
1178+
'currency_id' => $currency->id,
1179+
'channel_id' => $channel->id,
1180+
]);
1181+
1182+
$expectedCart = Cart::factory()->create([
1183+
'user_id' => $userA->id,
1184+
'currency_id' => $currency->id,
1185+
'channel_id' => $channel->id,
1186+
'merged_id' => null,
1187+
]);
1188+
1189+
$mergedCart = Cart::factory()->create([
1190+
'user_id' => $userA->id,
1191+
'currency_id' => $currency->id,
1192+
'channel_id' => $channel->id,
1193+
'merged_id' => $expectedCart->id,
1194+
]);
1195+
1196+
$cartId = $userA->carts()
1197+
->unmerged()
1198+
->active()
1199+
->latest('id')
1200+
->value('id');
1201+
1202+
expect($cartId)->toBe($expectedCart->id)
1203+
->and($cartId)->not->toBe($otherUsersCart->id)
1204+
->and($cartId)->not->toBe($mergedCart->id);
1205+
});
1206+
1207+
test('cart session manager prefers the latest unmerged cart for an authenticated user', function () {
1208+
setAuthUserConfig();
1209+
1210+
$currency = Currency::factory()->create();
1211+
$channel = Channel::factory()->create();
1212+
$user = StubUser::factory()->create();
1213+
1214+
$older = Cart::factory()->create([
1215+
'user_id' => $user->id,
1216+
'merged_id' => null,
1217+
'currency_id' => $currency->id,
1218+
'channel_id' => $channel->id,
1219+
]);
1220+
1221+
$expectedCart = Cart::factory()->create([
1222+
'user_id' => $user->id,
1223+
'merged_id' => null,
1224+
'currency_id' => $currency->id,
1225+
'channel_id' => $channel->id,
1226+
]);
1227+
1228+
$mergedCart = Cart::factory()->create([
1229+
'user_id' => $user->id,
1230+
'merged_id' => $expectedCart->id,
1231+
'currency_id' => $currency->id,
1232+
'channel_id' => $channel->id,
1233+
]);
1234+
1235+
$this->actingAs($user);
1236+
1237+
$manager = app(\Lunar\Managers\CartSessionManager::class);
1238+
$foundCart = $manager->current();
1239+
1240+
expect($foundCart)->not->toBeNull()
1241+
->and($foundCart->id)->toBe($expectedCart->id)
1242+
->and($foundCart->id)->not->toBe($older->id)
1243+
->and($foundCart->id)->not->toBe($mergedCart->id)
1244+
->and($foundCart->merged_id)->toBeNull();
1245+
});

0 commit comments

Comments
 (0)