Files
Investidor-V2/tests/Feature/DashboardOpportunityAccessTest.php
nala 01405cbf8a
tests / ci (push) Canceled after 0s
oportunidades 5
2026-10-10 14:15:28 +02:00

77 lines
5.9 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Opportunity;
use App\Models\User;
use App\Services\OpportunityManagement;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Inertia\Testing\AssertableInertia as Assert;
use Tests\TestCase;
class DashboardOpportunityAccessTest extends TestCase
{
use RefreshDatabase;
public function test_dashboard_exposes_authorized_destinations_and_complete_draft_archive_recovery(): void
{
$manager = User::factory()->create();
config(['portal.managers' => [$manager->email], 'portal.opportunity_dashboard_access_enabled' => true]);
$this->actingAs($manager)->get('/dashboard')->assertOk()->assertInertia(fn (Assert $page) => $page
->component('dashboard')->where('auth.canManagePortal', true)
->where('opportunityManagement.installed', true)
->where('opportunityManagement.manage.label', 'Gestão de Oportunidades')
->where('opportunityManagement.create.label', 'Nova oportunidade'));
// Discover destinations from the dashboard response, rather than assuming
// a successful direct request proves dashboard navigation.
$dashboard = $this->get('/dashboard')->viewData('page')['props']['opportunityManagement'];
$this->get($dashboard['manage']['href'])->assertInertia(fn (Assert $page) => $page->component('management/opportunities'));
$this->get($dashboard['create']['href'])->assertInertia(fn (Assert $page) => $page->component('management/opportunity-draft')->where('record', null));
$draft = $this->postJson('/management/opportunities/drafts', ['creation_key' => (string) Str::uuid(), 'title' => 'QA dashboard draft', 'reason' => 'Criação de rascunho pelo painel de gestão QA'])->assertCreated()->json();
$id = $draft['id'];
$this->get('/management/opportunities/'.$id.'/edit')->assertInertia(fn (Assert $page) => $page->where('values.title', 'QA dashboard draft'));
$update = $this->putJson('/management/opportunities/'.$id.'/draft', ['etag' => $draft['etag'], 'title' => 'QA dashboard edited', 'reason' => 'Edição e recuperação autorizadas no ensaio QA'])->assertOk()->json();
$request = ['etag' => $update['etag'], 'action' => 'archive', 'reason' => 'Arquivo explícito sem eliminar o rascunho QA', 'confirm' => true];
$this->postJson('/management/opportunities/'.$id.'/lifecycle', [...$request, 'confirm' => false])->assertUnprocessable();
$this->postJson('/management/opportunities/'.$id.'/lifecycle', $request)->assertOk();
$this->assertDatabaseHas('opportunities', ['id' => $id, 'status' => 'archived', 'title' => 'QA dashboard edited', 'deleted_at' => null, 'first_submitted_at' => null, 'management_closed_once' => false]);
$this->get($dashboard['manage']['href'].'?status=archived')->assertInertia(fn (Assert $page) => $page->where('records.data.0.id', $id));
$this->putJson('/management/opportunities/'.$id.'/draft', ['etag' => $update['etag'], 'reason' => $request['reason']])->assertConflict();
$this->postJson('/management/opportunities/'.$id.'/lifecycle', [...$request, 'action' => 'restore', 'etag' => app(OpportunityManagement::class)->etag(Opportunity::findOrFail($id))])->assertOk();
$this->get('/management/opportunities/'.$id.'/edit')->assertInertia(fn (Assert $page) => $page->where('record.status', 'draft')->where('values.title', 'QA dashboard edited'));
$this->assertSame(0, Opportunity::published()->count());
$this->assertSame(4, DB::table('audit_events')->where('source_system', 'opportunity-management')->where('after_data->record_id', $id)->count());
}
public function test_investor_unverified_manager_and_guest_do_not_gain_management_access(): void
{
$manager = User::factory()->unverified()->create();
$investor = User::factory()->create();
config(['portal.managers' => [$manager->email], 'portal.opportunity_dashboard_access_enabled' => true]);
$this->actingAs($investor)->get('/dashboard')->assertInertia(fn (Assert $page) => $page->where('summary', null)->where('opportunityManagement', null)->where('auth.canManagePortal', false));
$this->get('/management/opportunities')->assertForbidden();
$this->postJson('/management/opportunities/drafts', ['creation_key' => (string) Str::uuid()])->assertForbidden();
$this->actingAs($manager)->get('/dashboard')->assertRedirect('/email/verify');
$this->getJson('/management/opportunities')->assertForbidden();
$this->assertSame(0, Opportunity::count());
auth()->forgetGuards();
$this->flushSession();
$this->get('/dashboard')->assertRedirect('/login');
}
public function test_missing_installation_is_explicit_and_disabled_increment_preserves_compatibility(): void
{
$manager = User::factory()->create();
config(['portal.managers' => [$manager->email], 'portal.opportunity_dashboard_access_enabled' => false]);
$this->actingAs($manager)->get('/dashboard')->assertInertia(fn (Assert $page) => $page->where('opportunityManagement', null));
$this->postJson('/management/opportunities/1/lifecycle', ['etag' => str_repeat('a', 64), 'action' => 'archive', 'reason' => 'Incremento ainda não disponibilizado nesta configuração', 'confirm' => true])->assertUnprocessable();
config(['portal.opportunity_dashboard_access_enabled' => true]);
$migration = require database_path('migrations/2026_10_09_020000_extend_opportunity_management.php');
$migration->down();
$this->get('/dashboard')->assertInertia(fn (Assert $page) => $page->where('opportunityManagement.installed', false)->where('opportunityManagement.installationHref', '/management/opportunity-management-install'));
$this->postJson('/management/opportunities/drafts', ['creation_key' => (string) Str::uuid()])->assertServiceUnavailable();
}
}