commit14
This commit is contained in:
@@ -12,11 +12,13 @@ use App\Models\Tenant;
|
||||
use App\Models\User;
|
||||
use App\Services\DocumentaryQualificationWorkflow;
|
||||
use App\Services\FormalAdmission;
|
||||
use App\Services\ProposalOpeningWorkflow;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Testing\AssertableInertia as Assert;
|
||||
|
||||
require_once __DIR__.'/../Support/AdmissionFixture.php';
|
||||
require_once __DIR__.'/../Support/SupplyFixture.php';
|
||||
|
||||
beforeEach(function () {
|
||||
$this->f = admissionFixture();
|
||||
@@ -166,3 +168,71 @@ test('active process conflict prevents conference without creating approval', fu
|
||||
$this->actingAs($this->f['analyst'])->post('/admissoes/'.$decision->id.'/conferir', ['verdict' => 'approved', 'reason' => 'Conferência bloqueada por conflito'])->assertSessionHasErrors('conflict');
|
||||
expect(AdmissionReview::query()->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('formal task admission follows the adopted quorum and removes only the completed personal intervention', function () {
|
||||
$decision = admissionAttempt($this);
|
||||
$path = '/requisicoes/tarefas?module=purchases&search=admissão';
|
||||
$this->actingAs($this->f['analyst'])->get($path)->assertInertia(fn (Assert $page) => $page->where('tasks.total', 1)
|
||||
->where('tasks.data.0.href', $this->url.'?version='.$this->f['adoption']->id.'&decision_id='.$decision->id.'#admission-'.$decision->id)
|
||||
->missing('tasks.data.0.snapshot')->missing('tasks.data.0.reason')->missing('tasks.data.0.basis_hash'));
|
||||
$this->get($this->url.'?decision_id='.$decision->id)->assertInertia(fn (Assert $page) => $page->where('focusDecisionId', $decision->id)->where('history.data.0.canReview', true));
|
||||
// A different company policy does not replace the process's adopted quorum/roles.
|
||||
$this->actingAs($this->f['admin']);
|
||||
app(FormalAdmission::class)->policy($this->f['admin'], [...$this->f['policy_data'], 'previous_id' => $this->f['policy']->id, 'roles' => ['department_head'], 'required_count' => 1]);
|
||||
admissionConfer($this, $decision);
|
||||
$this->get($path)->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0));
|
||||
expect(app(FormalAdmission::class)->status($decision, $this->f['adoption']))->toBe('pending');
|
||||
$this->actingAs($this->f['other_analyst'])->get($path)->assertInertia(fn (Assert $page) => $page->where('tasks.total', 1));
|
||||
admissionConfer($this, $decision, $this->f['other_analyst']);
|
||||
$this->get($path)->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0));
|
||||
expect(AdmissionReview::query()->count())->toBe(2)->and(BudgetEntry::query()->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('formal task admission retains an older current decision and opens it beyond the first history page', function () {
|
||||
$supplier = $this->f['quote']->supplier->replicate();
|
||||
$supplier->fill(['nuit' => '987654321', 'name' => 'Segundo fornecedor fictício'])->save();
|
||||
$quote = $this->f['quote']->replicate();
|
||||
$quote->fill(['supplier_id' => $supplier->id, 'reference' => 'SEGUNDA-FICTICIA'])->save();
|
||||
$this->actingAs($this->f['issuer']);
|
||||
$opening = app(ProposalOpeningWorkflow::class);
|
||||
$set = app(DocumentaryQualificationWorkflow::class)->define($this->f['issuer'], $this->f['r'], [...$this->f['definition'], 'previous_id' => $this->f['set']->id, 'basis_hash' => $opening->basis($opening->proposals($this->f['r']))]);
|
||||
$this->actingAs($this->f['analyst']);
|
||||
foreach ([$this->f['quote'], $quote] as $candidate) {
|
||||
app(DocumentaryQualificationWorkflow::class)->assess($this->f['analyst'], $set, [...$this->f['assessment'], 'quotation_id' => $candidate->id]);
|
||||
}
|
||||
$service = app(FormalAdmission::class);
|
||||
$first = admissionAttempt($this, ['basis_hash' => $service->basis($this->f['r'], $this->f['quote']->id)['hash']]);
|
||||
$previous = 0;
|
||||
for ($index = 0; $index < 15; $index++) {
|
||||
$next = admissionAttempt($this, ['quotation_id' => $quote->id, 'previous_id' => $previous, 'basis_hash' => $service->basis($this->f['r'], $quote->id)['hash']]);
|
||||
$previous = $next->id;
|
||||
}
|
||||
$this->actingAs($this->f['other_analyst'])->get($this->url)->assertInertia(fn (Assert $page) => $page->where('history.total', 16)->where('history.data.0.id', $next->id));
|
||||
$this->get('/requisicoes/tarefas?module=purchases&search=admissão')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 2)->where('tasks.data.0.id', 'admission:'.$first->id.':review'));
|
||||
$this->get($this->url.'?version='.$this->f['adoption']->id.'&decision_id='.$first->id)->assertInertia(fn (Assert $page) => $page->where('history.total', 1)->where('history.data.0.id', $first->id)->where('history.data.0.canReview', true));
|
||||
});
|
||||
|
||||
test('formal task admission respects changed bases conflicts and consultation never records a decision', function () {
|
||||
$decision = admissionAttempt($this);
|
||||
$this->actingAs($this->f['analyst']);
|
||||
$before = [DB::table('admission_reviews')->count(), DB::table('audit_logs')->count(), DB::table('admission_decisions')->get()->toArray()];
|
||||
$this->get('/requisicoes/tarefas?module=purchases&search=admissão')->assertOk();
|
||||
$this->get($this->url.'?decision_id='.$decision->id)->assertOk();
|
||||
expect([DB::table('admission_reviews')->count(), DB::table('audit_logs')->count(), DB::table('admission_decisions')->get()->toArray()])->toEqual($before);
|
||||
ConflictDeclaration::query()->create(['tenant_id' => $this->f['tenant']->id, 'user_id' => $this->f['analyst']->id, 'requisition_id' => $this->f['r']->id, 'has_conflict' => true, 'known_since' => today()->toDateString(), 'declared_at' => now(), 'reason' => 'Conflito sintético impeditivo.']);
|
||||
$this->get('/requisicoes/tarefas?module=purchases&search=admissão')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0));
|
||||
$this->get($this->url.'?decision_id='.$decision->id)->assertInertia(fn (Assert $page) => $page->where('history.data.0.canReview', false));
|
||||
$this->f['quote']->update(['reference' => 'BASE-ALTERADA']);
|
||||
expect(app(FormalAdmission::class)->currentReviewBasis($this->f['r'], $this->f['adoption'], $decision))->toBeFalse();
|
||||
});
|
||||
|
||||
test('formal task admission cannot grant review to maintenance or focus another adoption', function () {
|
||||
$decision = admissionAttempt($this);
|
||||
supplyGrant($this->f['analyst'], ['finance']);
|
||||
DB::table('organization_memberships')->where('user_id', $this->f['analyst']->id)->update(['maintenance' => true, 'expires_at' => now()->addHour()]);
|
||||
$this->actingAs($this->f['analyst'])->get('/requisicoes/tarefas?module=purchases&search=admissão')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0));
|
||||
$this->get($this->url.'?decision_id='.$decision->id)->assertInertia(fn (Assert $page) => $page->where('history.data.0.canReview', false)->where('canPropose', false)->where('canAdopt', false));
|
||||
$this->post('/admissoes/'.$decision->id.'/conferir', ['verdict' => 'approved', 'reason' => 'Não executar em manutenção.'])->assertForbidden();
|
||||
expect(AdmissionReview::query()->count())->toBe(0);
|
||||
$this->getJson($this->url.'?decision_id=999999')->assertUnprocessable();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user