Files
lotteryLaravel/tests/Feature/PlayerRealtimeBroadcastTest.php
kang a9d0f39a9c feat: 增强开奖与设置控制器的币种支持功能
引入 CurrencyResolver,用于在 DrawCurrentController、DrawResultShowController 与 DrawResultsIndexController 中统一处理币种代码解析。
更新 DrawHallSnapshotBuilder 与 DrawResultViewService 的构建方法,新增币种代码参数支持,确保开奖相关功能中的币种处理一致性。
增强 SettingIndexController:新增允许访问的 KV 配置分组校验。
在 OddsStreamService、PlayConfigStreamService 与 RiskCapStreamService 中新增广播功能,用于在玩法目录变更时推送更新通知。
新增测试用例,验证风险限额发布的广播行为。
2026-05-27 09:57:39 +08:00

157 lines
4.9 KiB
PHP

<?php
use App\Events\BalanceUpdateBroadcast;
use App\Events\PlayCatalogUpdatedBroadcast;
use App\Events\RiskSoldOutBroadcast;
use App\Events\RiskWarningBroadcast;
use App\Services\Config\RiskCapStreamService;
use App\Models\Draw;
use App\Models\Player;
use App\Models\PlayerWallet;
use App\Models\RiskPool;
use App\Services\Ticket\RiskPoolService;
use App\Services\Wallet\LotteryTransferService;
use App\Services\Wallet\WalletBalanceRealtimeNotifier;
use Database\Seeders\CurrencySeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
uses(RefreshDatabase::class);
beforeEach(function (): void {
config(['broadcasting.default' => 'reverb']);
$this->seed(CurrencySeeder::class);
});
test('wallet balance notifier dispatches balance update broadcast', function (): void {
Event::fake([BalanceUpdateBroadcast::class]);
$player = Player::query()->create([
'site_code' => 'test',
'site_player_id' => 'ws-p1',
'username' => null,
'nickname' => null,
'default_currency' => 'NPR',
'status' => 0,
]);
$wallet = PlayerWallet::query()->create([
'player_id' => $player->id,
'wallet_type' => 'lottery',
'currency_code' => 'NPR',
'balance' => 10_000,
'frozen_balance' => 0,
'status' => 0,
'version' => 0,
]);
app(WalletBalanceRealtimeNotifier::class)->notifyAfterMovement($wallet, -500, 'bet_deduct');
Event::assertDispatched(
BalanceUpdateBroadcast::class,
fn (BalanceUpdateBroadcast $event): bool => $event->playerId === $player->id
&& $event->currencyCode === 'NPR'
&& $event->balanceMinor === 10_000
&& $event->changeMinor === -500
&& $event->reason === 'bet',
);
});
test('risk pool acquire dispatches warning and sold out broadcasts', function (): void {
Event::fake([RiskWarningBroadcast::class, RiskSoldOutBroadcast::class]);
$draw = Draw::query()->create([
'draw_no' => '20260526-001',
'business_date' => '2026-05-26',
'sequence_no' => 1,
'status' => 'open',
'start_time' => now()->subHour(),
'close_time' => now()->addHour(),
'draw_time' => now()->addHours(2),
'cooling_end_time' => null,
'result_source' => null,
'current_result_version' => 0,
'settle_version' => 0,
'is_reopened' => false,
]);
RiskPool::query()->create([
'draw_id' => $draw->id,
'normalized_number' => '1234',
'total_cap_amount' => 1000,
'locked_amount' => 750,
'remaining_amount' => 250,
'sold_out_status' => 0,
'version' => 0,
]);
app(RiskPoolService::class)->acquire($draw->id, null, [
['number_4d' => '1234', 'amount' => 250],
]);
Event::assertDispatched(
RiskWarningBroadcast::class,
fn (RiskWarningBroadcast $event): bool => $event->drawId === $draw->id
&& $event->drawNo === '20260526-001'
&& $event->normalizedNumber === '1234',
);
Event::assertDispatched(
RiskSoldOutBroadcast::class,
fn (RiskSoldOutBroadcast $event): bool => $event->drawId === $draw->id
&& $event->normalizedNumber === '1234',
);
});
test('risk cap publish dispatches play catalog updated broadcast', function (): void {
Event::fake([PlayCatalogUpdatedBroadcast::class]);
$admin = \App\Models\AdminUser::query()->create([
'username' => 'risk_cap_admin',
'name' => 'Risk Cap QA',
'email' => null,
'password' => \Illuminate\Support\Facades\Hash::make('secret-strong'),
'status' => 0,
]);
grantSuperAdminRole($admin);
$draft = app(RiskCapStreamService::class)->createDraft($admin, 'test', null);
app(RiskCapStreamService::class)->replaceItems($draft, [
[
'normalized_number' => '1234',
'cap_amount' => 1_000_000,
'cap_type' => 'default',
],
], $admin);
app(RiskCapStreamService::class)->publish($draft, $admin);
Event::assertDispatched(PlayCatalogUpdatedBroadcast::class);
});
test('transfer in dispatches balance update after success', function (): void {
Event::fake([BalanceUpdateBroadcast::class]);
$player = Player::query()->create([
'site_code' => 'test',
'site_player_id' => 'ws-p2',
'username' => null,
'nickname' => null,
'default_currency' => 'NPR',
'status' => 0,
]);
PlayerWallet::query()->create([
'player_id' => $player->id,
'wallet_type' => 'lottery',
'currency_code' => 'NPR',
'balance' => 0,
'frozen_balance' => 0,
'status' => 0,
'version' => 0,
]);
app(LotteryTransferService::class)->transferIn($player, 'NPR', 500, 'idem-ws-'.uniqid('', true));
Event::assertDispatched(BalanceUpdateBroadcast::class);
});