Files
shopit-back/tests/Feature/Migrations/CreateDesfilePuraTendenciaTenantTest.php
ncoronel 45d74e166f feat(tenant): add Desfile footer background asset migration
- Add footer background image for Desfile Pura Tendencia
- Upload and associate the asset with the tenant during migration
- Extend migration coverage to verify attachment creation and storage
2026-08-12 13:54:05 -03:00

243 lines
9.3 KiB
PHP

<?php
namespace Tests\Feature\Migrations;
use Database\Seeders\MenuSeeder;
use Database\Seeders\SocialMediaSeeder;
use Database\Seeders\TenantSeeder;
use Database\Seeders\WebsiteTypeSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
class CreateDesfilePuraTendenciaTenantTest extends TestCase
{
use RefreshDatabase;
public function test_it_provisions_the_desfile_tenant_configuration(): void
{
Storage::fake('s3');
$this->seed([
WebsiteTypeSeeder::class,
SocialMediaSeeder::class,
TenantSeeder::class,
MenuSeeder::class,
]);
$migration = require database_path(
'migrations/2026_08_12_020000_create_desfile_pura_tendencia_tenant.php'
);
$migration->up();
$footerBackgroundMigration = require database_path(
'migrations/2026_08_12_060000_set_desfile_footer_background_image.php'
);
$footerBackgroundMigration->up();
$this->assertDatabaseHas('tenants', [
'codigo' => 'desfile_pura_tendencia',
'nombre' => 'Desfile Pura Tendencia',
'dominio' => 'desfile-pura-tendencia.localhost',
'website_type_code' => 'onticket',
'event_title' => 'Desfile Pura Tendencia',
'event_location' => 'Salón Centro Recreativo Luz y Fuerza',
'event_date_text' => '16 de Octubre 2026',
'primary_color' => '#BA69A9',
'secondary_color' => '#A0A0A0',
'danger_color' => '#FF8888',
'success_color' => '#198754',
'header_bg_color' => '#ffffff',
'footer_bg_color' => '#D4441C',
'display_categories' => false,
'display_seach_bar' => false,
]);
$eventDate = DB::table('event_dates')
->where('tenant_code', 'desfile_pura_tendencia')
->sole();
$this->assertSame('2026-10-16', $eventDate->date);
$this->assertSame('20:30:00', $eventDate->time_start);
$this->assertSame('23:59:00', $eventDate->time_end);
$this->assertDatabaseHas('validity_times', [
'id' => $eventDate->validity_time_id,
'type' => 'fixed_window',
'fixed_starts_at' => '2026-10-16 20:30:00',
'fixed_expires_at' => '2026-10-16 23:59:00',
]);
$hero = DB::table('websites_extras')
->join(
'website_type_extras',
'website_type_extras.id',
'=',
'websites_extras.website_type_extra_id',
)
->where('websites_extras.website_code', 'desfile_pura_tendencia')
->where('website_type_extras.codigo', 'heroConfig')
->value('websites_extras.config');
$hero = json_decode($hero, true, flags: JSON_THROW_ON_ERROR);
$this->assertSame('<h1>LA NOCHE DE LA MODA</h1>', $hero['title_html']);
$this->assertSame(
'Viví una experiencia de <b>Alta Costura con conducción exclusiva de Pampita</b> y las colecciones de Pucheta-Paz.',
$hero['description_html'],
);
$this->assertDatabaseHas('attachments', [
'id' => $hero['background_image_id'],
'filename' => 'desfile_pura_tendencia_hero.png',
'type' => 'image',
]);
$footerBackgroundImageId = DB::table('tenants')
->where('codigo', 'desfile_pura_tendencia')
->value('footer_bg_image_id');
$this->assertDatabaseHas('attachments', [
'id' => $footerBackgroundImageId,
'filename' => 'desfile_pura_tendencia_footer_background.png',
'type' => 'image',
]);
foreach ([
'desfile_pura_tendencia_header.png',
'desfile_pura_tendencia_footer.png',
'desfile_pura_tendencia_hero.png',
'desfile_pura_tendencia_footer_background.png',
'entrada_pasarela.png',
] as $filename) {
$path = DB::table('attachments')->where('filename', $filename)->value('path');
$this->assertNotNull($path);
Storage::disk('s3')->assertExists($path);
}
$expectedMenus = DB::table('tenants_menues')
->where('tenant_code', 'fiesta_futbol_infantil')
->where('menu_code', 'not like', 'adminapp.fiesta-futbol-infantil.%')
->orderBy('menu_code')
->pluck('menu_code')
->all();
$actualMenus = DB::table('tenants_menues')
->where('tenant_code', 'desfile_pura_tendencia')
->orderBy('menu_code')
->pluck('menu_code')
->all();
$this->assertSame($expectedMenus, $actualMenus);
$this->assertContains('main.adminapp', $actualMenus);
$this->assertContains('adminapp.event', $actualMenus);
$this->assertContains('scanner.scan', $actualMenus);
$this->assertNotContains('adminapp.fiesta-futbol-infantil.entradas', $actualMenus);
$catalogItem = DB::table('catalog_items')
->where('tenant_code', 'desfile_pura_tendencia')
->where('slug', 'entrada')
->sole();
$this->assertSame('Entrada', $catalogItem->nombre);
$this->assertSame('tracked', $catalogItem->inventory_policy);
$this->assertSame(1, $catalogItem->has_tickets);
$this->assertSame('one_per_unit', $catalogItem->ticket_generation_policy);
$this->assertSame($eventDate->validity_time_id, $catalogItem->validity_time_id);
$this->assertDatabaseHas('catalog_items_attachments', [
'catalog_item_id' => $catalogItem->id,
'variant_id' => null,
'orden' => 0,
]);
$this->assertDatabaseHas('featured_groups', [
'tenant_code' => 'desfile_pura_tendencia',
'source_type' => 'all',
'product_layout' => 'ticket_selector',
'group_layout' => 'single',
]);
$attributes = DB::table('attribute')
->where('tenant_codigo', 'desfile_pura_tendencia')
->orderBy('id')
->get()
->keyBy('codigo');
$this->assertSame(['tipo', 'sector', 'fila', 'asiento'], $attributes->keys()->all());
$this->assertSame([
'tipo' => ['VIP + LUNCH', 'NORMAL'],
'sector' => ['A', 'B', 'C', 'D'],
'fila' => array_map('strval', range(1, 17)),
'asiento' => array_map('strval', range(1, 5)),
], $attributes->map(fn (object $attribute): array => DB::table('attribute_options')
->where('attribute_id', $attribute->id)
->orderBy('sort_order')
->pluck('value')
->all())->all());
$variants = DB::table('variantes')->where('catalog_item_id', $catalogItem->id);
$this->assertSame(330, (clone $variants)->count());
$this->assertSame(1320, DB::table('variant_values')
->whereIn('variant_id', (clone $variants)->pluck('id'))
->count());
$this->assertSame(0, DB::table('variant_event_dates')
->whereIn('variant_id', (clone $variants)->pluck('id'))
->count());
$this->assertSame(330, (clone $variants)->whereNull('event_date_id')->count());
$this->assertSame(330, DB::table('inventories')
->whereIn('id', (clone $variants)->pluck('inventory_id'))
->where('real_stock', 1)
->where('reserved_stock', 0)
->where('sold_units', 0)
->count());
foreach ([
250000 => 34,
200000 => 34,
100000 => 34,
75000 => 34,
50000 => 34,
240000 => 32,
190000 => 32,
90000 => 32,
65000 => 32,
40000 => 32,
] as $price => $expectedCount) {
$this->assertSame($expectedCount, (clone $variants)->where('precio', $price)->count());
}
$this->assertSame(0, $this->variantCountForSelection($catalogItem->id, [
'sector' => ['B', 'D'],
'fila' => ['17'],
]));
$this->assertSame(66, $this->variantCountForSelection($catalogItem->id, [
'tipo' => ['VIP + LUNCH'],
'asiento' => ['1'],
]));
$this->assertSame(66, $this->variantCountForSelection($catalogItem->id, [
'tipo' => ['NORMAL'],
'asiento' => ['5'],
]));
}
/** @param array<string, list<string>> $selection */
private function variantCountForSelection(int $catalogItemId, array $selection): int
{
$query = DB::table('variantes')->where('catalog_item_id', $catalogItemId);
foreach ($selection as $attributeCode => $values) {
$query->whereExists(fn ($subquery) => $subquery
->selectRaw('1')
->from('variant_values')
->join(
'item_attributes',
'item_attributes.id',
'=',
'variant_values.item_attribute_id',
)
->join('attribute', 'attribute.id', '=', 'item_attributes.attribute_id')
->whereColumn('variant_values.variant_id', 'variantes.id')
->where('attribute.codigo', $attributeCode)
->whereIn('variant_values.value', $values));
}
return $query->count();
}
}