Files
compras/tests/Feature/ProcurementReviewReportTest.php
T

94 lines
5.2 KiB
PHP

<?php
use App\Enums\PurchasingRole;
use App\Models\AuditLog;
use App\Models\Department;
use App\Models\QualificationAssessment;
use App\Models\QualificationSet;
use App\Models\Tenant;
use App\Models\User;
use App\Services\DocumentaryQualificationWorkflow;
use App\Services\ProcurementReviewReport;
use Illuminate\Support\Facades\DB;
use Inertia\Testing\AssertableInertia as Assert;
require_once __DIR__.'/../Support/QualificationFixture.php';
beforeEach(function () {
$this->f = qualificationFixture();
$this->url = '/requisicoes/'.$this->f['r']->id.'/relatorio';
$this->actingAs($this->f['issuer']);
});
function documentaryReportRecords(object $test): QualificationSet
{
$workflow = app(DocumentaryQualificationWorkflow::class);
$test->actingAs($test->f['issuer']);
$set = $workflow->define($test->f['issuer'], $test->f['r'], $test->f['definition']);
$test->actingAs($test->f['analyst']);
$workflow->assess($test->f['analyst'], $set, $test->f['assessment']);
return $set;
}
test('review report returns a private read-only consultation without inventing missing decisions', function () {
$before = AuditLog::query()->count();
$this->get($this->url)->assertOk()->assertHeader('Cache-Control', 'max-age=0, no-store, private')
->assertInertia(fn (Assert $page) => $page->component('purchases/review-report')
->where('report.requisition.number', $this->f['r']->number)
->where('report.comparison.ready', false)->where('report.comparison.top_count', 0)
->where('report.comparison.rows.0.score_minor', null)->where('report.comparison.rows.0.is_top', false)
->where('report.qualification', null)->where('report.award', null)->where('report.order', null)
->missing('report.recommended_supplier_id')->missing('report.bank_snapshot'));
expect(AuditLog::query()->count())->toBe($before);
});
test('review report separates current comparison from outdated documentary identities and results', function () {
$set = documentaryReportRecords($this);
$this->f['quote']->update(['reference' => 'REFERENCIA-POSTERIOR']);
$this->get($this->url)->assertInertia(fn (Assert $page) => $page->where('report.comparison.rows.0.reference', 'REFERENCIA-POSTERIOR')
->where('report.qualification.is_current', false)->where('report.qualification.revision', $set->revision)
->where('report.qualification.proposals.0.reference', 'PROP-TEST')
->where('report.qualification.proposals.0.analyses.0.answers.1.result', 'pending'));
});
test('review report retains the latest record of each analyst without majority or silent replacement', function () {
$set = documentaryReportRecords($this);
$first = QualificationAssessment::query()->sole();
$workflow = app(DocumentaryQualificationWorkflow::class);
$workflow->assess($this->f['analyst'], $set, [...$this->f['assessment'], 'previous_id' => $first->id, 'reason' => 'Correcção fictícia para conferência']);
$this->actingAs($this->f['other_analyst']);
$workflow->assess($this->f['other_analyst'], $set, $this->f['assessment']);
$before = AuditLog::query()->count();
$this->get($this->url)->assertInertia(fn (Assert $page) => $page->where('report.qualification.is_current', true)
->has('report.qualification.proposals.0.analyses', 2)
->where('report.qualification.proposals.0.analyses.0.revision', 2)
->where('report.qualification.proposals.0.analyses.1.revision', 1));
expect(QualificationAssessment::query()->count())->toBe(3)->and(AuditLog::query()->count())->toBe($before);
});
test('review report enforces financial-reader roles companies departments and guest protection', function () {
$this->actingAs($this->f['receiver'])->get($this->url)->assertForbidden();
$department = Department::query()->create(['tenant_id' => $this->f['tenant']->id, 'name' => 'Outro departamento']);
$head = User::factory()->create(['tenant_id' => $this->f['tenant']->id, 'department_id' => $department->id, 'purchasing_role' => PurchasingRole::DepartmentHead]);
$this->actingAs($head)->get($this->url)->assertNotFound();
$head->forceFill(['department_id' => $this->f['r']->department_id])->save();
$this->actingAs($head)->get($this->url)->assertOk();
$other = Tenant::query()->create(['name' => 'Outra empresa fictícia']);
$this->actingAs(User::factory()->create(['tenant_id' => $other->id, 'purchasing_role' => PurchasingRole::Admin]))->get($this->url)->assertNotFound();
auth()->logout();
$this->get($this->url)->assertRedirect('/login');
});
test('review report reloads cached actor access before reading business records', function () {
$this->actingAs($this->f['analyst']);
DB::table('users')->where('id', $this->f['analyst']->id)->update(['purchasing_role' => 'requester']);
$this->get($this->url)->assertForbidden();
});
test('review report omits unneeded supplier and evaluator details', function () {
$report = app(ProcurementReviewReport::class)->build($this->f['issuer'], $this->f['r']->id);
expect($report['comparison']['rows'][0]['supplier'])->toBeString()
->and($report['comparison']['rows'][0])->not->toHaveKeys(['evaluations', 'qualified_evaluations', 'items', 'beneficiaries', 'document_references', 'bank_snapshot']);
});