110 lines
4.3 KiB
PHP
110 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\App\Libraries;
|
|
|
|
use App\Libraries\RefundEligibilityService;
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
|
|
class RefundEligibilityServiceHarness extends RefundEligibilityService
|
|
{
|
|
public function __construct(
|
|
private int $sourceCreditCents,
|
|
private int $completedPayoutCents,
|
|
private int $reservedAmountCents
|
|
) {
|
|
}
|
|
|
|
protected function calculateSourceCreditCents(int $parentId, ?int $invoiceId, string $sourceType, int $sourceId): int
|
|
{
|
|
return $this->sourceCreditCents;
|
|
}
|
|
|
|
protected function calculateCompletedPayoutCents(string $sourceType, int $sourceId, ?int $excludeRefundId): int
|
|
{
|
|
return $this->completedPayoutCents;
|
|
}
|
|
|
|
protected function calculateReservedAmountCents(string $sourceType, int $sourceId, ?int $excludeRefundId, ?int $invoiceId = null): int
|
|
{
|
|
return $this->reservedAmountCents;
|
|
}
|
|
}
|
|
|
|
class RefundEligibilityServiceTest extends CIUnitTestCase
|
|
{
|
|
public function testInvoiceOverpaymentAvailableCreditDoesNotDoubleSubtractCompletedPayouts(): void
|
|
{
|
|
$service = new RefundEligibilityServiceHarness(10000, 2500, 1500);
|
|
|
|
$result = $service->calculateAvailableCredit(10, 20, 'invoice_overpayment', 20);
|
|
|
|
$this->assertSame(10000, $result->sourceCreditCents);
|
|
$this->assertSame(0, $result->completedPayoutCents);
|
|
$this->assertSame(1500, $result->reservedAmountCents);
|
|
$this->assertSame(8500, $result->availableAmountCents);
|
|
$this->assertNotContains('HAS_COMPLETED_PAYOUTS', $result->reasonCodes);
|
|
$this->assertContains('HAS_APPROVED_RESERVATIONS', $result->reasonCodes);
|
|
}
|
|
|
|
public function testPaymentSourceAvailableCreditSubtractsCompletedPayoutsAndReservations(): void
|
|
{
|
|
$service = new RefundEligibilityServiceHarness(10000, 2500, 1500);
|
|
|
|
$result = $service->calculateAvailableCredit(10, 20, 'payment_duplicate', 77);
|
|
|
|
$this->assertSame(10000, $result->sourceCreditCents);
|
|
$this->assertSame(2500, $result->completedPayoutCents);
|
|
$this->assertSame(1500, $result->reservedAmountCents);
|
|
$this->assertSame(6000, $result->availableAmountCents);
|
|
$this->assertContains('HAS_COMPLETED_PAYOUTS', $result->reasonCodes);
|
|
$this->assertContains('HAS_APPROVED_RESERVATIONS', $result->reasonCodes);
|
|
}
|
|
|
|
public function testTuitionWithdrawalAvailableCreditUsesAdjustedInvoiceCreditWithoutDoubleSubtractingPayouts(): void
|
|
{
|
|
$service = new RefundEligibilityServiceHarness(20000, 2500, 1500);
|
|
|
|
$result = $service->calculateAvailableCredit(10, 20, 'tuition_withdrawal', 20);
|
|
|
|
$this->assertSame(20000, $result->sourceCreditCents);
|
|
$this->assertSame(0, $result->completedPayoutCents);
|
|
$this->assertSame(1500, $result->reservedAmountCents);
|
|
$this->assertSame(18500, $result->availableAmountCents);
|
|
$this->assertNotContains('HAS_COMPLETED_PAYOUTS', $result->reasonCodes);
|
|
$this->assertContains('HAS_APPROVED_RESERVATIONS', $result->reasonCodes);
|
|
}
|
|
|
|
public function testValidateRejectsAmountAboveAvailableCredit(): void
|
|
{
|
|
$service = new RefundEligibilityServiceHarness(10000, 7000, 1000);
|
|
$result = $service->calculateAvailableCredit(10, 20, 'payment_duplicate', 20);
|
|
|
|
$this->expectException(\RuntimeException::class);
|
|
$this->expectExceptionMessage('Refund amount exceeds available source credit.');
|
|
|
|
$service->validateRequestedAmount($result, 2500);
|
|
}
|
|
|
|
public function testValidateRejectsNonPositiveAmount(): void
|
|
{
|
|
$service = new RefundEligibilityServiceHarness(10000, 0, 0);
|
|
$result = $service->calculateAvailableCredit(10, 20, 'invoice_overpayment', 20);
|
|
|
|
$this->expectException(\RuntimeException::class);
|
|
$this->expectExceptionMessage('Refund amount must be greater than zero.');
|
|
|
|
$service->validateRequestedAmount($result, 0);
|
|
}
|
|
|
|
public function testZeroAvailableCreditCarriesReasonCodes(): void
|
|
{
|
|
$service = new RefundEligibilityServiceHarness(0, 0, 0);
|
|
|
|
$result = $service->calculateAvailableCredit(10, 20, 'invoice_overpayment', 20);
|
|
|
|
$this->assertSame(0, $result->availableAmountCents);
|
|
$this->assertContains('NO_SOURCE_CREDIT', $result->reasonCodes);
|
|
$this->assertContains('NO_AVAILABLE_CREDIT', $result->reasonCodes);
|
|
}
|
|
}
|