refactor: add createDeveloperUser function and test to exclude developer role users from employee index display
This commit is contained in:
parent
da879eb1f3
commit
8f67a09936
@ -46,6 +46,20 @@ function createEmployeeWithProfile(): User
|
||||
return $user;
|
||||
}
|
||||
|
||||
function createDeveloperUser(): User
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
UserProfile::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'full_name' => fake()->name(),
|
||||
'phone_number' => fake()->numerify('08##########'),
|
||||
'gender' => fake()->randomElement(['male', 'female']),
|
||||
]);
|
||||
$user->assignRole('developer');
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
function validEmployeePayload(): array
|
||||
{
|
||||
return [
|
||||
@ -128,6 +142,19 @@ function validEmployeePayload(): array
|
||||
->get(route('admin.hr.employees.index', ['is_active' => '1']))
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('index does not display developer role users', function () {
|
||||
$user = createEmployeeUserWithPermission(PermissionEnum::EMPLOYEES_VIEW);
|
||||
|
||||
$developer = createDeveloperUser();
|
||||
$employee = createEmployeeWithProfile();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.hr.employees.index'))
|
||||
->assertOk()
|
||||
->assertDontSee($developer->email)
|
||||
->assertSee($employee->email);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Create ───────────────────────────────────────────────
|
||||
|
||||
595
tests/Feature/Admin/Master/RawMaterialTest.php
Normal file
595
tests/Feature/Admin/Master/RawMaterialTest.php
Normal file
@ -0,0 +1,595 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\Permission as PermissionEnum;
|
||||
use App\Enums\RawMaterialUnit;
|
||||
use App\Models\RawMaterial;
|
||||
use App\Models\RawMaterialPrice;
|
||||
use App\Models\User;
|
||||
use Database\Seeders\RolePermissionSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
$this->seed(RolePermissionSeeder::class);
|
||||
Storage::fake('public');
|
||||
});
|
||||
|
||||
// ─── Helper ───────────────────────────────────────────────
|
||||
|
||||
function createRawMaterialUserWithPermission(PermissionEnum ...$permissions): User
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
$user->givePermissionTo(
|
||||
array_merge(
|
||||
[PermissionEnum::DASHBOARD_VIEW->value],
|
||||
array_map(fn (PermissionEnum $p) => $p->value, $permissions)
|
||||
)
|
||||
);
|
||||
|
||||
$user->forgetCachedPermissions();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
function createRawMaterialWithPrices(): RawMaterial
|
||||
{
|
||||
$rawMaterial = RawMaterial::factory()->create();
|
||||
|
||||
$prices = RawMaterialPrice::factory()->count(2)->create(['raw_material_id' => $rawMaterial->id]);
|
||||
|
||||
foreach ($prices as $price) {
|
||||
$price->addMedia(UploadedFile::fake()->image("{$price->variant}.jpg", 100, 100))
|
||||
->toMediaCollection('images');
|
||||
}
|
||||
|
||||
return $rawMaterial;
|
||||
}
|
||||
|
||||
function priceWithImage(string $variant = 'Default', int $price = 50000, float $stock = 10): array
|
||||
{
|
||||
return [
|
||||
'variant' => $variant,
|
||||
'price' => $price,
|
||||
'stock' => $stock,
|
||||
'images' => [UploadedFile::fake()->image("{$variant}.jpg", 100, 100)],
|
||||
];
|
||||
}
|
||||
|
||||
// ─── Index ────────────────────────────────────────────────
|
||||
|
||||
describe('Raw Material Index', function () {
|
||||
test('authenticated user with permission can view raw material index', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.index'))
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('guest is redirected to login', function () {
|
||||
$this->get(route('admin.master.raw_materials.index'))
|
||||
->assertRedirect(route('login'));
|
||||
});
|
||||
|
||||
test('user without permission is forbidden', function () {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.index'))
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
test('index displays raw materials with prices', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
createRawMaterialWithPrices();
|
||||
createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.index'))
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('index can search raw materials by name', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
$rawMaterial = RawMaterial::factory()->create(['name' => 'Kain Batik']);
|
||||
RawMaterialPrice::factory()->create(['raw_material_id' => $rawMaterial->id]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.index', ['search' => 'Kain']))
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('index can filter by active status', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.index', ['is_active' => '1']))
|
||||
->assertOk();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Create ───────────────────────────────────────────────
|
||||
|
||||
describe('Raw Material Create', function () {
|
||||
test('authenticated user with permission can view create form', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.create'))
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('guest is redirected to login', function () {
|
||||
$this->get(route('admin.master.raw_materials.create'))
|
||||
->assertRedirect(route('login'));
|
||||
});
|
||||
|
||||
test('user without create permission is forbidden', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.create'))
|
||||
->assertForbidden();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Store ────────────────────────────────────────────────
|
||||
|
||||
describe('Raw Material Store', function () {
|
||||
test('authenticated user with permission can create a raw material', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [
|
||||
priceWithImage('Merah', 75000, 50),
|
||||
],
|
||||
])
|
||||
->assertRedirect(route('admin.master.raw_materials.index'));
|
||||
|
||||
$this->assertDatabaseHas('raw_materials', [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
]);
|
||||
});
|
||||
|
||||
test('guest cannot create a raw material', function () {
|
||||
$this->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [priceWithImage()],
|
||||
])->assertRedirect(route('login'));
|
||||
});
|
||||
|
||||
test('user without create permission is forbidden', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [priceWithImage()],
|
||||
])
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
test('name is required', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => '',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [priceWithImage()],
|
||||
])
|
||||
->assertSessionHasErrors('name');
|
||||
});
|
||||
|
||||
test('name must not exceed 200 characters', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => str_repeat('a', 201),
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [priceWithImage()],
|
||||
])
|
||||
->assertSessionHasErrors('name');
|
||||
});
|
||||
|
||||
test('unit is required', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => '',
|
||||
'prices' => [priceWithImage()],
|
||||
])
|
||||
->assertSessionHasErrors('unit');
|
||||
});
|
||||
|
||||
test('unit must be a valid enum value', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => 'invalid_unit',
|
||||
'prices' => [priceWithImage()],
|
||||
])
|
||||
->assertSessionHasErrors('unit');
|
||||
});
|
||||
|
||||
test('prices is required', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [],
|
||||
])
|
||||
->assertSessionHasErrors('prices');
|
||||
});
|
||||
|
||||
test('price variant is required', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [['variant' => '', 'price' => 50000, 'stock' => 10, 'images' => [UploadedFile::fake()->image('test.jpg')]]],
|
||||
])
|
||||
->assertSessionHasErrors('prices.0.variant');
|
||||
});
|
||||
|
||||
test('price amount is required and must be greater than 0', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [priceWithImage('Merah', 0, 10)],
|
||||
])
|
||||
->assertSessionHasErrors('prices.0.price');
|
||||
});
|
||||
|
||||
test('stock is required', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [['variant' => 'Merah', 'price' => 50000, 'stock' => '', 'images' => [UploadedFile::fake()->image('test.jpg')]]],
|
||||
])
|
||||
->assertSessionHasErrors('prices.0.stock');
|
||||
});
|
||||
|
||||
test('stock must be non-negative', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Sutra',
|
||||
'unit' => RawMaterialUnit::METER->value,
|
||||
'prices' => [priceWithImage('Merah', 50000, -5)],
|
||||
])
|
||||
->assertSessionHasErrors('prices.0.stock');
|
||||
});
|
||||
|
||||
test('creating raw material also creates prices', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_CREATE);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.master.raw_materials.store'), [
|
||||
'name' => 'Kain Premium',
|
||||
'unit' => RawMaterialUnit::YARD->value,
|
||||
'prices' => [
|
||||
priceWithImage('Merah', 75000, 50),
|
||||
priceWithImage('Biru', 80000, 30),
|
||||
],
|
||||
]);
|
||||
|
||||
$rawMaterial = RawMaterial::where('name', 'Kain Premium')->first();
|
||||
expect($rawMaterial)->not->toBeNull();
|
||||
expect($rawMaterial->prices)->toHaveCount(2);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Edit ─────────────────────────────────────────────────
|
||||
|
||||
describe('Raw Material Edit', function () {
|
||||
test('authenticated user with permission can view edit form', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.edit', $rawMaterial))
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('guest is redirected to login', function () {
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
|
||||
$this->get(route('admin.master.raw_materials.edit', $rawMaterial))
|
||||
->assertRedirect(route('login'));
|
||||
});
|
||||
|
||||
test('user without update permission is forbidden', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('admin.master.raw_materials.edit', $rawMaterial))
|
||||
->assertForbidden();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Update ───────────────────────────────────────────────
|
||||
|
||||
describe('Raw Material Update', function () {
|
||||
test('authenticated user with permission can update a raw material', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
$price = $rawMaterial->prices->first();
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('admin.master.raw_materials.update', $rawMaterial), [
|
||||
'name' => 'Nama Diubah',
|
||||
'unit' => RawMaterialUnit::KILOGRAM->value,
|
||||
'prices' => [
|
||||
['id' => $price->id, 'variant' => 'Putih', 'price' => 90000, 'stock' => 25],
|
||||
],
|
||||
])
|
||||
->assertRedirect(route('admin.master.raw_materials.index'));
|
||||
|
||||
expect($rawMaterial->fresh()->name)->toBe('Nama Diubah');
|
||||
expect($price->fresh()->variant)->toBe('Putih');
|
||||
});
|
||||
|
||||
test('guest cannot update a raw material', function () {
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
$price = $rawMaterial->prices->first();
|
||||
|
||||
$this->put(route('admin.master.raw_materials.update', $rawMaterial), [
|
||||
'name' => 'Nama Baru',
|
||||
'unit' => $rawMaterial->unit->value,
|
||||
'prices' => [['id' => $price->id, 'variant' => $price->variant, 'price' => $price->price, 'stock' => $price->stock]],
|
||||
])->assertRedirect(route('login'));
|
||||
});
|
||||
|
||||
test('user without update permission is forbidden', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
$price = $rawMaterial->prices->first();
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('admin.master.raw_materials.update', $rawMaterial), [
|
||||
'name' => 'Nama Baru',
|
||||
'unit' => $rawMaterial->unit->value,
|
||||
'prices' => [['id' => $price->id, 'variant' => $price->variant, 'price' => $price->price, 'stock' => $price->stock]],
|
||||
])
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
test('name is required on update', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
$price = $rawMaterial->prices->first();
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('admin.master.raw_materials.update', $rawMaterial), [
|
||||
'name' => '',
|
||||
'unit' => $rawMaterial->unit->value,
|
||||
'prices' => [
|
||||
['id' => $price->id, 'variant' => $price->variant, 'price' => $price->price, 'stock' => $price->stock],
|
||||
],
|
||||
])
|
||||
->assertSessionHasErrors('name');
|
||||
});
|
||||
|
||||
test('prices is required on update', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('admin.master.raw_materials.update', $rawMaterial), [
|
||||
'name' => 'Nama Bahan',
|
||||
'unit' => $rawMaterial->unit->value,
|
||||
'prices' => [],
|
||||
])
|
||||
->assertSessionHasErrors('prices');
|
||||
});
|
||||
|
||||
test('unsubmitted prices are removed on update', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_UPDATE);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
$priceToKeep = $rawMaterial->prices->first();
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('admin.master.raw_materials.update', $rawMaterial), [
|
||||
'name' => 'Updated Material',
|
||||
'unit' => $rawMaterial->unit->value,
|
||||
'prices' => [
|
||||
['id' => $priceToKeep->id, 'variant' => 'Kept', 'price' => 60000, 'stock' => 15],
|
||||
],
|
||||
]);
|
||||
|
||||
$rawMaterial->refresh();
|
||||
expect($rawMaterial->prices)->toHaveCount(1);
|
||||
expect($rawMaterial->prices->first()->variant)->toBe('Kept');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Toggle Status ────────────────────────────────────────
|
||||
|
||||
describe('Raw Material Toggle Status', function () {
|
||||
test('authenticated user with permission can toggle raw material status', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_TOGGLE_STATUS);
|
||||
|
||||
$rawMaterial = RawMaterial::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->patch(route('admin.master.raw_materials.toggle_status', $rawMaterial), [
|
||||
'is_active' => false,
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
expect($rawMaterial->fresh()->is_active)->toBeFalse();
|
||||
});
|
||||
|
||||
test('guest cannot toggle raw material status', function () {
|
||||
$rawMaterial = RawMaterial::factory()->create();
|
||||
|
||||
$this->patch(route('admin.master.raw_materials.toggle_status', $rawMaterial), [
|
||||
'is_active' => false,
|
||||
])->assertRedirect(route('login'));
|
||||
});
|
||||
|
||||
test('user without toggle permission is forbidden', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
$rawMaterial = RawMaterial::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->patch(route('admin.master.raw_materials.toggle_status', $rawMaterial), [
|
||||
'is_active' => false,
|
||||
])
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
test('is_active field is required', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_TOGGLE_STATUS);
|
||||
|
||||
$rawMaterial = RawMaterial::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->patch(route('admin.master.raw_materials.toggle_status', $rawMaterial), [
|
||||
'is_active' => null,
|
||||
])
|
||||
->assertSessionHasErrors('is_active');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Destroy ──────────────────────────────────────────────
|
||||
|
||||
describe('Raw Material Destroy', function () {
|
||||
test('authenticated user with permission can delete a raw material', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_DELETE);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('admin.master.raw_materials.destroy', $rawMaterial))
|
||||
->assertRedirect(route('admin.master.raw_materials.index'));
|
||||
|
||||
$this->assertSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);
|
||||
});
|
||||
|
||||
test('guest cannot delete a raw material', function () {
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
|
||||
$this->delete(route('admin.master.raw_materials.destroy', $rawMaterial))
|
||||
->assertRedirect(route('login'));
|
||||
|
||||
$this->assertNotSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);
|
||||
});
|
||||
|
||||
test('user without delete permission is forbidden', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('admin.master.raw_materials.destroy', $rawMaterial))
|
||||
->assertForbidden();
|
||||
|
||||
$this->assertNotSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);
|
||||
});
|
||||
|
||||
test('deleting raw material also soft deletes prices', function () {
|
||||
$user = createRawMaterialUserWithPermission(PermissionEnum::RAW_MATERIALS_VIEW, PermissionEnum::RAW_MATERIALS_DELETE);
|
||||
|
||||
$rawMaterial = createRawMaterialWithPrices();
|
||||
$priceIds = $rawMaterial->prices->pluck('id')->toArray();
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('admin.master.raw_materials.destroy', $rawMaterial));
|
||||
|
||||
$this->assertSoftDeleted('raw_materials', ['id' => $rawMaterial->id]);
|
||||
|
||||
foreach ($priceIds as $priceId) {
|
||||
$this->assertSoftDeleted('raw_material_prices', ['id' => $priceId]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Raw Material Model ───────────────────────────────────
|
||||
|
||||
describe('Raw Material Model', function () {
|
||||
test('raw material uses soft deletes', function () {
|
||||
$rawMaterial = RawMaterial::factory()->create();
|
||||
|
||||
$rawMaterial->delete();
|
||||
|
||||
expect($rawMaterial->trashed())->toBeTrue();
|
||||
});
|
||||
|
||||
test('raw material can have prices', function () {
|
||||
$rawMaterial = RawMaterial::factory()->create();
|
||||
RawMaterialPrice::factory()->count(3)->create(['raw_material_id' => $rawMaterial->id]);
|
||||
|
||||
expect($rawMaterial->fresh()->prices)->toHaveCount(3);
|
||||
});
|
||||
|
||||
test('raw material has is_active cast to boolean', function () {
|
||||
$rawMaterial = RawMaterial::factory()->create(['is_active' => true]);
|
||||
|
||||
expect($rawMaterial->is_active)->toBeTrue();
|
||||
|
||||
$rawMaterial->update(['is_active' => false]);
|
||||
|
||||
expect($rawMaterial->fresh()->is_active)->toBeFalse();
|
||||
});
|
||||
|
||||
test('raw material has unit cast to enum', function () {
|
||||
$rawMaterial = RawMaterial::factory()->create(['unit' => RawMaterialUnit::YARD->value]);
|
||||
|
||||
expect($rawMaterial->unit)->toBe(RawMaterialUnit::YARD);
|
||||
});
|
||||
|
||||
test('raw material has unit label accessor', function () {
|
||||
$rawMaterial = RawMaterial::factory()->create(['unit' => RawMaterialUnit::METER->value]);
|
||||
|
||||
expect($rawMaterial->unit_label)->toBe('Meter');
|
||||
});
|
||||
|
||||
test('raw material has unit abbreviation accessor', function () {
|
||||
$rawMaterial = RawMaterial::factory()->create(['unit' => RawMaterialUnit::KILOGRAM->value]);
|
||||
|
||||
expect($rawMaterial->unit_abbreviation)->toBe('kg');
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user