Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit. Atomic rollback #977

Merged
merged 3 commits into from
Jul 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions tests/Units/Service/AtomicServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,60 @@ public function testBlockIter3(): void

self::assertSame($iterations * 2000, $user->balanceInt);
}

/**
* Tests the rollback functionality of the AtomicService.
*
* This test creates a new Buyer and deposits 1000 units into their wallet. Then, it attempts to
* withdraw 3000 units from the wallet within an atomic block. Since there are not enough funds,
* an exception is thrown. The test then checks that the balance of the wallet has not changed.
*/
public function testRollback(): void
{
// Create a new instance of the AtomicService
$atomic = app(AtomicServiceInterface::class);

// Create a new Buyer and deposit 1000 units into their wallet
/** @var Buyer $user */
$user = BuyerFactory::new()->create();
$user->deposit(1000);

// Check that the balance of the wallet is 1000 units
$this->assertSame(1000, $user->balanceInt);

try {
// Start an atomic block and attempt to withdraw 3000 units from the wallet
$atomic->block($user, function () use ($user) {
// Withdraw 1000 units from the wallet
$user->forceWithdraw(1000);
// Withdraw 1000 units from the wallet
$user->forceWithdraw(1000);
// Withdraw 1000 units from the wallet
$user->forceWithdraw(1000);
// Deposit 5000 units into the wallet
$user->deposit(5000);

// Throw an exception to simulate an error
throw new \Exception();
});

// This should not be reached
$this->assertTrue(false); // check
} catch (\Throwable $e) {
// Intentionally left empty
}

// Refresh the balance of the wallet to ensure it has not changed
$this->assertTrue($user->wallet->refreshBalance()); // check

// Retrieve the Buyer from the database and check that the balance is still 1000 units

/** @var Buyer $userFromDb */
$userFromDb = Buyer::find($user->getKey());

// Check that the balance of the wallet is 1000 units
$this->assertSame(1000, $userFromDb->balanceInt);
// Check that the balance of the wallet is 1000 units
$this->assertSame(1000, $user->balanceInt);
}
}