test(catalog): cover composed availability restrictions

This commit is contained in:
2026-08-24 14:33:01 -03:00
parent 2fd6851b40
commit a73b628bb4
6 changed files with 80 additions and 49 deletions

View File

@@ -246,7 +246,7 @@ class CartControllerTest extends TestCase
->assertJsonPath('code', 'purchase.limit_exceeded')
->assertJsonPath('catalog_item_id', $item->id)
->assertJsonPath('catalog_item_name', $item->nombre)
->assertJsonPath('maximum_addable_quantity', 1)
->assertJsonPath('availability.maximum_quantity', 1)
->assertJsonPath(
'message',
"Podés agregar hasta 1 unidad más de “{$item->nombre}”.",

View File

@@ -267,7 +267,7 @@ class BundleCatalogItemTest extends TestCase
$this->getJson("/api/tenants/{$this->tenant->codigo}/catalog-items/{$bundleId}")
->assertOk()
->assertJsonPath('data.type', CatalogItemType::Bundle->value)
->assertJsonPath('data.maximum_addable_quantity', 4)
->assertJsonPath('data.availability.maximum_quantity', 4)
->assertJsonMissingPath('data.stock_tecnico')
->assertJsonCount(1, 'data.components')
->assertJsonPath('data.components.0.catalog_item_id', $component->id)

View File

@@ -72,18 +72,26 @@ class CatalogControllerTest extends TestCase
->assertJsonPath('0.items.0.nombre', 'Variants')
->assertJsonPath('0.items.0.descripcion', 'Variants description')
->assertJsonPath('0.items.0.precio', '100.00')
->assertJsonPath('0.items.0.maximum_addable_quantity', 7)
->assertJsonPath('0.items.0.availability.maximum_quantity', 7)
->assertJsonCount(3, '0.items.0.variants')
->assertJsonPath('0.items.0.variants.0.maximum_addable_quantity', 4)
->assertJsonPath('0.items.0.variants.1.maximum_addable_quantity', 3)
->assertJsonPath('0.items.0.variants.0.availability.maximum_quantity', 4)
->assertJsonPath('0.items.0.variants.1.availability.maximum_quantity', 3)
->assertJsonPath('0.items.0.variants.2.id', $unavailableVariant->id)
->assertJsonPath('0.items.0.variants.2.maximum_addable_quantity', 0)
->assertJsonPath('0.items.0.variants.2.availability.maximum_quantity', 0)
->assertJsonPath(
'0.items.0.variants.2.unavailable_message',
'0.items.0.variants.2.availability.restrictions.0.message',
'Este producto no tiene stock disponible.',
)
->assertJsonPath(
'0.items.0.variants.2.availability.capabilities.select_variant',
false,
)
->assertJsonPath(
'0.items.0.variants.2.availability.capabilities.add_to_cart',
false,
)
->assertJsonPath('1.title', 'Row')
->assertJsonPath('1.items.data.0.maximum_addable_quantity', 8)
->assertJsonPath('1.items.data.0.availability.maximum_quantity', 8)
->assertJsonMissingPath('1.items.data.0.stock_tecnico')
->assertJsonCount(0, '1.items.data.0.variants');
}
@@ -119,16 +127,20 @@ class CatalogControllerTest extends TestCase
$this->actingAs($user, 'sanctum')
->getJson("/api/tenants/{$tenant->codigo}/catalog")
->assertOk()
->assertJsonPath('0.items.0.variants.0.maximum_addable_quantity', 0)
->assertJsonPath('0.items.0.variants.1.maximum_addable_quantity', 0)
->assertJsonPath('0.items.0.variants.0.availability.maximum_quantity', 0)
->assertJsonPath('0.items.0.variants.1.availability.maximum_quantity', 0)
->assertJsonPath(
'0.items.0.variants.0.unavailable_message',
'0.items.0.variants.0.availability.restrictions.0.message',
'Alcanzaste el cupo máximo permitido para este producto.',
)
->assertJsonPath(
'0.items.0.variants.1.unavailable_message',
'0.items.0.variants.1.availability.restrictions.0.message',
'Alcanzaste el cupo máximo permitido para este producto.',
)
->assertJsonPath(
'0.items.0.variants.1.availability.capabilities.buy_now',
false,
)
->assertJsonMissingPath('0.items.0.variants.0.stock_tecnico')
->assertJsonMissingPath('0.items.0.variants.1.stock_tecnico');
}
@@ -163,13 +175,13 @@ class CatalogControllerTest extends TestCase
->assertOk()
->assertJsonCount(2, '0.items')
->assertJsonPath('0.items.0.nombre', 'Unavailable')
->assertJsonPath('0.items.0.maximum_addable_quantity', 0)
->assertJsonPath('0.items.0.availability.maximum_quantity', 0)
->assertJsonPath(
'0.items.0.unavailable_message',
'0.items.0.availability.restrictions.0.message',
'Este producto no tiene stock disponible.',
)
->assertJsonPath('0.items.1.nombre', 'Available')
->assertJsonPath('0.items.1.unavailable_message', null);
->assertJsonCount(0, '0.items.1.availability.restrictions');
}
public function test_column_with_image_uses_item_image_then_variant_image_then_null(): void

View File

@@ -40,7 +40,7 @@ class CatalogItemDetailControllerTest extends TestCase
$response
->assertOk()
->assertJsonPath('data.maximum_addable_quantity', 7)
->assertJsonPath('data.availability.maximum_quantity', 7)
->assertJsonMissingPath('data.stock_tecnico')
->assertJsonCount(0, 'data.variants')
->assertJsonCount(1, 'data.images');
@@ -71,14 +71,14 @@ class CatalogItemDetailControllerTest extends TestCase
->assertOk()
->assertJsonCount(2, 'data.variants')
->assertJsonPath('data.variants.0.id', $firstVariant->id)
->assertJsonPath('data.variants.0.maximum_addable_quantity', 0)
->assertJsonPath('data.variants.0.availability.maximum_quantity', 0)
->assertJsonPath(
'data.variants.0.unavailable_message',
'data.variants.0.availability.restrictions.0.message',
'Este producto no tiene stock disponible.',
)
->assertJsonPath('data.variants.1.id', $secondVariant->id)
->assertJsonPath('data.selected_variant.id', $secondVariant->id)
->assertJsonPath('data.selected_variant.maximum_addable_quantity', 6)
->assertJsonPath('data.selected_variant.availability.maximum_quantity', 6)
->assertJsonMissingPath('data.selected_variant.stock_tecnico')
->assertJsonCount(1, 'data.selected_variant.images');
$response
@@ -133,11 +133,11 @@ class CatalogItemDetailControllerTest extends TestCase
$response
->assertOk()
->assertJsonPath('data.variants.0.id', $firstVariant->id)
->assertJsonPath('data.variants.0.maximum_addable_quantity', 4)
->assertJsonPath('data.variants.0.availability.maximum_quantity', 4)
->assertJsonPath('data.variants.0.values.size.value', 'S')
->assertJsonPath('data.variants.0.values.size.label', 'Small')
->assertJsonPath('data.variants.1.id', $secondVariant->id)
->assertJsonPath('data.variants.1.maximum_addable_quantity', 7)
->assertJsonPath('data.variants.1.availability.maximum_quantity', 7)
->assertJsonPath('data.variants.1.values.size.value', 'M')
->assertJsonPath('data.variants.1.values.size.label', 'Medium')
->assertJsonPath('data.attributes.0.codigo', 'size')
@@ -145,7 +145,7 @@ class CatalogItemDetailControllerTest extends TestCase
->assertJsonPath('data.attributes.0.options.1.value', 'M')
->assertJsonCount(2, 'data.attributes.0.options')
->assertJsonPath('data.selected_variant.id', $secondVariant->id)
->assertJsonPath('data.selected_variant.maximum_addable_quantity', 7)
->assertJsonPath('data.selected_variant.availability.maximum_quantity', 7)
->assertJsonPath('data.selected_variant.values.size.value', 'M')
->assertJsonPath('data.selected_variant.values.size.label', 'Medium')
->assertJsonCount(1, 'data.selected_variant.images');
@@ -185,9 +185,9 @@ class CatalogItemDetailControllerTest extends TestCase
$this->getJson("/api/tenants/{$tenant->codigo}/catalog-items/{$item->id}")
->assertOk()
->assertJsonPath('data.selected_variant.id', $variant->id)
->assertJsonPath('data.selected_variant.maximum_addable_quantity', null)
->assertJsonPath('data.selected_variant.availability.maximum_quantity', null)
->assertJsonMissingPath('data.stock_tecnico')
->assertJsonPath('data.variants.0.maximum_addable_quantity', null)
->assertJsonPath('data.variants.0.availability.maximum_quantity', null)
->assertJsonMissingPath('data.selected_variant.stock_tecnico')
->assertJsonMissingPath('data.variants.0.stock_tecnico');
}

View File

@@ -394,7 +394,7 @@ class StorePurchaseTest extends TestCase
->assertJsonPath('code', 'purchase.limit_exceeded')
->assertJsonPath('catalog_item_id', $variant->catalog_item_id)
->assertJsonPath('catalog_item_name', $variant->catalogItem->nombre)
->assertJsonPath('maximum_addable_quantity', 1);
->assertJsonPath('availability.maximum_quantity', 1);
$this->actingAs($otherUser, 'sanctum')
->postJson('/api/tenants/sonder/compras/start-checkout', [

View File

@@ -3,41 +3,60 @@
namespace Tests\Unit\Catalog;
use App\Domains\Catalog\Services\CatalogItemAllowanceService;
use ReflectionClass;
use App\Domains\Purchase\Services\UserPurchaseLimitService;
use Mockery;
use Tests\TestCase;
class CatalogItemAllowanceServiceTest extends TestCase
{
private CatalogItemAllowanceService $service;
protected function setUp(): void
public function test_it_composes_stock_and_quota_into_restrictions_and_capabilities(): void
{
parent::setUp();
$this->service = (new ReflectionClass(CatalogItemAllowanceService::class))
->newInstanceWithoutConstructor();
}
public function test_it_returns_the_user_quota_message_with_priority_over_stock(): void
{
$this->assertSame(
'Alcanzaste el cupo máximo permitido para este producto.',
$this->service->unavailableMessage(0, 0),
$service = new CatalogItemAllowanceService(
Mockery::mock(UserPurchaseLimitService::class),
);
}
public function test_it_returns_the_out_of_stock_message(): void
{
$availability = $service->availability(0, 0, 'variant');
$this->assertSame(0, $availability['maximum_quantity']);
$this->assertSame(
'Este producto no tiene stock disponible.',
$this->service->unavailableMessage(0, null),
['user_quota_reached', 'out_of_stock'],
array_column($availability['restrictions'], 'code'),
);
$this->assertSame(['variant', 'variant'], array_column($availability['restrictions'], 'scope'));
$this->assertSame([
'select_variant' => false,
'change_quantity' => false,
'add_to_cart' => false,
'buy_now' => false,
], $availability['capabilities']);
}
public function test_it_returns_no_message_when_the_item_is_available(): void
public function test_it_keeps_all_capabilities_when_no_restriction_applies(): void
{
$this->assertNull($this->service->unavailableMessage(1, null));
$this->assertNull($this->service->unavailableMessage(null, 1));
$this->assertNull($this->service->unavailableMessage(null, null));
$service = new CatalogItemAllowanceService(
Mockery::mock(UserPurchaseLimitService::class),
);
$availability = $service->availability(5, 3);
$this->assertSame(3, $availability['maximum_quantity']);
$this->assertSame([], $availability['restrictions']);
$this->assertNotContains(false, $availability['capabilities'], true);
}
public function test_it_describes_a_requested_quantity_that_exceeds_the_remaining_quota(): void
{
$service = new CatalogItemAllowanceService(
Mockery::mock(UserPurchaseLimitService::class),
);
$availability = $service->purchaseLimitExceededAvailability(1, 'Solo podés agregar una unidad.');
$this->assertSame(1, $availability['maximum_quantity']);
$this->assertSame(
'requested_quantity_exceeds_user_quota',
$availability['restrictions'][0]['code'],
);
$this->assertTrue($availability['capabilities']['change_quantity']);
}
}