Skip to content

Commit 56d8606

Browse files
committed
global upgrade; add test for multi-wallet
1 parent ac50440 commit 56d8606

File tree

7 files changed

+322
-8
lines changed

7 files changed

+322
-8
lines changed

src/Models/Wallet.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
use Bavix\Wallet\Traits\CanBePaidFloat;
88
use Bavix\Wallet\WalletProxy;
99
use Illuminate\Database\Eloquent\Model;
10-
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10+
use Illuminate\Database\Eloquent\Relations\MorphTo;
11+
use Illuminate\Support\Str;
1112

1213
/**
1314
* Class Wallet
1415
* @package Bavix\Wallet\Models
16+
* @property string $slug
1517
* @property int $balance
1618
* @property \Bavix\Wallet\Interfaces\Wallet $holder
1719
*/
@@ -51,6 +53,16 @@ public function getTable(): string
5153
return parent::getTable();
5254
}
5355

56+
/**
57+
* @param string $name
58+
* @return void
59+
*/
60+
public function setNameAttribute(string $name): void
61+
{
62+
$this->attributes['name'] = $name;
63+
$this->attributes['slug'] = Str::slug($name);
64+
}
65+
5466
/**
5567
* @return bool
5668
*/
@@ -68,11 +80,11 @@ public function calculateBalance(): bool
6880
}
6981

7082
/**
71-
* @return BelongsToMany
83+
* @return MorphTo
7284
*/
73-
public function holder(): BelongsToMany
85+
public function holder(): MorphTo
7486
{
75-
return $this->belongsToMany('holder');
87+
return $this->morphTo();
7688
}
7789

7890
}

src/Traits/HasWallet.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ protected function assemble(Wallet $wallet, Transaction $withdraw, Transaction $
175175
/**
176176
* @var Model $wallet
177177
*/
178-
return \app(config('wallet.transfer.model'))->create([
178+
return \app('bavix.wallet::transfer')->create([
179179
'deposit_id' => $deposit->getKey(),
180180
'withdraw_id' => $withdraw->getKey(),
181181
'from_type' => $this->getMorphClass(),
@@ -212,10 +212,8 @@ protected function change(int $amount, ?array $meta, bool $confirmed): Transacti
212212
$this->addBalance($wallet, $amount);
213213
}
214214

215-
return $this->transactions()->create([
215+
return $payable->transactions()->create([
216216
'type' => $amount > 0 ? 'deposit' : 'withdraw',
217-
'payable_type' => $payable->getMorphClass(),
218-
'payable_id' => $payable->getKey(),
219217
'wallet_id' => $wallet->getKey(),
220218
'uuid' => Uuid::uuid4()->toString(),
221219
'confirmed' => $confirmed,

src/Traits/HasWallets.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,26 @@ public function getWallet(string $slug): ?WalletModel
6262
return $this->_wallets[$slug];
6363
}
6464

65+
/**
66+
* @param array $data
67+
* @return WalletModel
68+
*/
69+
public function createWallet(array $data): WalletModel
70+
{
71+
/**
72+
* Create a default wallet
73+
*/
74+
$this->getBalanceAttribute();
75+
76+
/**
77+
* @var WalletModel $wallet
78+
*/
79+
$wallet = $this->wallets()->create($data);
80+
if ($this->wallets()->save($wallet)) {
81+
$this->_wallets[$wallet->slug] = $wallet;
82+
}
83+
84+
return $wallet;
85+
}
86+
6587
}

src/WalletServiceProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public function register(): void
5353
\dirname(__DIR__) . '/config/config.php',
5454
'wallet'
5555
);
56+
57+
// Bind eloquent models to IoC container
58+
$this->app->singleton('bavix.wallet::transaction', config('wallet.transaction.model'));
59+
$this->app->singleton('bavix.wallet::transfer', config('wallet.transfer.model'));
60+
$this->app->singleton('bavix.wallet::wallet', config('wallet.wallet.model'));
5661
}
5762

5863
}

tests/Models/UserMulti.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Bavix\Wallet\Test\Models;
4+
5+
use Bavix\Wallet\Interfaces\Wallet;
6+
use Bavix\Wallet\Traits\HasWallet;
7+
use Bavix\Wallet\Traits\HasWallets;
8+
use Illuminate\Database\Eloquent\Model;
9+
10+
/**
11+
* Class User
12+
*
13+
* @package Bavix\Wallet\Test\Models
14+
* @property string $name
15+
* @property string $email
16+
*/
17+
class UserMulti extends Model implements Wallet
18+
{
19+
use HasWallet, HasWallets;
20+
21+
/**
22+
* @return string
23+
*/
24+
public function getTable(): string
25+
{
26+
return 'users';
27+
}
28+
}

tests/MultiWalletTest.php

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,234 @@
22

33
namespace Bavix\Wallet\Test;
44

5+
use Bavix\Wallet\Test\Models\UserMulti;
6+
57
class MultiWalletTest extends TestCase
68
{
79

10+
/**
11+
* @return void
12+
*/
13+
public function testDeposit(): void
14+
{
15+
/**
16+
* @var UserMulti $user
17+
*/
18+
$user = factory(UserMulti::class)->create();
19+
$wallet = $user->createWallet([
20+
'name' => 'deposit'
21+
]);
22+
23+
$this->assertEquals($user->balance, 0);
24+
$this->assertEquals($wallet->balance, 0);
25+
26+
$wallet->deposit(10);
27+
$this->assertEquals($user->balance, 0);
28+
$this->assertEquals($wallet->balance, 10);
29+
30+
$wallet->deposit(125);
31+
$this->assertEquals($user->balance, 0);
32+
$this->assertEquals($wallet->balance, 135);
33+
34+
$wallet->deposit(865);
35+
$this->assertEquals($user->balance, 0);
36+
$this->assertEquals($wallet->balance, 1000);
37+
38+
$this->assertEquals($user->transactions()->count(), 3);
39+
40+
$wallet->withdraw($wallet->balance);
41+
$this->assertEquals($user->balance, 0);
42+
$this->assertEquals($wallet->balance, 0);
43+
}
44+
45+
/**
46+
* @return void
47+
* @expectedException \Bavix\Wallet\Exceptions\AmountInvalid
48+
*/
49+
public function testInvalidDeposit(): void
50+
{
51+
/**
52+
* @var UserMulti $user
53+
*/
54+
$user = factory(UserMulti::class)->create();
55+
$wallet = $user->createWallet([
56+
'name' => 'deposit'
57+
]);
58+
59+
$wallet->deposit(-1);
60+
}
61+
62+
/**
63+
* @return void
64+
* @expectedException \Bavix\Wallet\Exceptions\BalanceIsEmpty
65+
*/
66+
public function testWithdraw(): void
67+
{
68+
/**
69+
* @var UserMulti $user
70+
*/
71+
$user = factory(UserMulti::class)->create();
72+
$wallet = $user->createWallet([
73+
'name' => 'deposit'
74+
]);
75+
76+
$this->assertEquals($wallet->balance, 0);
77+
78+
$wallet->deposit(100);
79+
$this->assertEquals($wallet->balance, 100);
80+
81+
$wallet->withdraw(10);
82+
$this->assertEquals($wallet->balance, 90);
83+
84+
$wallet->withdraw(81);
85+
$this->assertEquals($wallet->balance, 9);
86+
87+
$wallet->withdraw(9);
88+
$this->assertEquals($wallet->balance, 0);
89+
90+
$wallet->withdraw(1);
91+
}
92+
93+
/**
94+
* @return void
95+
* @expectedException \Bavix\Wallet\Exceptions\BalanceIsEmpty
96+
*/
97+
public function testInvalidWithdraw(): void
98+
{
99+
/**
100+
* @var UserMulti $user
101+
*/
102+
$user = factory(UserMulti::class)->create();
103+
$wallet = $user->createWallet([
104+
'name' => 'deposit'
105+
]);
106+
107+
$wallet->withdraw(-1);
108+
}
109+
110+
/**
111+
* @return void
112+
*/
113+
public function testTransfer(): void
114+
{
115+
/**
116+
* @var UserMulti $first
117+
* @var UserMulti $second
118+
*/
119+
list($first, $second) = factory(UserMulti::class, 2)->create();
120+
$firstWallet = $first->createWallet([
121+
'name' => 'deposit'
122+
]);
123+
124+
$secondWallet = $second->createWallet([
125+
'name' => 'deposit'
126+
]);
127+
128+
$this->assertNotEquals($first->id, $second->id);
129+
$this->assertNotEquals($firstWallet->id, $secondWallet->id);
130+
$this->assertEquals($firstWallet->balance, 0);
131+
$this->assertEquals($secondWallet->balance, 0);
132+
133+
$firstWallet->deposit(100);
134+
$this->assertEquals($firstWallet->balance, 100);
135+
136+
$secondWallet->deposit(100);
137+
$this->assertEquals($secondWallet->balance, 100);
138+
139+
$firstWallet->transfer($secondWallet, 100);
140+
$this->assertEquals($first->balance, 0);
141+
$this->assertEquals($firstWallet->balance, 0);
142+
$this->assertEquals($second->balance, 0);
143+
$this->assertEquals($secondWallet->balance, 200);
144+
145+
$secondWallet->transfer($firstWallet, 100);
146+
$this->assertEquals($secondWallet->balance, 100);
147+
$this->assertEquals($firstWallet->balance, 100);
148+
149+
$secondWallet->transfer($firstWallet, 100);
150+
$this->assertEquals($secondWallet->balance, 0);
151+
$this->assertEquals($firstWallet->balance, 200);
152+
153+
$firstWallet->withdraw($firstWallet->balance);
154+
$this->assertEquals($firstWallet->balance, 0);
155+
156+
$this->assertNull($firstWallet->safeTransfer($secondWallet, 100));
157+
$this->assertEquals($firstWallet->balance, 0);
158+
$this->assertEquals($secondWallet->balance, 0);
159+
160+
$this->assertNotNull($firstWallet->forceTransfer($secondWallet, 100));
161+
$this->assertEquals($firstWallet->balance, -100);
162+
$this->assertEquals($secondWallet->balance, 100);
163+
164+
$this->assertNotNull($secondWallet->forceTransfer($firstWallet, 100));
165+
$this->assertEquals($firstWallet->balance, 0);
166+
$this->assertEquals($secondWallet->balance, 0);
167+
}
168+
169+
/**
170+
* @return void
171+
*/
172+
public function testTransferYourself(): void
173+
{
174+
/**
175+
* @var UserMulti $user
176+
*/
177+
$user = factory(UserMulti::class)->create();
178+
$wallet = $user->createWallet([
179+
'name' => 'deposit'
180+
]);
181+
182+
$this->assertEquals($wallet->balance, 0);
183+
184+
$wallet->deposit(100);
185+
$wallet->transfer($wallet, 100);
186+
$this->assertEquals($wallet->balance, 100);
187+
188+
$wallet->withdraw($wallet->balance);
189+
$this->assertEquals($wallet->balance, 0);
190+
}
191+
192+
/**
193+
* @return void
194+
* @expectedException \Bavix\Wallet\Exceptions\BalanceIsEmpty
195+
*/
196+
public function testBalanceIsEmpty(): void
197+
{
198+
/**
199+
* @var UserMulti $user
200+
*/
201+
$user = factory(UserMulti::class)->create();
202+
$wallet = $user->createWallet([
203+
'name' => 'deposit'
204+
]);
205+
206+
$this->assertEquals($wallet->balance, 0);
207+
$wallet->withdraw(1);
208+
}
209+
210+
/**
211+
* @return void
212+
*/
213+
public function testConfirmed(): void
214+
{
215+
/**
216+
* @var UserMulti $user
217+
*/
218+
$user = factory(UserMulti::class)->create();
219+
$wallet = $user->createWallet([
220+
'name' => 'deposit'
221+
]);
222+
223+
$this->assertEquals($wallet->balance, 0);
224+
225+
$wallet->deposit(1);
226+
$this->assertEquals($wallet->balance, 1);
227+
228+
$wallet->withdraw(1, null, false);
229+
$this->assertEquals($wallet->balance, 1);
230+
231+
$wallet->withdraw(1);
232+
$this->assertEquals($wallet->balance, 0);
233+
}
234+
8235
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
use Faker\Generator as Faker;
4+
use Bavix\Wallet\Test\Models\UserMulti;
5+
6+
/*
7+
|--------------------------------------------------------------------------
8+
| Model Factories
9+
|--------------------------------------------------------------------------
10+
|
11+
| This directory should contain each of the model factory definitions for
12+
| your application. Factories provide a convenient way to generate new
13+
| model instances for testing / seeding your application's database.
14+
|
15+
*/
16+
17+
$factory->define(UserMulti::class, function(Faker $faker) {
18+
return [
19+
'name' => $faker->name,
20+
'email' => $faker->unique()->safeEmail,
21+
];
22+
});

0 commit comments

Comments
 (0)