Files
coruna-lab/tests/Feature/TransferRecordAdminTest.php
T
2026-10-13 02:44:36 +08:00

213 lines
7.7 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Admin;
use App\Models\Channel;
use App\Models\Device;
use App\Models\TransferRecord;
use App\Models\User;
use App\Models\WalletAddress;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class TransferRecordAdminTest extends TestCase
{
use RefreshDatabase;
#[Test]
public function admin_can_list_transfer_records(): void
{
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
TransferRecord::query()->create([
'from_address' => 'TFrom1111111111111111111111111111',
'to_address' => 'TTo222222222222222222222222222222',
'chain' => 'tron',
'tx_hash' => 'abc123',
'amount' => '10',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'USDT',
'operator' => 'tg:1',
'status' => TransferRecord::STATUS_SUCCESS,
'error' => null,
]);
$this->actingAs($admin, 'admin')
->get(route('admin.transfers.index'))
->assertOk()
->assertSee('交易记录')
->assertSee('时间范围')
->assertSee('成功归集金额')
->assertSee('手续费补足金额');
$this->actingAs($admin, 'admin')
->getJson(route('admin.transfers.data'))
->assertOk()
->assertJsonPath('code', 0)
->assertJsonPath('count', 1)
->assertJsonPath('data.0.asset', 'USDT')
->assertJsonPath('data.0.status', 'success')
->assertJsonPath('summary.totals.0.asset', 'USDT')
->assertJsonPath('summary.totals.0.amount', '10')
->assertJsonPath('summary.totals.1.asset', 'ETH')
->assertJsonPath('summary.totals.1.amount', '0');
}
#[Test]
public function transfer_summary_follows_filters_and_counts_success_only(): void
{
$admin = Admin::query()->create(['username' => 'admin-sum', 'password' => 'admin123']);
TransferRecord::query()->create([
'from_address' => 'TFromA',
'to_address' => 'TToA',
'chain' => 'tron',
'tx_hash' => 'ok-usdt',
'amount' => '12.5',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'USDT',
'operator' => 'auto',
'status' => TransferRecord::STATUS_SUCCESS,
]);
TransferRecord::query()->create([
'from_address' => '0xFromB',
'to_address' => '0xToB',
'chain' => 'eth',
'tx_hash' => 'ok-eth',
'amount' => '0.75',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'ETH',
'operator' => 'admin',
'status' => TransferRecord::STATUS_SUCCESS,
]);
TransferRecord::query()->create([
'from_address' => 'TFromC',
'to_address' => 'TToC',
'chain' => 'tron',
'tx_hash' => 'fail-usdt',
'amount' => '99',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'USDT',
'operator' => 'auto',
'status' => TransferRecord::STATUS_FAILED,
]);
TransferRecord::query()->create([
'from_address' => 'TFeeFrom',
'to_address' => 'TFeeTo',
'chain' => 'tron',
'tx_hash' => 'fee-ok',
'amount' => '20',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'TRX',
'operator' => 'fee-topup:auto',
'status' => TransferRecord::STATUS_SUCCESS,
]);
$this->actingAs($admin, 'admin')
->getJson(route('admin.transfers.data'))
->assertOk()
->assertJsonPath('summary.totals.0.asset', 'USDT')
->assertJsonPath('summary.totals.0.amount', '12.5')
->assertJsonPath('summary.totals.1.asset', 'ETH')
->assertJsonPath('summary.totals.1.amount', '0.75')
->assertJsonPath('summary.totals.2.asset', 'TRX')
->assertJsonPath('summary.totals.2.amount', '0')
->assertJsonPath('summary.fee_totals.2.asset', 'TRX')
->assertJsonPath('summary.fee_totals.2.amount', '20');
$this->actingAs($admin, 'admin')
->getJson(route('admin.transfers.data', ['asset' => 'USDT', 'status' => 'failed']))
->assertOk()
->assertJsonPath('count', 1)
->assertJsonPath('summary.totals.0.amount', '12.5')
->assertJsonPath('summary.totals.1.amount', '0');
}
#[Test]
public function transfer_summary_respects_date_range(): void
{
$admin = Admin::query()->create(['username' => 'admin-range', 'password' => 'admin123']);
$old = TransferRecord::query()->create([
'from_address' => 'TOld',
'to_address' => 'TTo',
'chain' => 'tron',
'tx_hash' => 'old',
'amount' => '20',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'USDT',
'operator' => 'auto',
'status' => TransferRecord::STATUS_SUCCESS,
]);
$old->created_at = '2026-01-01 12:00:00';
$old->save();
$fresh = TransferRecord::query()->create([
'from_address' => 'TNew',
'to_address' => 'TTo',
'chain' => 'tron',
'tx_hash' => 'new',
'amount' => '3',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'USDT',
'operator' => 'auto',
'status' => TransferRecord::STATUS_SUCCESS,
]);
$fresh->created_at = '2026-10-01 12:00:00';
$fresh->save();
$this->actingAs($admin, 'admin')
->getJson(route('admin.transfers.data', [
'date_from' => '2026-10-01',
'date_to' => '2026-10-02',
]))
->assertOk()
->assertJsonPath('count', 1)
->assertJsonPath('data.0.tx_hash', 'new')
->assertJsonPath('summary.totals.0.amount', '3');
}
#[Test]
public function agent_only_sees_transfers_for_own_channel_addresses(): void
{
$agent = User::query()->create(['username' => 'agent-tx', 'password' => 'secret12', 'status' => 1]);
$ch = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
Channel::query()->create(['channel_id' => $ch, 'user_id' => $agent->id, 'status' => 1]);
$device = Device::query()->create(['device_id' => 'dev-tx-1', 'channel_id' => $ch]);
WalletAddress::query()->create([
'device_id' => $device->id,
'address' => 'TMine3333333333333333333333333333',
'chain_type' => 'TRON',
'source' => 'trust',
]);
TransferRecord::query()->create([
'from_address' => 'TMine3333333333333333333333333333',
'to_address' => 'TTo',
'chain' => 'tron',
'tx_hash' => 'mine',
'amount' => '1',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'USDT',
'operator' => 'tg:agent',
'status' => TransferRecord::STATUS_SUCCESS,
]);
TransferRecord::query()->create([
'from_address' => 'TOther444444444444444444444444444',
'to_address' => 'TTo',
'chain' => 'tron',
'tx_hash' => 'other',
'amount' => '2',
'type' => TransferRecord::TYPE_OUT,
'asset' => 'USDT',
'operator' => 'tg:other',
'status' => TransferRecord::STATUS_SUCCESS,
]);
$this->actingAs($agent, 'agent')
->getJson(route('user.transfers.data'))
->assertOk()
->assertJsonPath('count', 1)
->assertJsonPath('data.0.tx_hash', 'mine');
}
}