diff --git a/tests/Units/Service/AtomicServiceTest.php b/tests/Units/Service/AtomicServiceTest.php index 8c29cc82e..f16f5bfd4 100644 --- a/tests/Units/Service/AtomicServiceTest.php +++ b/tests/Units/Service/AtomicServiceTest.php @@ -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); + } }