Files
Investidor-V2/tests/Unit/InvestorGuidanceRulesTest.php
nala 1106509116
tests / ci (push) Canceled after 0s
vrsao 2
2026-10-08 14:02:01 +02:00

62 lines
3.6 KiB
PHP

<?php
namespace Tests\Unit;
use App\Services\Ai\InvestorGuidanceRules;
use PHPUnit\Framework\TestCase;
class InvestorGuidanceRulesTest extends TestCase
{
public function test_declared_quantities_require_common_scope_and_never_invent_missing_values(): void
{
$rules = new InvestorGuidanceRules;
$missing = $rules->evaluate(['demand_quantity' => '100', 'capacity_quantity' => '50']);
$this->assertContains('demand_quantity_comparison_incomplete', array_column($missing[1]['risks'], 'code'));
$facts = ['demand_quantity' => '100', 'capacity_quantity' => '50', 'quantity_unit' => 'toneladas', 'quantity_period' => 'ano',
'resources_required' => '12', 'resources_available' => '0', 'resource_unit' => 'pessoas',
'funding_required' => '100.50', 'funding_committed' => '100.49', 'funding_currency' => 'MZN',
'expected_start_date' => '2026-12-01', 'funding_ready_date' => '2027-01-01', 'completion_date' => '2026-11-01'];
$phases = $rules->evaluate($facts);
foreach ([1 => 'demand_quantity_declared_gap', 3 => 'resources_required_declared_gap', 4 => 'funding_required_declared_gap'] as $i => $code) {
$this->assertContains($code, array_column($phases[$i]['risks'], 'code'));
foreach ($phases[$i]['risks'] as $risk) {
$this->assertFalse($risk['restriction']);
}
}
$this->assertCount(2, $phases[5]['risks']);
$facts['funding_committed'] = '100.50';
$this->assertNotContains('funding_required_declared_gap', array_column($rules->evaluate($facts)[4]['risks'], 'code'));
}
public function test_missing_declared_and_attached_information_are_not_verified(): void
{
$rules = new InvestorGuidanceRules;
$this->assertSame('absent', $rules->evaluate([])[2]['evidence'][0]['state']);
$declared = $rules->evaluate(['location_evidence' => 'Declaração QA']);
$this->assertSame('investor_declared_not_verified', $declared[2]['evidence'][0]['state']);
$attached = $rules->evaluate([], ['location_evidence' => ['state' => 'attached_unchecked', 'documents' => []]]);
$this->assertSame('attached_unchecked', $attached[2]['evidence'][0]['state']);
$this->assertNotEmpty($attached[2]['risks']);
}
public function test_scoped_internal_verification_removes_only_the_corresponding_pending_alert(): void
{
$evidence = ['location_evidence' => ['state' => 'internally_verified', 'documents' => [['review' => ['author' => 'Verificador QA', 'date' => '2026-10-08', 'scope' => 'Acesso descrito no documento QA']]]]];
$phases = (new InvestorGuidanceRules)->evaluate([], $evidence);
$this->assertSame([], $phases[2]['risks']);
$this->assertNotEmpty($phases[3]['risks']);
$this->assertSame($evidence['location_evidence']['documents'], $phases[2]['evidence'][0]['documents']);
$this->assertStringContainsString('não aprova', $phases[2]['recommendations'][0]['limitations'][0]);
}
public function test_contradictions_expiration_and_replacement_are_specific_non_blocking_alerts(): void
{
foreach (['contradiction', 'expired', 'superseded'] as $state) {
$phase = (new InvestorGuidanceRules)->evaluate([], ['market_evidence' => ['state' => $state, 'documents' => []]])[1];
$this->assertSame('market_evidence_'.$state, $phase['risks'][0]['code']);
$this->assertFalse($phase['risks'][0]['restriction']);
$this->assertSame($state === 'contradiction' ? 'documented_contradiction' : 'insufficient_information', $phase['risks'][0]['classification']);
}
}
}