Files
compras/tests/Feature/WarehouseRequestsTest.php
T
2026-11-02 08:08:05 +02:00

69 lines
4.5 KiB
PHP

<?php
use App\Models\CriticalityLevel;
use App\Models\Equipment;
use App\Models\WarehouseRequest;
use App\Services\RequisitionWorkflow;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Inertia\Testing\AssertableInertia as Assert;
require_once __DIR__.'/../Support/ReceiptFixture.php';
require_once __DIR__.'/../Support/SupplyFixture.php';
beforeEach(function () {
$this->f = receiptFixture();
supplyGrant($this->f['issuer'], ['warehouse_request_prepare']);
$this->actingAs($this->f['issuer']);
$this->data = ['operation_key' => (string) Str::uuid(), 'warehouse_id' => $this->f['warehouse']->id, 'cost_center_id' => $this->f['r']->cost_center_id,
'destination' => 'Oficina da unidade', 'reason' => 'Material para manutenção da unidade.', 'priority' => 'normal',
'lines' => [['stock_item_id' => $this->f['stock']->id, 'quantity' => '2.500', 'use' => 'internal', 'equipment_id' => null]]];
});
test('warehouse draft freezes catalogue and destination once without stock budget or purchase effects', function () {
$moves = DB::table('stock_movements')->count();
$purchases = DB::table('requisitions')->count();
$this->postJson('/stock/requisicoes', $this->data)->assertRedirect();
$this->postJson('/stock/requisicoes', $this->data)->assertRedirect();
$record = WarehouseRequest::query()->sole();
expect($record->snapshot['lines'][0]['quantity_milli'])->toBe(2500)->and($record->snapshot['lines'][0]['item']['unit'])->toBe($this->f['stock']->unit)
->and($record->snapshot['destination'])->toBe($this->data['destination'])
->and(DB::table('stock_movements')->count())->toBe($moves)->and(DB::table('requisitions')->count())->toBe($purchases)
->and(DB::table('budget_entries')->count())->toBe(0);
$this->f['stock']->update(['name' => 'Nome futuro do artigo']);
expect($record->fresh()->snapshot['lines'][0]['item']['name'])->not->toBe('Nome futuro do artigo');
$this->postJson('/stock/requisicoes', [...$this->data, 'destination' => 'Outro local'])->assertUnprocessable();
$this->get('/stock/requisicoes')->assertOk()->assertInertia(fn (Assert $p) => $p->component('stock/requests')->where('records.total', 1)->missing('records.data.0.input_hash'));
});
test('equipment destination is conditional and selected from the permitted catalogue', function () {
$this->data['lines'][0]['use'] = 'equipment';
$this->postJson('/stock/requisicoes', $this->data)->assertUnprocessable();
$level = CriticalityLevel::query()->create(['tenant_id' => $this->f['tenant']->id, 'created_by' => $this->f['issuer']->id, 'code' => 'NORMAL', 'name' => 'Normal', 'criteria' => 'Critério de teste.', 'is_critical' => false, 'created_at' => now()]);
$equipment = Equipment::query()->create(['tenant_id' => $this->f['tenant']->id, 'created_by' => $this->f['issuer']->id, 'department_id' => $this->f['issuer']->department_id,
'criticality_level_id' => $level->id, 'code' => 'EQ-1', 'description' => 'Máquina da oficina', 'area' => 'Oficina', 'status' => 'active']);
$this->data['lines'][0]['equipment_id'] = $equipment->id;
$this->postJson('/stock/requisicoes', $this->data)->assertRedirect();
expect(WarehouseRequest::query()->sole()->snapshot['lines'][0]['equipment']['code'])->toBe('EQ-1');
$this->data['operation_key'] = (string) Str::uuid();
$this->data['lines'][0]['use'] = 'internal';
$this->postJson('/stock/requisicoes', $this->data)->assertUnprocessable();
$this->data['lines'][0]['use'] = 'sale';
$this->postJson('/stock/requisicoes', $this->data)->assertUnprocessable();
});
test('warehouse draft rejects another company sources and revoked access', function () {
$foreign = receiptFixture();
$this->actingAs($this->f['issuer'])->postJson('/stock/requisicoes', [...$this->data, 'warehouse_id' => $foreign['warehouse']->id])->assertNotFound();
DB::table('organization_memberships')->where('user_id', $this->f['issuer']->id)->update(['expires_at' => now()->subMinute()]);
$this->postJson('/stock/requisicoes', $this->data)->assertForbidden();
expect(DB::table('warehouse_requests')->count())->toBe(0);
});
test('warehouse draft audit failure leaves no partial document', function () {
$this->mock(RequisitionWorkflow::class)->shouldReceive('audit')->once()->andThrow(new RuntimeException('Injected draft audit failure'));
$this->withoutExceptionHandling();
expect(fn () => $this->postJson('/stock/requisicoes', $this->data))->toThrow(RuntimeException::class);
expect(DB::table('warehouse_requests')->count())->toBe(0);
});