| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- <?php
- namespace Tests\Feature;
- use App\Models\Reservation;
- use App\Models\Role;
- use App\Models\SparePart;
- use App\Models\SparePartOrder;
- use App\Models\User;
- use Illuminate\Foundation\Testing\RefreshDatabase;
- use Tests\TestCase;
- class SparePartOrderControllerTest extends TestCase
- {
- use RefreshDatabase;
- protected $seed = true;
- private User $adminUser;
- private User $managerUser;
- protected function setUp(): void
- {
- parent::setUp();
- $this->adminUser = User::factory()->create(['role' => Role::ADMIN]);
- $this->managerUser = User::factory()->create(['role' => Role::MANAGER]);
- }
- // ==================== Authentication ====================
- public function test_guest_cannot_access_spare_part_orders_index(): void
- {
- $response = $this->get(route('spare_part_orders.index'));
- $response->assertRedirect(route('login'));
- }
- public function test_guest_cannot_access_spare_part_order_create(): void
- {
- $response = $this->get(route('spare_part_orders.create'));
- $response->assertRedirect(route('login'));
- }
- public function test_guest_cannot_store_spare_part_order(): void
- {
- $response = $this->post(route('spare_part_orders.store'), []);
- $response->assertRedirect(route('login'));
- }
- // ==================== Index ====================
- public function test_admin_can_access_spare_part_orders_index(): void
- {
- $response = $this->actingAs($this->adminUser)
- ->get(route('spare_part_orders.index'));
- $response->assertStatus(200);
- $response->assertViewIs('spare_parts.index');
- }
- public function test_manager_can_access_spare_part_orders_index(): void
- {
- $response = $this->actingAs($this->managerUser)
- ->get(route('spare_part_orders.index'));
- $response->assertStatus(200);
- $response->assertViewIs('spare_parts.index');
- }
- // ==================== Show ====================
- public function test_admin_can_view_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->actingAs($this->adminUser)
- ->get(route('spare_part_orders.show', $sparePartOrder));
- $response->assertStatus(200);
- $response->assertViewIs('spare_part_orders.edit');
- }
- public function test_manager_can_view_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->actingAs($this->managerUser)
- ->get(route('spare_part_orders.show', $sparePartOrder));
- $response->assertStatus(200);
- $response->assertViewIs('spare_part_orders.edit');
- }
- public function test_guest_cannot_view_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->get(route('spare_part_orders.show', $sparePartOrder));
- $response->assertRedirect(route('login'));
- }
- // ==================== Create ====================
- public function test_admin_can_access_create_form(): void
- {
- $response = $this->actingAs($this->adminUser)
- ->get(route('spare_part_orders.create'));
- $response->assertStatus(200);
- $response->assertViewIs('spare_part_orders.edit');
- }
- public function test_manager_can_access_create_form(): void
- {
- $response = $this->actingAs($this->managerUser)
- ->get(route('spare_part_orders.create'));
- $response->assertStatus(200);
- $response->assertViewIs('spare_part_orders.edit');
- }
- // ==================== Store ====================
- public function test_admin_can_create_spare_part_order(): void
- {
- $sparePart = SparePart::factory()->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.store'), [
- 'spare_part_id' => $sparePart->id,
- 'status' => SparePartOrder::STATUS_ORDERED,
- 'ordered_quantity' => 10,
- 'source_text' => 'Test Supplier',
- ]);
- $response->assertRedirect();
- $response->assertSessionHas('success');
- $this->assertDatabaseHas('spare_part_orders', [
- 'spare_part_id' => $sparePart->id,
- 'status' => SparePartOrder::STATUS_ORDERED,
- 'ordered_quantity' => 10,
- ]);
- }
- public function test_manager_can_create_spare_part_order(): void
- {
- $sparePart = SparePart::factory()->create();
- $response = $this->actingAs($this->managerUser)
- ->post(route('spare_part_orders.store'), [
- 'spare_part_id' => $sparePart->id,
- 'status' => SparePartOrder::STATUS_ORDERED,
- 'ordered_quantity' => 5,
- ]);
- $response->assertRedirect();
- $response->assertSessionHas('success');
- }
- public function test_store_validates_required_spare_part_id(): void
- {
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.store'), [
- 'status' => SparePartOrder::STATUS_ORDERED,
- 'ordered_quantity' => 10,
- ]);
- $response->assertSessionHasErrors('spare_part_id');
- }
- public function test_store_validates_required_ordered_quantity(): void
- {
- $sparePart = SparePart::factory()->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.store'), [
- 'spare_part_id' => $sparePart->id,
- 'status' => SparePartOrder::STATUS_ORDERED,
- ]);
- $response->assertSessionHasErrors('ordered_quantity');
- }
- // ==================== Update ====================
- public function test_admin_can_update_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->ordered()->create();
- $response = $this->actingAs($this->adminUser)
- ->put(route('spare_part_orders.update', $sparePartOrder), [
- 'spare_part_id' => $sparePartOrder->spare_part_id,
- 'status' => SparePartOrder::STATUS_ORDERED,
- 'ordered_quantity' => 20,
- 'order_number' => 'ORD-2024-001',
- ]);
- $response->assertRedirect();
- $response->assertSessionHas('success');
- $this->assertDatabaseHas('spare_part_orders', [
- 'id' => $sparePartOrder->id,
- 'ordered_quantity' => 20,
- 'order_number' => 'ORD-2024-001',
- ]);
- }
- public function test_manager_can_update_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->ordered()->create();
- $response = $this->actingAs($this->managerUser)
- ->put(route('spare_part_orders.update', $sparePartOrder), [
- 'spare_part_id' => $sparePartOrder->spare_part_id,
- 'status' => SparePartOrder::STATUS_ORDERED,
- 'ordered_quantity' => 15,
- ]);
- $response->assertRedirect();
- $response->assertSessionHas('success');
- }
- public function test_guest_cannot_update_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->put(route('spare_part_orders.update', $sparePartOrder), []);
- $response->assertRedirect(route('login'));
- }
- // ==================== Destroy ====================
- public function test_admin_can_delete_spare_part_order_without_active_reservations(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->actingAs($this->adminUser)
- ->delete(route('spare_part_orders.destroy', $sparePartOrder));
- $response->assertRedirect(route('spare_part_orders.index'));
- $response->assertSessionHas('success');
- $this->assertSoftDeleted('spare_part_orders', ['id' => $sparePartOrder->id]);
- }
- public function test_admin_cannot_delete_spare_part_order_with_active_reservations(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->create();
- Reservation::factory()->create([
- 'spare_part_order_id' => $sparePartOrder->id,
- 'spare_part_id' => $sparePartOrder->spare_part_id,
- 'status' => Reservation::STATUS_ACTIVE,
- ]);
- $response = $this->actingAs($this->adminUser)
- ->delete(route('spare_part_orders.destroy', $sparePartOrder));
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('error');
- $this->assertDatabaseHas('spare_part_orders', ['id' => $sparePartOrder->id, 'deleted_at' => null]);
- }
- public function test_manager_cannot_delete_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->actingAs($this->managerUser)
- ->delete(route('spare_part_orders.destroy', $sparePartOrder));
- $response->assertStatus(403);
- }
- public function test_guest_cannot_delete_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->delete(route('spare_part_orders.destroy', $sparePartOrder));
- $response->assertRedirect(route('login'));
- }
- // ==================== SetInStock ====================
- public function test_admin_can_set_order_in_stock(): void
- {
- $sparePartOrder = SparePartOrder::factory()->ordered()->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.set_in_stock', $sparePartOrder));
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('success');
- $this->assertDatabaseHas('spare_part_orders', [
- 'id' => $sparePartOrder->id,
- 'status' => SparePartOrder::STATUS_IN_STOCK,
- ]);
- }
- public function test_manager_can_set_order_in_stock(): void
- {
- $sparePartOrder = SparePartOrder::factory()->ordered()->create();
- $response = $this->actingAs($this->managerUser)
- ->post(route('spare_part_orders.set_in_stock', $sparePartOrder));
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('success');
- }
- public function test_guest_cannot_set_order_in_stock(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->post(route('spare_part_orders.set_in_stock', $sparePartOrder));
- $response->assertRedirect(route('login'));
- }
- // ==================== Ship ====================
- public function test_admin_can_ship_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(20)->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.ship', $sparePartOrder), [
- 'quantity' => 5,
- 'note' => 'Тестовая отгрузка',
- ]);
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('success');
- $this->assertDatabaseHas('spare_part_orders', [
- 'id' => $sparePartOrder->id,
- 'available_qty' => 15,
- ]);
- }
- public function test_ship_fails_if_quantity_exceeds_available(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(3)->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.ship', $sparePartOrder), [
- 'quantity' => 10,
- 'note' => 'Попытка отгрузить больше чем есть',
- ]);
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('error');
- $this->assertDatabaseHas('spare_part_orders', [
- 'id' => $sparePartOrder->id,
- 'available_qty' => 3,
- ]);
- }
- public function test_ship_validates_required_quantity(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.ship', $sparePartOrder), [
- 'note' => 'Без количества',
- ]);
- $response->assertSessionHasErrors('quantity');
- }
- public function test_manager_can_ship_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(10)->create();
- $response = $this->actingAs($this->managerUser)
- ->post(route('spare_part_orders.ship', $sparePartOrder), [
- 'quantity' => 2,
- 'note' => 'Отгрузка менеджером',
- ]);
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('success');
- }
- public function test_guest_cannot_ship_spare_part_order(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->post(route('spare_part_orders.ship', $sparePartOrder), [
- 'quantity' => 1,
- 'note' => 'Test',
- ]);
- $response->assertRedirect(route('login'));
- }
- // ==================== Correct (Inventory) ====================
- public function test_admin_can_correct_inventory(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(10)->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.correct', $sparePartOrder), [
- 'new_quantity' => 8,
- 'reason' => 'Инвентаризация — обнаружена недостача',
- ]);
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('success');
- $this->assertDatabaseHas('spare_part_orders', [
- 'id' => $sparePartOrder->id,
- 'available_qty' => 8,
- ]);
- }
- public function test_correct_fails_if_quantity_unchanged(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(10)->create();
- $response = $this->actingAs($this->adminUser)
- ->post(route('spare_part_orders.correct', $sparePartOrder), [
- 'new_quantity' => 10,
- 'reason' => 'Без изменений',
- ]);
- $response->assertRedirect(route('spare_part_orders.show', $sparePartOrder));
- $response->assertSessionHas('error');
- }
- public function test_manager_cannot_correct_inventory(): void
- {
- $sparePartOrder = SparePartOrder::factory()->inStock()->create();
- $response = $this->actingAs($this->managerUser)
- ->post(route('spare_part_orders.correct', $sparePartOrder), [
- 'new_quantity' => 5,
- 'reason' => 'Test',
- ]);
- $response->assertStatus(403);
- }
- public function test_guest_cannot_correct_inventory(): void
- {
- $sparePartOrder = SparePartOrder::factory()->create();
- $response = $this->post(route('spare_part_orders.correct', $sparePartOrder), [
- 'new_quantity' => 5,
- 'reason' => 'Test',
- ]);
- $response->assertRedirect(route('login'));
- }
- }
|