AMS_Backend/tests/unit/CalculateServiceTest.php
2025-11-06 13:41:06 +08:00

106 lines
4.9 KiB
PHP

<?php
namespace Tests\Unit;
use CodeIgniter\Test\CIUnitTestCase;
use App\Services\CalculateService;
use App\Services\PromoService;
class CalculateServiceTest extends CIUnitTestCase
{
protected $calculateService;
protected function setUp(): void
{
parent::setUp();
// Mock PromoService for testing
/** @var PromoService $promoService */
$promoService = $this->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');
}
}