fix(billing): bound approved/paid amounts on claim transition (M1)
approve/pay accepted any approved_rials/paid_rials with no bounds, so the claiming tenant could write arbitrary figures into the insurer-debt ledger (negative, or far above the claimed total). Validate: approved ∈ [0, claimed], paid ∈ [0, approved] → 422 otherwise. (The "force arbitrary status" half of the finding was already prevented by Claim::canTransitionTo.) Regression: tests/Billing/ClaimAmountBoundsTest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Billing;
|
||||
|
||||
use App\Auth\Entity\User;
|
||||
use App\Billing\Entity\Claim;
|
||||
use App\Billing\Entity\ClaimItem;
|
||||
use App\Doctor\Entity\Doctor;
|
||||
use App\Tests\ApiTestCase;
|
||||
|
||||
/**
|
||||
* The claim approve/pay transition must bound the financial figures: approved
|
||||
* cannot exceed the claimed total (nor be negative). Guards the insurer-debt
|
||||
* ledger from arbitrary amounts entered by the claiming tenant.
|
||||
*/
|
||||
class ClaimAmountBoundsTest extends ApiTestCase
|
||||
{
|
||||
private Doctor $doctor;
|
||||
private User $owner;
|
||||
|
||||
private function submittedClaim(int $claimedRials): Claim
|
||||
{
|
||||
$claim = new Claim('doctor', $this->doctor->getId(), 1, 'base');
|
||||
$item = new ClaimItem($claim, 1, $claimedRials);
|
||||
$claim->addItem($item);
|
||||
$claim->submit();
|
||||
$this->em->persist($claim);
|
||||
$this->em->persist($item);
|
||||
$this->em->flush();
|
||||
|
||||
return $claim;
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->owner = $this->createUser(['ROLE_DOCTOR']);
|
||||
$this->doctor = new Doctor($this->owner, 'دکتر تست');
|
||||
$this->em->persist($this->doctor);
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
public function testApproveAboveClaimedIsRejected(): void
|
||||
{
|
||||
$claim = $this->submittedClaim(100_000);
|
||||
|
||||
$this->authJson('POST', '/api/v1/billing/claims/' . $claim->getUuid() . '/approve', $this->owner, [
|
||||
'approved_rials' => 999_999,
|
||||
]);
|
||||
|
||||
$this->assertSame(422, $this->responseCode());
|
||||
}
|
||||
|
||||
public function testApproveWithinBoundsSucceeds(): void
|
||||
{
|
||||
$claim = $this->submittedClaim(100_000);
|
||||
|
||||
$this->authJson('POST', '/api/v1/billing/claims/' . $claim->getUuid() . '/approve', $this->owner, [
|
||||
'approved_rials' => 60_000,
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $this->responseCode());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user