@@ -66,4 +66,60 @@ public function testBlockIter3(): void
6666
6767 self ::assertSame ($ iterations * 2000 , $ user ->balanceInt );
6868 }
69+
70+ /**
71+ * Tests the rollback functionality of the AtomicService.
72+ *
73+ * This test creates a new Buyer and deposits 1000 units into their wallet. Then, it attempts to
74+ * withdraw 3000 units from the wallet within an atomic block. Since there are not enough funds,
75+ * an exception is thrown. The test then checks that the balance of the wallet has not changed.
76+ */
77+ public function testRollback (): void
78+ {
79+ // Create a new instance of the AtomicService
80+ $ atomic = app (AtomicServiceInterface::class);
81+
82+ // Create a new Buyer and deposit 1000 units into their wallet
83+ /** @var Buyer $user */
84+ $ user = BuyerFactory::new ()->create ();
85+ $ user ->deposit (1000 );
86+
87+ // Check that the balance of the wallet is 1000 units
88+ $ this ->assertSame (1000 , $ user ->balanceInt );
89+
90+ try {
91+ // Start an atomic block and attempt to withdraw 3000 units from the wallet
92+ $ atomic ->block ($ user , function () use ($ user ) {
93+ // Withdraw 1000 units from the wallet
94+ $ user ->forceWithdraw (1000 );
95+ // Withdraw 1000 units from the wallet
96+ $ user ->forceWithdraw (1000 );
97+ // Withdraw 1000 units from the wallet
98+ $ user ->forceWithdraw (1000 );
99+ // Deposit 5000 units into the wallet
100+ $ user ->deposit (5000 );
101+
102+ // Throw an exception to simulate an error
103+ throw new \Exception ();
104+ });
105+
106+ // This should not be reached
107+ $ this ->assertTrue (false ); // check
108+ } catch (\Throwable $ e ) {
109+ // Intentionally left empty
110+ }
111+
112+ // Refresh the balance of the wallet to ensure it has not changed
113+ $ this ->assertTrue ($ user ->wallet ->refreshBalance ()); // check
114+
115+ // Retrieve the Buyer from the database and check that the balance is still 1000 units
116+
117+ /** @var Buyer $userFromDb */
118+ $ userFromDb = Buyer::find ($ user ->getKey ());
119+
120+ // Check that the balance of the wallet is 1000 units
121+ $ this ->assertSame (1000 , $ userFromDb ->balanceInt );
122+ // Check that the balance of the wallet is 1000 units
123+ $ this ->assertSame (1000 , $ user ->balanceInt );
124+ }
69125}
0 commit comments