createTenant('search-default'); $this->assertDatabaseHas('tenants', [ 'codigo' => $tenant->codigo, 'search_product_layout' => ProductLayout::ColumnWithImage->value, 'search_group_layout' => GroupLayout::Paginated->value, 'search_items_per_page' => 12, ]); } public function test_search_layouts_can_be_updated_on_the_tenant_and_are_returned_by_bootstrap(): void { $tenant = $this->createTenant('search-config'); $this->putJson("/api/tenants/{$tenant->codigo}", [ 'search_product_layout' => ProductLayout::Row->value, 'search_group_layout' => GroupLayout::SimpleVertical->value, 'search_items_per_page' => 24, ]) ->assertOk() ->assertJsonPath('data.search_product_layout', ProductLayout::Row->value) ->assertJsonPath('data.search_group_layout', GroupLayout::SimpleVertical->value) ->assertJsonPath('data.search_items_per_page', 24); $this->getJson("/api/tenants/bootstrap/{$tenant->dominio}") ->assertOk() ->assertJsonPath('data.search_product_layout', ProductLayout::Row->value) ->assertJsonPath('data.search_group_layout', GroupLayout::SimpleVertical->value) ->assertJsonPath('data.search_items_per_page', 24); } public function test_search_is_tenant_scoped_relevant_and_uses_configured_page_size(): void { $tenant = $this->createTenant('search-items'); $otherTenant = $this->createTenant('other-search-items'); $tenant->update(['search_items_per_page' => 4]); foreach (range(1, 5) as $number) { $this->createCatalogItem($tenant, "Running {$number}"); } $exactMatch = $this->createCatalogItem($tenant, 'Running'); $this->createCatalogItem($tenant, 'Unrelated'); $this->createCatalogItem($otherTenant, 'Running foreign'); $response = $this->getJson( "/api/tenants/{$tenant->codigo}/catalog-items?q=running" ); $response ->assertOk() ->assertJsonPath('meta.current_page', 1) ->assertJsonPath('meta.per_page', 4) ->assertJsonPath('meta.total', 6) ->assertJsonCount(4, 'data') ->assertJsonPath('data.0.id', $exactMatch->id) ->assertJsonMissing(['nombre' => 'Running foreign']) ->assertJsonMissing(['nombre' => 'Unrelated']); } public function test_search_validates_the_query(): void { $tenant = $this->createTenant('search-validation'); $this->getJson("/api/tenants/{$tenant->codigo}/catalog-items?q=a") ->assertUnprocessable() ->assertJsonValidationErrors('q'); } private function createCatalogItem(Tenant $tenant, string $name): CatalogItem { $inventory = Inventory::query()->create(['real_stock' => 10]); return CatalogItem::query()->create([ 'tenant_code' => $tenant->codigo, 'inventory_id' => $inventory->id, 'slug' => str($name)->slug()->toString(), 'nombre' => $name, 'descripcion' => "{$name} description", 'precio' => 100, ]); } private function createTenant(string $code): Tenant { $headerLogo = $this->createAttachment("{$code}-header"); $footerLogo = $this->createAttachment("{$code}-footer"); return Tenant::query()->create([ 'codigo' => $code, 'nombre' => ucfirst($code), 'dominio' => "{$code}.local", 'primary_color' => '#000000', 'secondary_color' => '#000000', 'danger_color' => '#000000', 'success_color' => '#000000', 'header_bg_color' => '#000000', 'footer_bg_color' => '#000000', 'header_logo_id' => $headerLogo->id, 'footer_logo_id' => $footerLogo->id, ]); } private function createAttachment(string $name): Attachment { return Attachment::query()->create([ 'path' => "test/{$name}.png", 'filename' => "{$name}.png", 'type' => AttachmentType::Image, 'mime_type' => 'image/png', ]); } }