commit21
This commit is contained in:
@@ -9,12 +9,15 @@ use App\Models\SupplierEvaluation;
|
||||
use App\Models\User;
|
||||
use App\Services\RequisitionWorkflow;
|
||||
use App\Services\SupplierEvaluationWorkflow;
|
||||
use App\Services\WorkflowTaskInbox;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Inertia\Testing\AssertableInertia as Assert;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
require_once __DIR__.'/../Support/ReceiptFixture.php';
|
||||
require_once __DIR__.'/../Support/SupplyFixture.php';
|
||||
|
||||
beforeEach(function () {
|
||||
$this->f = receiptFixture();
|
||||
@@ -163,3 +166,96 @@ test('a newly declared process conflict prevents review of the stored evaluation
|
||||
$this->actingAs($this->reviewer)->post('/fornecedores/avaliacoes/'.$e->id.'/approve', ['version' => 2, 'reason' => 'Tentativa após declaração de conflito'])->assertForbidden();
|
||||
expect($e->refresh()->status)->toBe('review')->and($e->version)->toBe(2);
|
||||
});
|
||||
|
||||
function qualityEvaluationTasks(object $test, User $actor): array
|
||||
{
|
||||
$test->actingAs($actor);
|
||||
|
||||
return array_values(array_filter(app(WorkflowTaskInbox::class)->build($actor, 'procurement'),
|
||||
fn ($row) => str_starts_with($row['id'], 'supplier-evaluation:')));
|
||||
}
|
||||
|
||||
test('quality task follows preparation independent review return and approval', function () {
|
||||
$e = evaluationDraft($this);
|
||||
expect(qualityEvaluationTasks($this, $this->f['issuer']))->toHaveCount(1)
|
||||
->and(qualityEvaluationTasks($this, $this->reviewer))->toBe([]);
|
||||
$this->actingAs($this->f['issuer'])->post('/fornecedores/avaliacoes/'.$e->id.'/submit', ['version' => 1])->assertRedirect();
|
||||
expect(qualityEvaluationTasks($this, $this->f['issuer']))->toBe([]);
|
||||
$tasks = qualityEvaluationTasks($this, $this->reviewer);
|
||||
expect($tasks)->toHaveCount(1)->and($tasks[0]['task'])->toBe('supplier_evaluation_review')->and($tasks[0]['due_on'])->toBeNull();
|
||||
$this->get($tasks[0]['href'])->assertInertia(fn (Assert $p) => $p->where('canReview', true));
|
||||
$this->post('/fornecedores/avaliacoes/'.$e->id.'/return', ['version' => 2, 'reason' => 'Conferir novamente o âmbito e as evidências.'])->assertRedirect();
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toBe([])->and(qualityEvaluationTasks($this, $this->f['issuer']))->toHaveCount(1);
|
||||
$this->post('/fornecedores/avaliacoes/'.$e->id.'/submit', ['version' => 3])->assertRedirect();
|
||||
$this->actingAs($this->reviewer)->post('/fornecedores/avaliacoes/'.$e->id.'/approve', ['version' => 4, 'reason' => 'Âmbito e evidências conferidos independentemente.'])->assertRedirect();
|
||||
expect(qualityEvaluationTasks($this, $this->f['issuer']))->toBe([])->and(qualityEvaluationTasks($this, $this->reviewer))->toBe([]);
|
||||
$before = $e->refresh()->getAttributes();
|
||||
qualityEvaluationTasks($this, $this->reviewer);
|
||||
expect($e->fresh()->getAttributes())->toBe($before);
|
||||
});
|
||||
|
||||
test('quality task excludes all contributors after shared editing and does not publish conclusions', function () {
|
||||
$e = evaluationDraft($this);
|
||||
$this->actingAs($this->reviewer)->put('/fornecedores/avaliacoes/'.$e->id, ['version' => 1, 'payload' => [...$this->data['payload'], 'scope' => 'Âmbito corrigido por outro preparador.']])->assertRedirect();
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toHaveCount(1);
|
||||
$this->post('/fornecedores/avaliacoes/'.$e->id.'/submit', ['version' => 2])->assertRedirect();
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toBe([])->and(qualityEvaluationTasks($this, $this->f['issuer']))->toBe([]);
|
||||
$independent = User::factory()->create(['tenant_id' => $this->f['tenant']->id, 'purchasing_role' => PurchasingRole::Finance]);
|
||||
$tasks = qualityEvaluationTasks($this, $independent);
|
||||
expect($tasks)->toHaveCount(1)->and(array_key_exists('payload', $tasks[0]))->toBeFalse();
|
||||
});
|
||||
|
||||
test('quality task excludes foreign company department and current process conflict', function () {
|
||||
$e = submittedEvaluation($this);
|
||||
$other = receiptFixture();
|
||||
expect(qualityEvaluationTasks($this, $other['issuer']))->toBe([]);
|
||||
$dept = Department::query()->create(['tenant_id' => $this->f['tenant']->id, 'name' => 'Outro âmbito']);
|
||||
$head = User::factory()->create(['tenant_id' => $this->f['tenant']->id, 'department_id' => $dept->id, 'purchasing_role' => PurchasingRole::DepartmentHead]);
|
||||
expect(qualityEvaluationTasks($this, $head))->toBe([]);
|
||||
ConflictDeclaration::query()->create(['tenant_id' => $this->f['tenant']->id, 'user_id' => $this->reviewer->id, 'requisition_id' => $this->f['r']->id,
|
||||
'has_conflict' => true, 'known_since' => today()->toDateString(), 'declared_at' => now(), 'reason' => 'Conflito fictício no processo avaliado.']);
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toBe([]);
|
||||
$this->get('/fornecedores/avaliacoes/'.$e->id)->assertInertia(fn (Assert $p) => $p->where('canReview', false));
|
||||
});
|
||||
|
||||
test('quality task keeps old pending evaluations visible through pagination without writing', function () {
|
||||
$e = submittedEvaluation($this);
|
||||
for ($i = 0; $i < 104; $i++) {
|
||||
$copy = $e->replicate();
|
||||
$copy->operation_key = (string) Str::uuid();
|
||||
$copy->save();
|
||||
}
|
||||
$before = AuditLog::query()->count();
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toHaveCount(105);
|
||||
$this->get('/requisicoes/tarefas?module=purchases&search=AVA-')->assertInertia(fn (Assert $p) => $p->where('tasks.total', 105)->has('tasks.data', 25)->where('tasks.data.0.id', 'supplier-evaluation:'.$e->id.':review:2'));
|
||||
$this->get('/requisicoes/tarefas?module=purchases&search=AVA-&page=5')->assertInertia(fn (Assert $p) => $p->where('tasks.total', 105)->has('tasks.data', 5));
|
||||
expect(AuditLog::query()->count())->toBe($before);
|
||||
});
|
||||
|
||||
test('quality task blocks maintenance writes and expired memberships using current authority', function () {
|
||||
$e = submittedEvaluation($this);
|
||||
supplyGrant($this->reviewer, ['finance']);
|
||||
DB::table('organization_memberships')->where('user_id', $this->reviewer->id)->update(['maintenance' => true, 'expires_at' => now()->addHour()]);
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toBe([]);
|
||||
$this->get('/fornecedores/avaliacoes')->assertInertia(fn (Assert $p) => $p->where('canCreate', false));
|
||||
$this->get('/fornecedores/avaliacoes/'.$e->id)->assertInertia(fn (Assert $p) => $p->where('canReview', false));
|
||||
$this->post('/fornecedores/avaliacoes/'.$e->id.'/approve', ['version' => 2, 'reason' => 'Tentativa com acesso apenas para manutenção.'])->assertForbidden();
|
||||
$this->post('/fornecedores/avaliacoes', [...$this->data, 'operation_key' => (string) Str::uuid()])->assertForbidden();
|
||||
DB::table('organization_memberships')->where('user_id', $this->reviewer->id)->update(['expires_at' => now()->subMinute()]);
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toBe([])->and($e->refresh()->status)->toBe('review');
|
||||
});
|
||||
|
||||
test('quality task and commands reject a revoked role even with a previously loaded actor', function () {
|
||||
$e = submittedEvaluation($this);
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer))->toHaveCount(1);
|
||||
DB::table('users')->where('id', $this->reviewer->id)->update(['purchasing_role' => 'requester']);
|
||||
expect(qualityEvaluationTasks($this, $this->reviewer->fresh()))->toBe([]);
|
||||
$this->actingAs($this->reviewer);
|
||||
try {
|
||||
app(SupplierEvaluationWorkflow::class)->transition($this->reviewer, $e->id, 2, 'approve', 'Tentativa com instância anterior à revogação.');
|
||||
$this->fail('O papel revogado não pode decidir.');
|
||||
} catch (HttpException $exception) {
|
||||
expect($exception->getStatusCode())->toBe(403);
|
||||
}
|
||||
expect($e->refresh()->status)->toBe('review')->and($e->version)->toBe(2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user