withoutVite(); $this->get('/pesquisa?'.http_build_query(['q' => 'como licenciar uma empresa']))->assertOk()->assertInertia(fn (Assert $page) => $page ->where('answer.type', 'guide')->where('results.total', 2) ->where('results.data.0.url', '/como-investir#planeamento') ->where('results.data.1.url', '/investimentos/iniciar?step=S08')); } public function test_physical_product_search_keeps_the_product_and_documented_location_in_its_link(): void { $this->assertTrue(IsolatedQaDatabase::allowsSchemaChanges()); $this->withoutVite(); config(['portal.legacy_content_enabled' => false, 'portal.legacy_content_qa_enabled' => false]); $sector = Sector::firstOrCreate(['slug' => 'mineracao'], ['name' => 'Mineração']); $sector->forceFill(['is_active' => true, 'published_at' => now()->subMinute()])->save(); $this->get('/pesquisa?'.http_build_query(['q' => 'onde encontrar grafite em Cabo Delgado']))->assertOk()->assertInertia(fn (Assert $page) => $page ->where('answer.type', 'products')->where('results.total', 1)->where('results.unavailable', []) ->where('results.data.0.title', 'Grafite')->where('results.data.0.category', 'Produtos e localizações') ->where('results.data.0.location', fn ($text) => str_contains($text, 'Cabo Delgado')) ->where('results.data.0.url', fn ($url) => str_contains($url, 'resource_group=') && str_contains($url, 'resource_location=Cabo+Delgado'))); $this->get('/pesquisa?'.http_build_query(['q' => 'grafite Cabo Delgado', 'category' => 'physical']))->assertOk()->assertInertia(fn (Assert $page) => $page ->where('answer.category', 'physical')->where('results.total', 1) ->where('results.data.0.category', 'Produtos e localizações')); $this->get('/pesquisa?category=invalid')->assertRedirect(); } public function test_financial_product_search_excludes_drafts_and_future_publications_and_distinguishes_coverage(): void { $this->assertTrue(IsolatedQaDatabase::allowsSchemaChanges()); $this->withoutVite(); if (! Schema::hasTable('funding_programmes')) { // Only this transaction in the isolated QA database; no active schema changes. (require database_path('migrations/2026_11_02_210000_funding_programme_catalogue.php'))->up(); } $actor = User::factory()->create(); $marker = 'SYNTHFIN'.Str::random(8); foreach (['published', 'draft', 'future'] as $state) { $id = (string) Str::uuid(); $version = (string) Str::uuid(); $payload = json_encode(['title' => $marker.' '.$state, 'kind' => 'institution', 'summary' => 'Nota de preparação: ficha e documento gerador.', 'institution_nature' => 'bank', 'institution_services' => ['investment'], 'locations' => [['location_text' => 'Nampula']], 'products' => [['title' => 'Crédito PME', 'coverage' => 'national', 'needs' => ['investment']]]], JSON_THROW_ON_ERROR); DB::table('funding_programmes')->insert(['id' => $id, 'code' => $marker.$state, 'draft' => $payload, 'created_by' => $actor->id]); DB::table('funding_programme_versions')->insert(['id' => $version, 'programme_id' => $id, 'version' => 1, 'payload' => $payload, 'reason' => 'Synthetic QA only', 'actor_id' => $actor->id, 'published_at' => $state === 'future' ? now()->addDay() : now()->subMinute()]); if ($state !== 'draft') { DB::table('funding_programmes')->where('id', $id)->update(['published_version_id' => $version]); } } $this->get('/pesquisa?'.http_build_query(['q' => 'produtos financeiros '.$marker.' em Nampula']))->assertOk()->assertInertia(fn (Assert $page) => $page ->where('answer.type', 'products')->where('results.total', 1)->where('results.unavailable', []) ->where('results.data.0.category', 'Produtos financeiros')->where('results.data.0.description', 'Crédito PME') ->where('results.data.0.location', 'Presença física: Nampula') ->where('results.data.0.coverage', fn ($text) => str_contains($text, 'nacional'))); } public function test_corridor_count_excludes_other_types_drafts_and_deleted_entities(): void { $this->assertTrue(IsolatedQaDatabase::allowsSchemaChanges()); $this->withoutVite(); $marker = 'SYNTHCOUNT'.Str::random(10); foreach (range(1, 4) as $n) { $corridor = DevelopmentCorridor::create(['code' => $marker.$n, 'name' => $marker.$n, 'status' => 'active', 'data_classification' => 'public']); InvestmentDossier::create(['corridor_id' => $corridor->id, 'title' => $marker.' '.$n, 'content' => [], 'source' => 'Synthetic QA only', 'publication_status' => $n === 3 ? 'draft' : 'published', 'published_at' => now()->subMinute(), 'approval_basis' => 'document_owner', 'approval_evidence' => 'Synthetic QA only']); if ($n === 4) { $corridor->delete(); } } InvestmentDossier::create(['project_id' => Project::factory()->create()->id, 'title' => $marker.' corredor relacionado', 'content' => [], 'source' => 'Synthetic QA only', 'publication_status' => 'published', 'published_at' => now(), 'approval_basis' => 'document_owner', 'approval_evidence' => 'Synthetic QA only']); $query = 'quantos corredores existem '.$marker; $this->get('/pesquisa?'.http_build_query(['q' => $query]))->assertOk()->assertInertia(fn (Assert $page) => $page ->component('portal/search')->where('query', $query)->where('answer.count', 2)->where('answer.label', 'corredores') ->where('results.total', 2)->has('results.data', 2)->where('results.unavailable', [])); $this->get('/pesquisa?'.http_build_query(['q' => 'quantos corredores existem '.$marker.' inexistente'])) ->assertOk()->assertInertia(fn (Assert $page) => $page->where('answer.count', 0)->where('results.total', 0)); $this->get('/pesquisa?q=quantos+corredores+existem')->assertOk()->assertInertia(fn (Assert $page) => $page ->where('answer.label', 'corredores')->where('answer.count', fn ($count) => $count >= 2) ->where('results.unavailable', [])); } }