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']); });