feat(cart): enhance item update functionality to support variant changes and stock management; update related request validation and resource formatting; add tests for variant handling in cart

This commit is contained in:
2026-08-10 12:08:09 -03:00
parent 2693df2cbf
commit c6351d706f
8 changed files with 225 additions and 15 deletions

View File

@@ -256,6 +256,101 @@ class CartControllerTest extends TestCase
]);
}
public function test_it_changes_an_item_variant_and_moves_the_stock_reservation(): void
{
$tenant = $this->createTenant('acme');
[$item, $firstVariant] = $this->createVariantItem($tenant, 10, '15.00');
$secondInventory = Inventory::query()->create(['real_stock' => 8]);
$secondVariant = $item->variants()->create([
'inventory_id' => $secondInventory->id,
'precio' => '20.00',
]);
$createResponse = $this->postJson('/api/tenants/acme/cart/items', [
'catalog_item_id' => $item->id,
'variant_id' => $firstVariant->id,
'cantidad' => 2,
]);
$guestToken = $createResponse->getCookie('guest_token', false)?->getValue();
$cartItemId = $createResponse->json('data.items.0.id');
$this->call(
'PATCH',
"/api/tenants/acme/cart/items/{$cartItemId}",
[],
['guest_token' => $guestToken],
[],
['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'],
json_encode(['cantidad' => 2, 'variant_id' => $secondVariant->id]),
)
->assertOk()
->assertJsonPath('data.items.0.variant_id', $secondVariant->id)
->assertJsonPath('data.items.0.precio_unitario', '20.00')
->assertJsonCount(2, 'data.items.0.product.variants');
$this->assertDatabaseHas('inventories', [
'id' => $firstVariant->inventory_id,
'reserved_stock' => 0,
]);
$this->assertDatabaseHas('inventories', [
'id' => $secondInventory->id,
'reserved_stock' => 2,
]);
}
public function test_changing_to_a_variant_already_in_the_cart_merges_both_rows(): void
{
$tenant = $this->createTenant('acme');
[$item, $firstVariant] = $this->createVariantItem($tenant, 10, '15.00');
$secondInventory = Inventory::query()->create(['real_stock' => 10]);
$secondVariant = $item->variants()->create(['inventory_id' => $secondInventory->id]);
$firstResponse = $this->postJson('/api/tenants/acme/cart/items', [
'catalog_item_id' => $item->id,
'variant_id' => $firstVariant->id,
'cantidad' => 2,
]);
$guestToken = $firstResponse->getCookie('guest_token', false)?->getValue();
$firstCartItemId = $firstResponse->json('data.items.0.id');
$this->call(
'POST',
'/api/tenants/acme/cart/items',
[],
['guest_token' => $guestToken],
[],
['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'],
json_encode([
'catalog_item_id' => $item->id,
'variant_id' => $secondVariant->id,
'cantidad' => 3,
]),
)->assertOk();
$this->call(
'PATCH',
"/api/tenants/acme/cart/items/{$firstCartItemId}",
[],
['guest_token' => $guestToken],
[],
['HTTP_Accept' => 'application/json', 'CONTENT_TYPE' => 'application/json'],
json_encode(['cantidad' => 2, 'variant_id' => $secondVariant->id]),
)
->assertOk()
->assertJsonCount(1, 'data.items')
->assertJsonPath('data.items.0.variant_id', $secondVariant->id)
->assertJsonPath('data.items.0.cantidad', 5);
$this->assertDatabaseCount('carrito_items', 1);
$this->assertDatabaseHas('inventories', [
'id' => $firstVariant->inventory_id,
'reserved_stock' => 0,
]);
$this->assertDatabaseHas('inventories', [
'id' => $secondInventory->id,
'reserved_stock' => 5,
]);
}
public function test_it_requires_a_variant_when_the_item_has_variant_inventory(): void
{
$tenant = $this->createTenant('acme');