Files
Investidor-V2/tests/Feature/DeskFormAnalysisScopeTest.php
2026-11-02 20:31:15 +02:00

108 lines
5.9 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Tests\TestCase;
final class DeskFormAnalysisScopeTest extends TestCase
{
use RefreshDatabase;
private User $manager;
private User $investor;
protected function setUp(): void
{
parent::setUp();
$this->withoutVite();
$this->manager = User::factory()->create();
$this->investor = User::factory()->create();
config(['portal.managers' => [$this->manager->email]]);
}
private function publish(string $code, array $definition, int $version = 0): string
{
return $this->actingAs($this->manager)->putJson('/management/balcao/servicos/'.$code, [
'base_version' => $version, 'definition' => $definition, 'confirm' => true,
'reason' => 'Synthetic QA analysis scope, without actual applicants.',
])->assertCreated()->json('id');
}
private function requestUrl(string $service): string
{
$case = $this->actingAs($this->investor)->postJson('/balcao-virtual/dossiers', [
'title' => 'Synthetic analysis scope', 'client_key' => (string) Str::uuid(), 'reuse_consent' => true,
])->assertCreated()->json('id');
$id = $this->postJson('/balcao-virtual/dossiers/'.$case.'/pedidos', [
'service_version_id' => $service, 'client_key' => (string) Str::uuid(),
])->assertCreated()->json('id');
return '/balcao-virtual/pedidos/'.$id;
}
public function test_checks_do_not_ask_for_finance_or_location_fields_absent_from_the_form(): void
{
$definition = config('virtual-desk.services.project-change');
unset($definition['fields']['territory_id'], $definition['fields']['location_source']);
$url = $this->requestUrl($this->publish('project-change', $definition));
$view = $this->getJson($url)->assertOk()->json();
$codes = array_column($view['findings'], 'code');
$this->assertNotContains('finance_unknown', $codes);
$this->assertNotContains('finance_difference', $codes);
$this->assertNotContains('location_unknown', $codes);
$this->assertContains('official_form_pending', $codes);
}
public function test_inactive_answers_are_preserved_without_blocking_submission_and_receipt_distinguishes_their_scope(): void
{
$definition = config('virtual-desk.services.project-preparation');
$definition['fields']['financial_branch'] = ['label' => 'Synthetic branch', 'type' => 'select', 'required' => true,
'options' => ['no' => 'No', 'yes' => 'Yes']];
foreach (['investment_amount', 'own_finance', 'other_finance', 'currency', 'territory_id', 'location_source'] as $key) {
$definition['fields'][$key]['when'] = ['field' => 'financial_branch', 'equals' => 'yes'];
}
$definition['fields']['investment_amount']['label'] = 'Valor sintético preservado';
$url = $this->requestUrl($this->publish('project-preparation', $definition));
$answers = ['title' => 'Synthetic investment', 'description' => 'Synthetic description', 'regime' => 'unknown',
'financial_branch' => 'no', 'investment_amount' => '100.00', 'own_finance' => '20.00', 'other_finance' => '30.00',
'currency' => 'MZN', 'location_source' => 'Synthetic stored source'];
$this->putJson($url, ['version' => 1, 'payload' => $answers, 'submit' => true, 'consent' => true])
->assertOk()->assertJsonPath('status', 'submitted');
$view = $this->getJson($url)->assertOk()->json();
$this->assertSame($answers, $view['request']['payload']);
$this->assertNotContains('finance_difference', array_column($view['findings'], 'code'));
$this->assertNotContains('finance_unknown', array_column($view['findings'], 'code'));
$this->assertNotContains('location_unknown', array_column($view['findings'], 'code'));
$id = basename($url);
$snapshot = DB::table('desk_requests')->where('id', $id)->value('submitted_snapshot');
$definition['fields']['investment_amount']['label'] = 'A later version must not relabel old receipts';
$this->publish('project-preparation', $definition, 1);
$this->actingAs($this->investor);
$html = $this->get($url.'/recibo?format=html')->assertOk()->assertHeader('Cache-Control', 'no-store, private')
->assertSee('Respostas conservadas de perguntas não aplicáveis')->assertSee('Valor sintético preservado')
->assertDontSee('A later version must not relabel old receipts')->getContent();
[$applicable, $preserved] = explode('Respostas conservadas de perguntas não aplicáveis', $html, 2);
$this->assertStringNotContainsString('Valor sintético preservado', $applicable);
$this->assertStringContainsString('Valor sintético preservado', $preserved);
$this->assertStringContainsString('100,00 MZN', $preserved);
$technical = $this->get($url.'/recibo')->assertOk()->streamedContent();
$this->assertStringContainsString('100.00', $technical);
$this->assertSame($snapshot, DB::table('desk_requests')->where('id', $id)->value('submitted_snapshot'));
$this->actingAs(User::factory()->create())->get($url.'/recibo?format=html')->assertForbidden();
$active = $this->requestUrl(DB::table('desk_service_versions')->where('code', 'project-preparation')->where('version', 2)->value('id'));
$answers['financial_branch'] = 'yes';
$this->putJson($active, ['version' => 1, 'payload' => $answers, 'submit' => true, 'consent' => true])
->assertUnprocessable()->assertJsonValidationErrors('payload.investment_amount');
$answers['own_finance'] = '40.00';
$answers['other_finance'] = '60.00';
$this->putJson($active, ['version' => 1, 'payload' => $answers, 'submit' => true, 'consent' => true])
->assertOk()->assertJsonPath('status', 'submitted');
}
}