admin = User::factory()->create([ 'user_type' => 'admin', ]); } public function test_can_view_single_material_items_index_page(): void { Material::create([ 'name' => 'Portland Cement Type 1', 'sku' => 'MAT-CEM-001', 'category' => 'Cement & Concrete', 'unit' => 'bag', 'unit_cost' => 245.00, 'type' => 'single', 'status' => 'active', ]); $response = $this->actingAs($this->admin)->get(route('materials-catalog.items.index')); $response->assertStatus(200); $response->assertInertia(fn ($page) => $page ->component('MaterialsCatalog::Items/Index', false) ->has('items.data', 1) ); } public function test_can_store_update_and_destroy_single_material_item(): void { // 1. Store $response = $this->actingAs($this->admin)->post(route('materials-catalog.items.store'), [ 'name' => 'Deformed Steel Bar 16mm', 'sku' => 'MAT-REB-016', 'category' => 'Steel & Metals', 'unit' => 'pcs', 'unit_cost' => 485.50, 'description' => 'Grade 40 16mm x 6.0m deformed rebar', ]); $response->assertRedirect(route('materials-catalog.items.index')); $this->assertDatabaseHas('materials', [ 'name' => 'Deformed Steel Bar 16mm', 'sku' => 'MAT-REB-016', 'unit_cost' => 485.50, 'type' => 'single', ]); $item = Material::where('sku', 'MAT-REB-016')->firstOrFail(); // 2. Update $response = $this->actingAs($this->admin)->put(route('materials-catalog.items.update', $item->id), [ 'name' => 'Deformed Steel Bar 16mm - Grade 60', 'sku' => 'MAT-REB-016-G60', 'category' => 'Steel & Metals', 'unit' => 'pcs', 'unit_cost' => 520.00, 'description' => 'High tensile strength grade 60', 'status' => 'active', ]); $response->assertRedirect(route('materials-catalog.items.index')); $this->assertDatabaseHas('materials', [ 'id' => $item->id, 'name' => 'Deformed Steel Bar 16mm - Grade 60', 'unit_cost' => 520.00, ]); // 3. Destroy $response = $this->actingAs($this->admin)->delete(route('materials-catalog.items.destroy', $item->id)); $response->assertRedirect(); $this->assertDatabaseMissing('materials', [ 'id' => $item->id, ]); } public function test_can_view_assemblies_and_kits_index_page(): void { $raw1 = Material::create([ 'name' => 'Portland Cement', 'sku' => 'MAT-CEM-01', 'unit' => 'bag', 'unit_cost' => 250.00, 'type' => 'single', ]); $raw2 = Material::create([ 'name' => 'Washed Sand', 'sku' => 'MAT-SND-01', 'unit' => 'cu.m', 'unit_cost' => 1200.00, 'type' => 'single', ]); $kit = Material::create([ 'name' => 'Concrete Mix Class A (1 cu.m)', 'sku' => 'KIT-CONC-01', 'category' => 'Structural Mixes', 'unit' => 'kit', 'type' => 'kit', 'unit_cost' => 3450.00, ]); MaterialComponent::create([ 'parent_id' => $kit->id, 'component_id' => $raw1->id, 'quantity' => 9, ]); $response = $this->actingAs($this->admin)->get(route('materials-catalog.kits.index')); $response->assertStatus(200); $response->assertInertia(fn ($page) => $page ->component('MaterialsCatalog::MaterialsCatalog/Index', false) ->has('kits.data', 1) ); } public function test_can_store_update_and_destroy_assembly_kit(): void { $raw = Material::create([ 'name' => 'Standard Concrete Hollow Block 4"', 'sku' => 'MAT-CHB-04', 'unit' => 'pcs', 'unit_cost' => 18.00, 'type' => 'single', ]); // 1. Store Kit $response = $this->actingAs($this->admin)->post(route('materials-catalog.kits.store'), [ 'name' => 'Masonry Wall Assembly (10 sq.m)', 'sku' => 'KIT-MAS-10SQM', 'category' => 'Masonry', 'description' => 'CHB 4" wall assembly with mortar', 'components' => [ [ 'component_id' => $raw->id, 'quantity' => 125, ] ] ]); $response->assertRedirect(route('materials-catalog.kits.index')); $kit = Material::where('sku', 'KIT-MAS-10SQM')->firstOrFail(); $this->assertEquals(2250.00, $kit->unit_cost); // 125 * 18 = 2250 $this->assertDatabaseHas('material_components', [ 'parent_id' => $kit->id, 'component_id' => $raw->id, 'quantity' => 125, ]); // 2. Update Kit $response = $this->actingAs($this->admin)->put(route('materials-catalog.kits.update', $kit->id), [ 'name' => 'Masonry Wall Assembly Enhanced (10 sq.m)', 'sku' => 'KIT-MAS-10SQM', 'category' => 'Masonry', 'description' => 'Updated CHB with reinforcement', 'components' => [ [ 'component_id' => $raw->id, 'quantity' => 150, ] ] ]); $response->assertRedirect(route('materials-catalog.kits.index')); $kit->refresh(); $this->assertEquals(2700.00, $kit->unit_cost); // 150 * 18 = 2700 // 3. Destroy Kit $response = $this->actingAs($this->admin)->delete(route('materials-catalog.kits.destroy', $kit->id)); $response->assertRedirect(); $this->assertDatabaseMissing('materials', [ 'id' => $kit->id, ]); $this->assertDatabaseMissing('material_components', [ 'parent_id' => $kit->id, ]); } }