seed(CurrencySeeder::class); $this->seed(PlayTypeSeeder::class); $this->seed(OperationalConfigV1Seeder::class); $this->seed(LotterySettingsSeeder::class); }); test('jackpot summary is public', function (): void { JackpotPool::query()->create([ 'currency_code' => 'NPR', 'current_amount' => 1_234_000, 'contribution_rate' => '0.0100', 'trigger_threshold' => 0, 'payout_rate' => '0.5000', 'force_trigger_draw_gap' => 0, 'min_bet_amount' => 0, 'status' => 1, 'last_trigger_draw_id' => null, ]); $this->getJson('/api/v1/jackpot/summary?currency_code=NPR') ->assertOk() ->assertJsonPath('data.enabled', true) ->assertJsonPath('data.current_amount_minor', 1_234_000); }); test('ticket items index returns placed ticket for player', function (): void { $uniq = bin2hex(random_bytes(4)); $player = Player::query()->create([ 'site_code' => 'test', 'site_player_id' => 'items-p-'.$uniq, 'username' => 'ti_'.$uniq, 'nickname' => null, 'default_currency' => 'NPR', 'status' => 0, ]); PlayerWallet::query()->create([ 'player_id' => $player->id, 'wallet_type' => 'lottery', 'currency_code' => 'NPR', 'balance' => 5_000_000, 'frozen_balance' => 0, 'status' => 0, 'version' => 0, ]); $draw = Draw::query()->create([ 'draw_no' => '20260511-777', 'business_date' => '2026-05-11', 'sequence_no' => 777, 'status' => DrawStatus::Open->value, 'start_time' => now()->subMinutes(2), 'close_time' => now()->addMinutes(5), 'draw_time' => now()->addMinutes(6), 'cooling_end_time' => null, 'result_source' => null, 'current_result_version' => 0, 'settle_version' => 0, 'is_reopened' => false, ]); $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->postJson('/api/v1/ticket/place', [ 'draw_id' => '20260511-777', 'currency_code' => 'NPR', 'client_trace_id' => 'items-trace-1', 'lines' => [ ['number' => '1234', 'play_code' => 'big', 'amount' => 10_000], ], ]) ->assertOk(); $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->getJson('/api/v1/ticket/items') ->assertOk() ->assertJsonPath('data.total', 1) ->assertJsonPath('data.items.0.draw_no', '20260511-777') ->assertJsonPath('data.items.0.play_code', 'big'); $ticketNo = $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->getJson('/api/v1/ticket/items') ->json('data.items.0.ticket_no'); $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->getJson('/api/v1/ticket/items/'.$ticketNo) ->assertOk() ->assertJsonPath('data.ticket_no', $ticketNo) ->assertJsonPath('data.combinations.0.number_4d', '1234'); $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->getJson('/api/v1/ticket/items?draw_no='.urlencode('20260511-777')) ->assertOk() ->assertJsonPath('data.total', 1); $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->getJson('/api/v1/ticket/items?draw_no='.urlencode('20260511-000')) ->assertOk() ->assertJsonPath('data.total', 0); }); test('my-match returns hit numbers when draw published', function (): void { $uniq = bin2hex(random_bytes(4)); $player = Player::query()->create([ 'site_code' => 'test', 'site_player_id' => 'match-p-'.$uniq, 'username' => 'tm_'.$uniq, 'nickname' => null, 'default_currency' => 'NPR', 'status' => 0, ]); PlayerWallet::query()->create([ 'player_id' => $player->id, 'wallet_type' => 'lottery', 'currency_code' => 'NPR', 'balance' => 5_000_000, 'frozen_balance' => 0, 'status' => 0, 'version' => 0, ]); $draw = Draw::query()->create([ 'draw_no' => '20260511-778', 'business_date' => '2026-05-11', 'sequence_no' => 778, 'status' => DrawStatus::Open->value, 'start_time' => now()->subMinutes(2), 'close_time' => now()->addMinutes(5), 'draw_time' => now()->addMinutes(6), 'cooling_end_time' => null, 'result_source' => null, 'current_result_version' => 0, 'settle_version' => 0, 'is_reopened' => false, ]); $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->postJson('/api/v1/ticket/place', [ 'draw_id' => '20260511-778', 'currency_code' => 'NPR', 'client_trace_id' => 'match-trace-1', 'lines' => [ ['number' => '1234', 'play_code' => 'big', 'amount' => 10_000], ], ]) ->assertOk(); $batch = DrawResultBatch::query()->create([ 'draw_id' => $draw->id, 'result_version' => 1, 'source_type' => 'rng', 'rng_seed_hash' => 'test', 'raw_seed_encrypted' => null, 'status' => DrawResultBatchStatus::Published->value, 'created_by' => null, 'confirmed_by' => null, 'confirmed_at' => now(), ]); foreach (DrawPrizeLayout::slots() as $slot) { $num = $slot['prize_type'] === 'first' ? '1234' : '5678'; DrawResultItem::query()->create([ 'draw_id' => $draw->id, 'result_batch_id' => $batch->id, 'prize_type' => $slot['prize_type'], 'prize_index' => $slot['prize_index'], 'number_4d' => $num, 'suffix_3d' => substr($num, -3), 'suffix_2d' => substr($num, -2), 'head_digit' => (int) substr($num, 0, 1), 'tail_digit' => (int) substr($num, 3, 1), ]); } $draw->forceFill([ 'status' => DrawStatus::Cooldown->value, 'current_result_version' => 1, ])->save(); $this->withHeader('Authorization', 'Bearer dev:'.$player->id) ->getJson('/api/v1/ticket/draws/20260511-778/my-match') ->assertOk() ->assertJsonPath('data.has_bets', true) ->assertJsonPath('data.hit_numbers_4d', ['1234']); });