Files
Investidor-V2/tests/Feature/InvestmentAnchorIntegrationTest.php
T

128 lines
9.0 KiB
PHP

<?php
namespace Tests\Feature;
use App\Http\Controllers\InvestmentPortfolioController;
use App\Models\User;
use App\Services\ApprovedAnchorTerritories;
use App\Services\InvestmentRelations;
use App\Services\InvestorContext;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Inertia\Testing\AssertableInertia as Assert;
use Tests\TestCase;
final class InvestmentAnchorIntegrationTest extends TestCase
{
use DatabaseTransactions;
private User $actor;
protected function setUp(): void
{
parent::setUp();
$identity = DB::selectOne('select current_database() as name,inet_server_port() as port');
$this->assertSame('simulator_fiscal_delta_20261021_test', $identity->name);
$this->assertSame(55441, (int) $identity->port);
$this->withoutVite();
$this->withoutMiddleware(ThrottleRequests::class);
config(['investor-path.enabled' => true, 'investor-path.private_preparation' => true, 'suitecrm.enabled' => false, 'investmoz_ai.enabled' => false]);
$this->actor = User::factory()->create();
}
public function test_documented_sector_filter_is_explicit_and_preserves_the_catalogue_scope(): void
{
$anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
$sector = $anchor->content['sector'];
$this->get('/carteira?'.http_build_query(['kind' => 'project', 'sector' => $sector]))->assertOk()
->assertInertia(fn (Assert $p) => $p->where('filters.sector', $sector)->has('records.data', 1)->where('records.data.0.id', $anchor->id)->has('sectors'));
$this->get('/carteira?sector=sector-inexistente')->assertOk()->assertInertia(fn (Assert $p) => $p->has('records.data', 0));
$this->get('/carteira')->assertOk()->assertInertia(fn (Assert $p) => $p->where('records.total', InvestmentPortfolioController::visible()->count()));
}
public function test_accepted_territories_are_recovered_by_identity_with_citations_and_idempotence(): void
{
$service = app(ApprovedAnchorTerritories::class);
$before = DB::table('investment_dossiers')->orderBy('id')->get()->toJson();
$plan = $service->plan();
$this->assertCount(28, $plan['links']);
$this->assertCount(13, $plan['projects']);
$result = $service->apply($plan);
$this->assertSame(count(array_filter($plan['links'], fn ($link) => ! $link['already_present'])), $result['relations_restored']);
$this->assertSame(0, $result['publication_changes']);
$this->assertSame($before, DB::table('investment_dossiers')->orderBy('id')->get()->toJson());
$second = $service->apply($service->plan());
$this->assertSame(0, $second['relations_restored']);
$this->assertSame(0, $second['projects_updated']);
$anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
$locations = app(InvestmentRelations::class)->projectLocations($anchor->project_id);
$this->assertCount(4, $locations);
$this->assertNotEmpty($locations[0]['source_quote']);
$this->assertSame('secondary', $locations[0]['role']);
$province = $locations[0]['id'];
$this->get('/carteira?'.http_build_query(['kind' => 'project', 'sector' => $anchor->content['sector'], 'province_id' => $province]))->assertOk()
->assertInertia(fn (Assert $p) => $p->has('records.data', 1)->where('records.data.0.id', $anchor->id));
$this->assertCount(0, app(InvestmentRelations::class)->projectLocations(InvestmentPortfolioController::visible()->where('content->code', 'A01')->firstOrFail()->project_id));
}
public function test_anchor_without_offer_survives_login_dossier_and_simulator_as_documentary_origin(): void
{
$anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
$source = 'portfolio:'.$anchor->id;
$entry = '/investimentos/iniciar?'.http_build_query(['source' => $source]);
$this->get($entry)->assertRedirect(route('login'));
$this->assertStringEndsWith($entry, session('url.intended'));
$this->actingAs($this->actor);
$this->get($entry)->assertOk()->assertInertia(fn (Assert $p) => $p->where('source.key', $source)->has('opportunityChoices', 0));
$reference = app(InvestorContext::class)->reference($source);
$this->assertArrayNotHasKey('province_id', $reference['fields']);
$this->assertFalse($reference['analysis']['available_opportunity']);
$id = $this->postJson('/investimentos', ['title' => 'SYNTHETIC QA - ideia propria', 'client_key' => (string) Str::uuid(), 'reuse_consent' => true])->assertCreated()->json('id');
$body = ['version' => $this->getJson('/investimentos/'.$id.'/contexto')->json('case.version'), 'selection' => ['portfolio' => $source]];
$preview = $this->postJson('/investimentos/'.$id.'/contexto/previa', $body)->assertOk()->json();
$this->assertSame('SYNTHETIC QA - ideia propria', $preview['fields']['project_title']);
$this->postJson('/investimentos/'.$id.'/contexto/confirmar', [...$body, 'preview_hash' => $preview['preview_hash'], 'operation_key' => (string) Str::uuid(), 'confirm' => true])->assertOk();
$view = $this->getJson('/investimentos/'.$id.'/contexto')->assertOk()->json();
$this->assertSame($source, $view['context']['selection']['portfolio']['key']);
$this->assertSame([], $view['context']['opportunity_choices']);
$snapshot = json_decode($view['prefill']['simulator']['context_applicability_snapshot'], true);
$this->assertSame($source, $snapshot['portfolio_origin']['key']);
$draft = $this->postJson('/api/v1/simulation-drafts', ['context' => $id, 'personal_snapshot' => [], 'economic_snapshot' => ['purpose' => 'simulate_only', 'project_title' => 'SYNTHETIC QA - titulo proprio', 'context_applicability_snapshot' => json_encode($snapshot)]], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
$saved = $this->getJson('/api/v1/simulation-drafts/'.$draft.'?context='.$id)->assertOk()->json('data.economic_snapshot');
$this->assertSame($source, json_decode($saved['context_applicability_snapshot'], true)['portfolio_origin']['key']);
$this->assertSame('SYNTHETIC QA - titulo proprio', $saved['project_title']);
$anchor->publication_status = 'draft';
$anchor->save();
$this->get($entry)->assertNotFound();
}
public function test_interest_resumption_keeps_the_same_anchor_and_filters_without_creating_a_request_on_get(): void
{
$anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
$query = http_build_query(['sector' => $anchor->content['sector'], 'kind' => 'project']);
$entry = '/carteira/'.$anchor->id.'/interesse?'.http_build_query(['catalogue_query' => $query]);
$before = DB::table('investment_submissions')->count();
$this->get($entry)->assertRedirect(route('login'));
$this->assertStringEndsWith($entry, session('url.intended'));
$this->actingAs($this->actor);
$this->get($entry)->assertRedirect('/carteira/'.$anchor->id.'?'.http_build_query(['catalogue_query' => $query, 'prepare_interest' => '1']));
$this->assertSame($before, DB::table('investment_submissions')->count());
$response = $this->postJson('/investidor/manifestacoes', ['dossier_id' => $anchor->id])->assertCreated();
$row = DB::table('investment_submissions')->where('id', $response->json('id'))->first();
$this->assertSame($anchor->id, $row->dossier_id);
$start = '/investimentos/iniciar?'.http_build_query(['source' => 'portfolio:'.$anchor->id, 'submission' => $row->id]);
$this->get($start)->assertOk()->assertInertia(fn (Assert $p) => $p->where('entrySubmission.id', $row->id)->where('entrySubmission.version', (int) $row->version));
$other = InvestmentPortfolioController::visible()->where('id', '!=', $anchor->id)->firstOrFail();
$this->get('/investimentos/iniciar?'.http_build_query(['source' => 'portfolio:'.$other->id, 'submission' => $row->id]))->assertUnprocessable();
$case = $this->postJson('/investimentos', ['title' => 'SYNTHETIC QA - manifesto e ancora', 'client_key' => (string) Str::uuid(), 'reuse_consent' => true])->assertCreated()->json('id');
$version = $this->getJson('/investimentos/'.$case.'/contexto')->json('case.version');
$this->postJson('/investidor/manifestacoes/'.$row->id.'/contexto', ['case_id' => $case, 'case_version' => $version, 'version' => (int) $row->version])->assertOk();
$this->assertSame($row->id, DB::table('desk_cases')->where('id', $case)->value('submission_id'));
$this->assertSame($anchor->id, DB::table('investment_submissions')->where('id', $row->id)->value('dossier_id'));
$this->actingAs(User::factory()->create());
$this->get($start)->assertNotFound();
}
}