95 lines
3.0 KiB
PHP
95 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\App\Services;
|
|
|
|
use App\Services\FeeCalculationService;
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
|
|
class FeeCalculationServiceRefundAdapterHarness extends FeeCalculationService
|
|
{
|
|
public array $previewedEnrollmentIds = [];
|
|
|
|
public function __construct(private array $latestByEnrollment, private array $previewByEnrollment)
|
|
{
|
|
}
|
|
|
|
protected function latestWithdrawalCalculation(int $enrollmentId): ?array
|
|
{
|
|
return $this->latestByEnrollment[$enrollmentId] ?? null;
|
|
}
|
|
|
|
protected function previewWithdrawalCalculation(int $enrollmentId): array
|
|
{
|
|
$this->previewedEnrollmentIds[] = $enrollmentId;
|
|
return $this->previewByEnrollment[$enrollmentId] ?? ['new_refund_request_cents' => 0];
|
|
}
|
|
}
|
|
|
|
class FeeCalculationServiceTest extends CIUnitTestCase
|
|
{
|
|
public function testRefundAdapterUsesWithdrawalFinancialPreviewAmounts(): void
|
|
{
|
|
$service = new FeeCalculationServiceRefundAdapterHarness(
|
|
latestByEnrollment: [
|
|
10 => ['status' => 'preview', 'new_refund_request_cents' => 12345],
|
|
11 => ['status' => 'superseded', 'new_refund_request_cents' => 99999],
|
|
],
|
|
previewByEnrollment: [
|
|
11 => ['status' => 'preview', 'new_refund_request_cents' => 500],
|
|
]
|
|
);
|
|
|
|
$refund = $service->calculateRefund([
|
|
['id' => 10, 'parent_id' => 8, 'enrollment_status' => 'withdraw under review'],
|
|
['id' => 11, 'parent_id' => 8, 'enrollment_status' => 'refund pending'],
|
|
['id' => 12, 'parent_id' => 8, 'enrollment_status' => 'enrolled'],
|
|
['id' => 13, 'parent_id' => 9, 'enrollment_status' => 'refund pending'],
|
|
], 8);
|
|
|
|
$this->assertSame(128.45, $refund);
|
|
$this->assertSame([11], $service->previewedEnrollmentIds);
|
|
}
|
|
|
|
public function testRefundReversesLatestTuitionTierFirst(): void
|
|
{
|
|
$fees = $this->refundFeeStack(3, 2, 380.0, 280.0);
|
|
|
|
$this->assertSame([280.0], $fees);
|
|
}
|
|
|
|
public function testRefundKeepsReversingAdditionalFeesBeforeFirstStudentFee(): void
|
|
{
|
|
$fees = $this->refundFeeStack(3, 0, 380.0, 280.0);
|
|
|
|
$this->assertSame([280.0, 280.0, 380.0], $fees);
|
|
}
|
|
|
|
public function testSingleStudentWithdrawalRefundsFirstStudentFee(): void
|
|
{
|
|
$fees = $this->refundFeeStack(1, 0, 380.0, 280.0);
|
|
|
|
$this->assertSame([380.0], $fees);
|
|
}
|
|
|
|
/**
|
|
* @return array<int,float>
|
|
*/
|
|
private function refundFeeStack(
|
|
int $originalStudentCount,
|
|
int $remainingStudentCount,
|
|
float $firstStudentFee,
|
|
float $additionalStudentFee
|
|
): array {
|
|
$method = new \ReflectionMethod(FeeCalculationService::class, 'reverseTuitionRefundFeeStack');
|
|
$method->setAccessible(true);
|
|
|
|
return $method->invoke(
|
|
new FeeCalculationService(),
|
|
$originalStudentCount,
|
|
$remainingStudentCount,
|
|
$firstStudentFee,
|
|
$additionalStudentFee
|
|
);
|
|
}
|
|
}
|