diff --git a/tests/Feature/AdminContentTest.php b/tests/Feature/AdminContentTest.php index 9ace8a7..49765d0 100644 --- a/tests/Feature/AdminContentTest.php +++ b/tests/Feature/AdminContentTest.php @@ -407,4 +407,99 @@ class AdminContentTest extends TestCase $this->assertEquals(45, (int) Setting::get('calc_default_markup')); $this->assertEquals(8, (int) Setting::get('calc_failure_rate')); } + + public function test_3d_print_price_calculator_service_calculates_correctly(): void + { + $calculator = app(\App\Services\PriceCalculatorService::class); + + // 100 grams, 4 hours, 1 color, PLA, 40% margin + $result = $calculator->calculate( + weightGrams: 100, + printTimeHours: 4.0, + colorCount: 1, + material: 'pla', + customMarkupPercent: 40.0 + ); + + $this->assertArrayHasKey('suggested_price', $result); + $this->assertArrayHasKey('suggested_price_formatted', $result); + $this->assertArrayHasKey('breakdown', $result); + $this->assertArrayHasKey('material_cost', $result['breakdown']); + $this->assertArrayHasKey('electricity_cost', $result['breakdown']); + $this->assertArrayHasKey('machine_cost', $result['breakdown']); + $this->assertArrayHasKey('total_cost_price', $result['breakdown']); + + $this->assertGreaterThan(5.0, $result['suggested_price']); + + // Multi-color test: 4 colors should cost more than 1 color due to purge waste & setup + $multiColorResult = $calculator->calculate( + weightGrams: 100, + printTimeHours: 4.0, + colorCount: 4, + material: 'pla', + customMarkupPercent: 40.0 + ); + + $this->assertGreaterThan($result['suggested_price'], $multiColorResult['suggested_price']); + $this->assertGreaterThan($result['breakdown']['material_cost'], $multiColorResult['breakdown']['material_cost']); + } + + public function test_admin_can_use_calculate_price_api_endpoint(): void + { + $response = $this->actingAs($this->admin)->postJson(route('admin.products.calculate-price'), [ + 'weight_grams' => 120, + 'print_time_hours' => 5.5, + 'color_count' => 2, + 'material' => 'petg', + 'markup_percent' => 50, + ]); + + $response->assertStatus(200); + $response->assertJsonStructure([ + 'success', + 'data' => [ + 'inputs', + 'rates', + 'breakdown' => [ + 'effective_weight_grams', + 'material_cost', + 'electricity_cost', + 'machine_cost', + 'handling_cost', + 'failure_cost', + 'total_cost_price', + 'profit_amount', + 'price_excl_vat', + 'vat_amount', + 'price_incl_vat_exact', + ], + 'suggested_price', + 'suggested_price_formatted', + ], + ]); + } + + public function test_admin_can_save_calculator_tariffs_in_content_settings(): void + { + $response = $this->actingAs($this->admin)->post(route('admin.content.update'), [ + 'calc_filament_price_kg' => '22.50', + 'calc_electricity_kwh' => '0.40', + 'calc_printer_wattage' => '180', + 'calc_machine_hourly_rate' => '0.65', + 'calc_handling_flat' => '2.00', + 'calc_default_markup' => '45', + 'calc_failure_rate' => '8', + ]); + + $response->assertRedirect(route('admin.content.index')); + Setting::flushCache(); + + $this->assertEquals(22.50, (float) Setting::get('calc_filament_price_kg')); + $this->assertEquals(0.40, (float) Setting::get('calc_electricity_kwh')); + $this->assertEquals(180, (int) Setting::get('calc_printer_wattage')); + $this->assertEquals(0.65, (float) Setting::get('calc_machine_hourly_rate')); + $this->assertEquals(2.00, (float) Setting::get('calc_handling_flat')); + $this->assertEquals(45, (int) Setting::get('calc_default_markup')); + $this->assertEquals(8, (int) Setting::get('calc_failure_rate')); + } }