feat: autotransfer
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Admin;
|
||||
use App\Models\Channel;
|
||||
use App\Models\Device;
|
||||
use App\Models\User;
|
||||
use App\Models\WalletAddress;
|
||||
use App\Models\WalletMnemonic;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Tests\TestCase;
|
||||
|
||||
class MnemonicWalletsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
private function storeMnemonic(Device $device, string $source = 'imToken'): WalletMnemonic
|
||||
{
|
||||
$row = new WalletMnemonic([
|
||||
'device_id' => $device->id,
|
||||
'source' => $source,
|
||||
]);
|
||||
$row->mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
$row->save();
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function wallets_endpoint_returns_linked_address_balances(): void
|
||||
{
|
||||
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
|
||||
$device = Device::query()->create(['device_id' => 'dev-mn-wallets']);
|
||||
$mnemonic = $this->storeMnemonic($device);
|
||||
|
||||
WalletAddress::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'address' => 'TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH',
|
||||
'chain_type' => 'TRON',
|
||||
'source' => 'imToken',
|
||||
'mnemonic_id' => $mnemonic->id,
|
||||
'derive_index' => 0,
|
||||
'usdt' => 12.5,
|
||||
'trx' => 3.1,
|
||||
]);
|
||||
WalletAddress::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'address' => '0x9858effd232b4033e47d90003d41ec34ecaeda94',
|
||||
'chain_type' => 'ETH',
|
||||
'source' => 'imToken',
|
||||
'mnemonic_id' => $mnemonic->id,
|
||||
'derive_index' => 0,
|
||||
'eth' => 1.25,
|
||||
]);
|
||||
WalletAddress::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'address' => 'unlinked-addr',
|
||||
'chain_type' => 'BTC',
|
||||
'source' => 'imToken',
|
||||
'btc' => 9,
|
||||
]);
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->getJson(route('admin.mnemonics.wallets', $mnemonic))
|
||||
->assertOk()
|
||||
->assertJsonPath('code', 0)
|
||||
->assertJsonPath('data.mnemonic_id', $mnemonic->id)
|
||||
->assertJsonPath('data.addresses.0.address', 'TUEZSdKsoDHQMeZwihtdoBiN46zxhGWYdH')
|
||||
->assertJsonPath('data.addresses.0.usdt', '12.5')
|
||||
->assertJsonPath('data.addresses.0.trx', '3.1')
|
||||
->assertJsonPath('data.addresses.1.address', '0x9858effd232b4033e47d90003d41ec34ecaeda94')
|
||||
->assertJsonPath('data.addresses.1.eth', '1.25')
|
||||
->assertJsonCount(2, 'data.addresses');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function wallets_endpoint_respects_agent_scope(): void
|
||||
{
|
||||
$agent = User::query()->create(['username' => 'agent-w', 'password' => 'secret12', 'status' => 1]);
|
||||
$chA = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
$chB = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
|
||||
Channel::query()->create(['channel_id' => $chA, 'user_id' => $agent->id, 'status' => 1]);
|
||||
Channel::query()->create(['channel_id' => $chB, 'user_id' => Channel::OFFICIAL_USER_ID, 'status' => 1]);
|
||||
|
||||
$mine = Device::query()->create(['device_id' => 'dev-mine', 'channel_id' => $chA]);
|
||||
$other = Device::query()->create(['device_id' => 'dev-other', 'channel_id' => $chB]);
|
||||
$mnMine = $this->storeMnemonic($mine);
|
||||
$mnOther = $this->storeMnemonic($other, 'Trust');
|
||||
|
||||
$this->actingAs($agent, 'agent')
|
||||
->getJson(route('user.mnemonics.wallets', $mnMine))
|
||||
->assertOk()
|
||||
->assertJsonPath('code', 0);
|
||||
|
||||
$this->actingAs($agent, 'agent')
|
||||
->getJson(route('user.mnemonics.wallets', $mnOther))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function mnemonic_list_includes_wallets_url(): void
|
||||
{
|
||||
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
|
||||
$device = Device::query()->create(['device_id' => 'dev-mn-list']);
|
||||
$mnemonic = $this->storeMnemonic($device);
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->getJson(route('admin.mnemonics.data'))
|
||||
->assertOk()
|
||||
->assertJsonPath('data.0.id', $mnemonic->id)
|
||||
->assertJsonPath('data.0.wallets_url', route('admin.mnemonics.wallets', $mnemonic))
|
||||
->assertJsonPath('data.0.refresh_url', route('admin.mnemonics.wallets.refresh', $mnemonic));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function refresh_updates_linked_balances_and_throttles(): void
|
||||
{
|
||||
Http::fake([
|
||||
'*/v1/accounts/*' => Http::response([
|
||||
'data' => [[
|
||||
'balance' => 2_000_000,
|
||||
'trc20' => [
|
||||
['TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t' => '5000000'],
|
||||
],
|
||||
]],
|
||||
'success' => true,
|
||||
], 200),
|
||||
]);
|
||||
|
||||
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
|
||||
$device = Device::query()->create(['device_id' => 'dev-mn-refresh']);
|
||||
$mnemonic = $this->storeMnemonic($device);
|
||||
$addr = WalletAddress::query()->create([
|
||||
'device_id' => $device->id,
|
||||
'address' => 'TKKyetwdwuv6fTWVMPsdQUZYwB7yiNwRp6',
|
||||
'chain_type' => 'TRON',
|
||||
'source' => 'imToken',
|
||||
'mnemonic_id' => $mnemonic->id,
|
||||
'usdt' => 0,
|
||||
'trx' => 0,
|
||||
]);
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->postJson(route('admin.mnemonics.wallets.refresh', $mnemonic))
|
||||
->assertOk()
|
||||
->assertJsonPath('code', 0)
|
||||
->assertJsonPath('data.refreshed', 1)
|
||||
->assertJsonPath('data.addresses.0.trx', '2')
|
||||
->assertJsonPath('data.addresses.0.usdt', '5');
|
||||
|
||||
$addr->refresh();
|
||||
$this->assertEqualsWithDelta(2.0, (float) $addr->trx, 0.0000001);
|
||||
$this->assertEqualsWithDelta(5.0, (float) $addr->usdt, 0.0000001);
|
||||
|
||||
$this->actingAs($admin, 'admin')
|
||||
->postJson(route('admin.mnemonics.wallets.refresh', $mnemonic))
|
||||
->assertStatus(429)
|
||||
->assertJsonPath('code', 1)
|
||||
->assertJsonStructure(['data' => ['retry_after']]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user