test: cover event variant replacements
This commit is contained in:
parent
2bd3bf9dc1
commit
b4a7b80430
|
|
@ -11,6 +11,7 @@ use App\Domains\Catalog\Models\Inventory;
|
|||
use App\Domains\Catalog\Models\Variant;
|
||||
use App\Domains\Event\Events\EventDateRescheduled;
|
||||
use App\Domains\Event\Events\EventDateSuspended;
|
||||
use App\Domains\Purchase\Services\Checkout\CatalogSelectionResolver;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use App\Domains\Tenant\Models\WebsiteType;
|
||||
use App\Domains\Ticket\Enums\ValidityTimeType;
|
||||
|
|
@ -20,6 +21,7 @@ use Database\Seeders\SocialMediaSeeder;
|
|||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
use Tests\TestCase;
|
||||
|
||||
|
|
@ -247,6 +249,7 @@ class AdminAppEventControllerTest extends TestCase
|
|||
'time_end' => '20:00',
|
||||
]);
|
||||
$variant = $this->createVariant($tenant, $original->id);
|
||||
$variant->inventory()->update(['real_stock' => 5]);
|
||||
$ticket = $this->createTicket($tenant, $admin, $variant);
|
||||
Sanctum::actingAs($admin);
|
||||
|
||||
|
|
@ -267,6 +270,31 @@ class AdminAppEventControllerTest extends TestCase
|
|||
});
|
||||
|
||||
$this->assertDatabaseCount('event_dates', 2);
|
||||
$variant->refresh();
|
||||
$replacement = $variant->replacement()->firstOrFail();
|
||||
$this->assertSame($original->id, $variant->event_date_id);
|
||||
$this->assertSame($destination->id, $replacement->event_date_id);
|
||||
$this->assertSame($variant->inventory_id, $replacement->inventory_id);
|
||||
$this->assertNotNull($variant->sales_disabled_at);
|
||||
$this->assertSame($replacement->id, $variant->replaced_by_variant_id);
|
||||
$this->assertSame(
|
||||
[$replacement->id],
|
||||
$variant->catalogItem->fresh(['variants.inventory'])->visibleVariants()->modelKeys(),
|
||||
);
|
||||
$this->assertSame($variant->id, $ticket->fresh()->source_variant_id);
|
||||
|
||||
try {
|
||||
app(CatalogSelectionResolver::class)->resolve(
|
||||
$tenant,
|
||||
$variant->catalog_item_id,
|
||||
$variant->id,
|
||||
'direct_items.0',
|
||||
);
|
||||
$this->fail('The historical variant should not be sellable.');
|
||||
} catch (ValidationException $exception) {
|
||||
$this->assertArrayHasKey('direct_items.0.variant_id', $exception->errors());
|
||||
}
|
||||
|
||||
$this->assertSame('20 de Octubre 2027', $tenant->fresh()->event_date_text);
|
||||
$this->getJson('/api/tenants/bootstrap?dominio=acme.test&path=%2F')
|
||||
->assertOk()
|
||||
|
|
@ -287,6 +315,12 @@ class AdminAppEventControllerTest extends TestCase
|
|||
])->assertOk()->assertJsonPath('data.status', 'rescheduled');
|
||||
|
||||
$this->assertDatabaseCount('event_dates', 3);
|
||||
$replacement->refresh();
|
||||
$latestReplacement = $replacement->replacement()->firstOrFail();
|
||||
$this->assertSame($replacement->inventory_id, $latestReplacement->inventory_id);
|
||||
$this->assertSame('2027-10-25', $latestReplacement->eventDate->date->format('Y-m-d'));
|
||||
$this->assertFalse($replacement->isSellable());
|
||||
$this->assertTrue($latestReplacement->isSellable());
|
||||
$this->assertSame('25 de Octubre 2027', $tenant->fresh()->event_date_text);
|
||||
$this->getJson('/api/tenants/bootstrap?dominio=acme.test&path=%2F')
|
||||
->assertOk()
|
||||
|
|
@ -299,6 +333,41 @@ class AdminAppEventControllerTest extends TestCase
|
|||
);
|
||||
}
|
||||
|
||||
public function test_rescheduling_reuses_an_equivalent_destination_variant(): void
|
||||
{
|
||||
Event::fake([EventDateRescheduled::class]);
|
||||
$tenant = $this->createActiveEvent($this->createTenant('acme'), 'Festival Acme');
|
||||
$original = $tenant->eventDates()->create([
|
||||
'date' => '2027-10-09',
|
||||
'time_start' => '09:00',
|
||||
'time_end' => '18:30',
|
||||
]);
|
||||
$destination = $tenant->eventDates()->create([
|
||||
'date' => '2027-10-20',
|
||||
'time_start' => '09:00',
|
||||
'time_end' => '18:30',
|
||||
]);
|
||||
$historicalVariant = $this->createVariant($tenant, $original->id);
|
||||
$destinationVariant = Variant::query()->create([
|
||||
'catalog_item_id' => $historicalVariant->catalog_item_id,
|
||||
'inventory_id' => Inventory::query()->create(['real_stock' => 5])->id,
|
||||
'event_date_id' => $destination->id,
|
||||
]);
|
||||
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||
|
||||
$this->postJson("/api/v1/adminapp/tenant/event-dates/{$original->id}/reschedule", [
|
||||
'date' => '2027-10-20',
|
||||
])->assertOk();
|
||||
|
||||
$this->assertSame(2, Variant::query()->count());
|
||||
$this->assertSame(
|
||||
$destinationVariant->id,
|
||||
$historicalVariant->fresh()->replaced_by_variant_id,
|
||||
);
|
||||
$this->assertSame($original->id, $historicalVariant->fresh()->event_date_id);
|
||||
$this->assertTrue($destinationVariant->fresh()->isSellable());
|
||||
}
|
||||
|
||||
public function test_suspending_disables_only_tickets_without_another_usable_date(): void
|
||||
{
|
||||
Event::fake([EventDateSuspended::class]);
|
||||
|
|
@ -335,6 +404,8 @@ class AdminAppEventControllerTest extends TestCase
|
|||
|
||||
$this->assertNotNull($singleDateTicket->fresh()->disabled_at);
|
||||
$this->assertNull($multipleDateTicket->fresh()->disabled_at);
|
||||
$this->assertNotNull($singleDateVariant->fresh()->sales_disabled_at);
|
||||
$this->assertNotNull($multipleDateVariant->fresh()->sales_disabled_at);
|
||||
$this->assertSame('10 de Octubre 2027', $tenant->fresh()->event_date_text);
|
||||
$this->getJson('/api/tenants/bootstrap?dominio=acme.test&path=%2F')
|
||||
->assertOk()
|
||||
|
|
|
|||
|
|
@ -72,6 +72,79 @@ class StorePurchaseTest extends TestCase
|
|||
$this->travelBack();
|
||||
}
|
||||
|
||||
public function test_checkout_replaces_a_historical_cart_variant_without_duplicating_stock(): void
|
||||
{
|
||||
$tenant = $this->createTenant('sonder', 'Sonder', 'sonder.com.ar');
|
||||
$user = User::factory()->create();
|
||||
$historicalVariant = $this->createVariantForTenant('sonder', 10, '50.00');
|
||||
$cart = Cart::query()->create([
|
||||
'tenant_codigo' => $tenant->codigo,
|
||||
'user_id' => $user->id,
|
||||
'status' => Cart::STATUS_ACTIVE,
|
||||
]);
|
||||
$cart->addItem($historicalVariant->catalog_item_id, $historicalVariant->id, 2);
|
||||
|
||||
$replacement = Variant::query()->create([
|
||||
'catalog_item_id' => $historicalVariant->catalog_item_id,
|
||||
'inventory_id' => $historicalVariant->inventory_id,
|
||||
'precio' => '50.00',
|
||||
]);
|
||||
$historicalVariant->update([
|
||||
'replaced_by_variant_id' => $replacement->id,
|
||||
'sales_disabled_at' => now(),
|
||||
]);
|
||||
|
||||
$purchase = app(CheckoutService::class)->startCheckout($tenant, $user->id, [
|
||||
'cart_id' => $cart->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('carrito_items', [
|
||||
'cart_id' => $cart->id,
|
||||
'variant_id' => $replacement->id,
|
||||
'cantidad' => 2,
|
||||
]);
|
||||
$this->assertDatabaseHas('compra_items', [
|
||||
'compra_id' => $purchase->id,
|
||||
'source_variant_id' => $replacement->id,
|
||||
'cantidad' => 2,
|
||||
]);
|
||||
$this->assertDatabaseHas('inventories', [
|
||||
'id' => $historicalVariant->inventory_id,
|
||||
'real_stock' => 10,
|
||||
'reserved_stock' => 2,
|
||||
]);
|
||||
$this->assertSame(8, $historicalVariant->catalogItem->fresh()->availableStock());
|
||||
}
|
||||
|
||||
public function test_direct_checkout_rejects_a_historical_variant(): void
|
||||
{
|
||||
$tenant = $this->createTenant('sonder', 'Sonder', 'sonder.com.ar');
|
||||
$user = User::factory()->create();
|
||||
$historicalVariant = $this->createVariantForTenant('sonder', 10, '50.00');
|
||||
$replacement = Variant::query()->create([
|
||||
'catalog_item_id' => $historicalVariant->catalog_item_id,
|
||||
'inventory_id' => $historicalVariant->inventory_id,
|
||||
'precio' => '50.00',
|
||||
]);
|
||||
$historicalVariant->update([
|
||||
'replaced_by_variant_id' => $replacement->id,
|
||||
'sales_disabled_at' => now(),
|
||||
]);
|
||||
|
||||
$this->actingAs($user, 'sanctum')
|
||||
->postJson('/api/tenants/sonder/compras/start-checkout', [
|
||||
'direct_items' => [[
|
||||
'catalog_item_id' => $historicalVariant->catalog_item_id,
|
||||
'variant_id' => $historicalVariant->id,
|
||||
'cantidad' => 1,
|
||||
]],
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('direct_items.0.variant_id');
|
||||
|
||||
$this->assertDatabaseCount('compras', 0);
|
||||
}
|
||||
|
||||
public function test_checkout_cannot_replace_an_overdue_cart_reservation(): void
|
||||
{
|
||||
$tenant = $this->createTenant('sonder', 'Sonder', 'sonder.com.ar');
|
||||
|
|
|
|||
Loading…
Reference in New Issue