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'); } }