Files
Investidor-V2/tests/Feature/InvestmentStructureTest.php
T
nala 250ac35fd1
tests / ci (push) Canceled after 0s
first commit
2026-09-28 10:01:09 +02:00

86 lines
4.7 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\EconomicCluster;
use App\Models\Project;
use App\Models\User;
use App\Models\ValueChain;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
class InvestmentStructureTest extends TestCase
{
use RefreshDatabase;
private function manager(): void
{
$user = User::factory()->create();
config(['portal.managers' => [$user->email]]);
$this->actingAs($user);
}
public function test_project_validates_money_dates_and_duplicate_codes_without_precision_loss(): void
{
$this->manager();
$data = ['code' => 'P-001', 'name' => 'Projecto de teste', 'status' => 'planned',
'budget_amount' => '999999999999999999.99', 'budget_currency' => 'MZN',
'start_date' => '2026-10-01', 'end_date' => '2026-11-01'];
$this->post('/management/projects', [...$data, 'end_date' => '2026-09-01'])->assertSessionHasErrors('end_date');
$this->post('/management/projects', [...$data, 'budget_currency' => ''])->assertSessionHasErrors('budget_currency');
$this->post('/management/projects', $data)->assertSessionHasNoErrors()->assertRedirect();
$project = Project::firstOrFail();
$this->assertSame($data['budget_amount'], $project->budget_amount);
$this->post('/management/projects', $data)->assertSessionHasErrors('code');
$this->put('/management/projects/'.$project->id, [...$data, 'status' => 'active'])->assertSessionHasNoErrors();
$this->get('/management/projects/'.$project->id.'/edit')->assertOk();
$this->get('/management/projects?q=P-001')->assertOk();
$this->assertDatabaseCount('projects', 1);
$this->assertSame(2, DB::table('audit_events')->where('entity_type', 'projects')->count());
}
public function test_cluster_membership_is_idempotent_and_role_changes_are_audited(): void
{
$this->manager();
$this->post('/management/clusters', ['code' => 'C-001', 'name' => 'Cluster de teste', 'sector' => 'Energia', 'status' => 'planned'])->assertSessionHasNoErrors();
$cluster = EconomicCluster::firstOrFail();
$project = Project::factory()->create();
$url = '/management/clusters/'.$cluster->id.'/projects';
$this->post($url, ['project_id' => $project->id, 'role' => 'anchor'])->assertSessionHasNoErrors();
$this->post($url, ['project_id' => $project->id, 'role' => 'anchor'])->assertSessionHasNoErrors();
$this->assertDatabaseCount('cluster_projects', 1);
$this->post($url, ['project_id' => $project->id, 'role' => 'supporting'])->assertSessionHasNoErrors();
$this->assertDatabaseHas('cluster_projects', ['project_id' => $project->id, 'role' => 'supporting']);
$this->assertSame(2, DB::table('audit_events')->where('entity_type', 'cluster_projects')->count());
$project->delete();
$this->post($url, ['project_id' => $project->id, 'role' => 'anchor'])->assertSessionHasErrors('project_id');
$this->get('/management/clusters/'.$cluster->id.'/edit')->assertOk();
}
public function test_chain_edit_cannot_cross_cluster_and_codes_are_unique_per_cluster(): void
{
$this->manager();
$first = EconomicCluster::create(['code' => 'C1', 'name' => 'Primeiro', 'sector' => 'Energia', 'status' => 'planned']);
$second = EconomicCluster::create(['code' => 'C2', 'name' => 'Segundo', 'sector' => 'Agro', 'status' => 'planned']);
$data = ['code' => 'INPUT', 'name' => 'Insumos', 'stage' => 'input'];
$this->post('/management/clusters/'.$first->id.'/chains', $data)->assertSessionHasNoErrors();
$chain = ValueChain::firstOrFail();
$this->post('/management/clusters/'.$first->id.'/chains', $data)->assertSessionHasErrors('code');
$this->post('/management/clusters/'.$second->id.'/chains', $data)->assertSessionHasNoErrors();
$this->put('/management/clusters/'.$second->id.'/chains/'.$chain->id, [...$data, 'name' => 'Alterado'])->assertNotFound();
$this->assertSame('Insumos', $chain->fresh()->name);
$this->put('/management/clusters/'.$first->id.'/chains/'.$chain->id, [...$data, 'stage' => 'processing'])->assertSessionHasNoErrors();
$this->assertSame('processing', $chain->fresh()->stage);
}
public function test_structure_management_requires_authorised_verified_manager(): void
{
$this->get('/management/clusters')->assertRedirect('/login');
$this->actingAs(User::factory()->create());
$this->get('/management/projects')->assertForbidden();
$this->post('/management/clusters', [])->assertForbidden();
$this->assertDatabaseCount('economic_clusters', 0);
}
}