createMock(PromoService::class); $this->calculateService = new CalculateService($promoService); } public function testCalculateDeliveryFee() { // Test cases for delivery fee calculation $testCases = [ ['distance' => 0, 'expected' => 0.00], ['distance' => 2.5, 'expected' => 5.00], // Below 5 km: RM 5 ['distance' => 5.0, 'expected' => 7.00], // 5-6.99 km: RM 7 ['distance' => 6.99, 'expected' => 7.00], // 5-6.99 km: RM 7 ['distance' => 7.0, 'expected' => 12.00], // 7-12.99 km: RM 12 ['distance' => 10.5, 'expected' => 12.00], // 7-12.99 km: RM 12 ['distance' => 12.99, 'expected' => 12.00], // 7-12.99 km: RM 12 ['distance' => 13.0, 'expected' => 15.00], // 13-20 km: RM 15 ['distance' => 16.5, 'expected' => 15.00], // 13-20 km: RM 15 ['distance' => 20.0, 'expected' => 15.00], // 13-20 km: RM 15 ['distance' => 22.0, 'expected' => 17.00], // Above 20 km: +RM 2 for every 5 km ['distance' => 25.0, 'expected' => 17.00], // Above 20 km: +RM 2 for every 5 km ['distance' => 27.0, 'expected' => 19.00], // Above 20 km: +RM 2 for every 5 km ['distance' => 30.0, 'expected' => 19.00], // Above 20 km: +RM 2 for every 5 km ]; foreach ($testCases as $testCase) { $result = $this->calculateService->calculateDeliveryFee($testCase['distance']); $this->assertEquals( $testCase['expected'], $result, "Distance: {$testCase['distance']} km should cost RM {$testCase['expected']}, but got RM {$result}" ); } } public function testCalculateDeliveryFeeWithInvalidInput() { // Test invalid inputs $invalidInputs = [ -5.0, // Negative distance 'invalid', // String null, // Null [], // Array true, // Boolean ]; foreach ($invalidInputs as $invalidInput) { $result = $this->calculateService->calculateDeliveryFee($invalidInput); $this->assertEquals(0, $result, "Invalid input '{$invalidInput}' should return 0"); } } public function testCalculateDistanceWithInvalidInput() { // Test invalid outlet ID $result = $this->calculateService->calculateDistance('invalid', 3.123, 101.654); $this->assertEquals(0, $result, 'Invalid outlet ID should return 0'); // Test invalid coordinates $result = $this->calculateService->calculateDistance(1, 'invalid_lat', 101.654); $this->assertEquals(0, $result, 'Invalid latitude should return 0'); $result = $this->calculateService->calculateDistance(1, 3.123, 'invalid_lng'); $this->assertEquals(0, $result, 'Invalid longitude should return 0'); // Test out of range coordinates $result = $this->calculateService->calculateDistance(1, 100.0, 101.654); // Latitude > 90 $this->assertEquals(0, $result, 'Latitude > 90 should return 0'); $result = $this->calculateService->calculateDistance(1, 3.123, 200.0); // Longitude > 180 $this->assertEquals(0, $result, 'Longitude > 180 should return 0'); } public function testDeliveryFeeCalculationLogic() { // Test edge cases around the boundaries $this->assertEquals(5.00, $this->calculateService->calculateDeliveryFee(4.99), '4.99 km should be RM 5'); $this->assertEquals(7.00, $this->calculateService->calculateDeliveryFee(5.00), '5.00 km should be RM 7'); $this->assertEquals(7.00, $this->calculateService->calculateDeliveryFee(6.99), '6.99 km should be RM 7'); $this->assertEquals(12.00, $this->calculateService->calculateDeliveryFee(7.00), '7.00 km should be RM 12'); $this->assertEquals(12.00, $this->calculateService->calculateDeliveryFee(12.99), '12.99 km should be RM 12'); $this->assertEquals(15.00, $this->calculateService->calculateDeliveryFee(13.00), '13.00 km should be RM 15'); $this->assertEquals(15.00, $this->calculateService->calculateDeliveryFee(20.00), '20.00 km should be RM 15'); $this->assertEquals(17.00, $this->calculateService->calculateDeliveryFee(21.00), '21.00 km should be RM 17'); $this->assertEquals(17.00, $this->calculateService->calculateDeliveryFee(24.99), '24.99 km should be RM 17'); $this->assertEquals(19.00, $this->calculateService->calculateDeliveryFee(25.00), '25.00 km should be RM 19'); } }