77 lines
5.9 KiB
PHP
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();
|
|
}
|
|
}
|