144 lines
5.2 KiB
PHP
144 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace Modules\MaterialLogistics\Http\Controllers {
|
|
/**
|
|
* Namespaced function override to mock extension_loaded for fileinfo.
|
|
*/
|
|
function extension_loaded($name) {
|
|
if ($name === 'fileinfo' && isset($GLOBALS['mock_fileinfo_disabled']) && $GLOBALS['mock_fileinfo_disabled'] === true) {
|
|
return false;
|
|
}
|
|
return \extension_loaded($name);
|
|
}
|
|
}
|
|
|
|
namespace Tests\Feature {
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Modules\MaterialLogistics\Models\PurchaseOrder;
|
|
use Modules\MaterialLogistics\Models\Warehouse;
|
|
use Spatie\Permission\Models\Role;
|
|
use Tests\TestCase;
|
|
|
|
class PurchaseOrderReceiptUploadTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected User $user;
|
|
protected PurchaseOrder $purchaseOrder;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
// Create admin user
|
|
$this->user = User::factory()->create([
|
|
'status' => 'active',
|
|
'user_type' => 'admin',
|
|
]);
|
|
|
|
// Create required permission and assign to user
|
|
\Spatie\Permission\Models\Permission::firstOrCreate(['name' => 'inventory.access']);
|
|
$this->user->givePermissionTo('inventory.access');
|
|
|
|
// Create target warehouse
|
|
$warehouse = Warehouse::create([
|
|
'name' => 'Main Storage Warehouse',
|
|
'code' => 'WH-TEST-01',
|
|
'address' => 'Test Location',
|
|
'type' => 'main',
|
|
'status' => 'active',
|
|
]);
|
|
|
|
// Create approved PO
|
|
$this->purchaseOrder = PurchaseOrder::create([
|
|
'document_number' => 'PO-2026-0001',
|
|
'supplier' => 'Acme Supplies',
|
|
'status' => 'approved',
|
|
'payment_status' => 'unpaid',
|
|
'target_warehouse_id' => $warehouse->id,
|
|
'requested_by' => $this->user->id,
|
|
]);
|
|
|
|
// Reset fileinfo mock global
|
|
unset($GLOBALS['mock_fileinfo_disabled']);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
unset($GLOBALS['mock_fileinfo_disabled']);
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function test_can_upload_receipt_and_mark_po_as_paid_with_fileinfo(): void
|
|
{
|
|
Storage::fake('public');
|
|
|
|
$file = UploadedFile::fake()->create('receipt.pdf', 500, 'application/pdf');
|
|
|
|
$response = $this->actingAs($this->user)
|
|
->from(route('purchase-orders.show', $this->purchaseOrder))
|
|
->post(route('purchase-orders.pay', $this->purchaseOrder), [
|
|
'receipt' => $file,
|
|
]);
|
|
|
|
$response->assertRedirect(route('purchase-orders.show', $this->purchaseOrder));
|
|
$response->assertSessionHas('success');
|
|
|
|
$this->purchaseOrder->refresh();
|
|
$this->assertEquals('paid', $this->purchaseOrder->payment_status->value);
|
|
$this->assertNotNull($this->purchaseOrder->receipt_path);
|
|
$this->assertEquals('receipt.pdf', $this->purchaseOrder->receipt_original_name);
|
|
|
|
// Assert file exists on storage
|
|
Storage::disk('public')->assertExists($this->purchaseOrder->receipt_path);
|
|
}
|
|
|
|
public function test_can_upload_receipt_and_mark_po_as_paid_without_fileinfo(): void
|
|
{
|
|
// Enable fileinfo missing mock
|
|
$GLOBALS['mock_fileinfo_disabled'] = true;
|
|
|
|
Storage::fake('public');
|
|
|
|
$file = UploadedFile::fake()->create('receipt.pdf', 500, 'application/pdf');
|
|
|
|
$response = $this->actingAs($this->user)
|
|
->from(route('purchase-orders.show', $this->purchaseOrder))
|
|
->post(route('purchase-orders.pay', $this->purchaseOrder), [
|
|
'receipt' => $file,
|
|
]);
|
|
|
|
$response->assertRedirect(route('purchase-orders.show', $this->purchaseOrder));
|
|
$response->assertSessionHas('success');
|
|
|
|
$this->purchaseOrder->refresh();
|
|
$this->assertEquals('paid', $this->purchaseOrder->payment_status->value);
|
|
$this->assertNotNull($this->purchaseOrder->receipt_path);
|
|
$this->assertEquals('receipt.pdf', $this->purchaseOrder->receipt_original_name);
|
|
|
|
// Assert file exists on storage
|
|
Storage::disk('public')->assertExists($this->purchaseOrder->receipt_path);
|
|
}
|
|
|
|
public function test_rejects_invalid_mime_type_extension_without_fileinfo(): void
|
|
{
|
|
$GLOBALS['mock_fileinfo_disabled'] = true;
|
|
|
|
$file = UploadedFile::fake()->create('receipt.txt', 10, 'text/plain');
|
|
|
|
$response = $this->actingAs($this->user)
|
|
->from(route('purchase-orders.show', $this->purchaseOrder))
|
|
->post(route('purchase-orders.pay', $this->purchaseOrder), [
|
|
'receipt' => $file,
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('receipt');
|
|
$this->assertEquals('unpaid', $this->purchaseOrder->refresh()->payment_status->value);
|
|
}
|
|
}
|
|
}
|