create($attrs); $batch = DrawResultBatch::query()->create([ 'draw_id' => $draw->id, 'result_version' => 1, 'source_type' => 'rng', 'rng_seed_hash' => hash('sha256', $digit), 'raw_seed_encrypted' => null, 'status' => DrawResultBatchStatus::Published->value, 'created_by' => null, 'confirmed_by' => null, 'confirmed_at' => now(), ]); DrawResultItem::query()->create([ 'draw_id' => $draw->id, 'result_batch_id' => $batch->id, 'prize_type' => 'first', 'prize_index' => 0, 'number_4d' => str_repeat($digit, 4), 'suffix_3d' => str_repeat($digit, 3), 'suffix_2d' => str_repeat($digit, 2), 'head_digit' => (int) $digit, 'tail_digit' => (int) $digit, ]); return $draw->fresh(); } test('draw results index returns published draws with PRD shaped results', function (): void { $draw = seedMinimalPublishedDraw([ 'draw_no' => '20260509-111', 'business_date' => '2026-05-09', 'sequence_no' => 111, 'status' => DrawStatus::Cooldown->value, 'start_time' => now()->subHour(), 'close_time' => now()->subMinutes(45), 'draw_time' => now()->subMinutes(30), 'cooling_end_time' => now()->addMinutes(10), 'result_source' => 'rng', 'current_result_version' => 1, 'settle_version' => 0, 'is_reopened' => false, ], '8'); $batch = DrawResultBatch::query()->where('draw_id', $draw->id)->firstOrFail(); foreach (['second', 'third'] as $tier) { DrawResultItem::query()->create([ 'draw_id' => $draw->id, 'result_batch_id' => $batch->id, 'prize_type' => $tier, 'prize_index' => 0, 'number_4d' => $tier === 'second' ? '7777' : '6666', 'suffix_3d' => '777', 'suffix_2d' => '77', 'head_digit' => 7, 'tail_digit' => 7, ]); } $this->getJson('/api/v1/draw/results?size=5') ->assertOk() ->assertJsonPath('code', 0) ->assertJsonPath('data.items.0.draw_no', '20260509-111') ->assertJsonPath('data.items.0.results.1st', '8888') ->assertJsonPath('data.items.0.results.2nd', '7777') ->assertJsonPath('data.items.0.results.3rd', '6666'); }); test('draw result show includes neighbor draw numbers', function (): void { $t0 = now()->subHours(3); seedMinimalPublishedDraw([ 'draw_no' => '20260509-100', 'business_date' => '2026-05-09', 'sequence_no' => 100, 'status' => DrawStatus::Cooldown->value, 'start_time' => $t0, 'close_time' => $t0, 'draw_time' => $t0->copy()->addSecond(), 'cooling_end_time' => null, 'result_source' => 'rng', 'current_result_version' => 1, 'settle_version' => 0, 'is_reopened' => false, ], '1'); $t1 = now()->subHours(2); seedMinimalPublishedDraw([ 'draw_no' => '20260509-101', 'business_date' => '2026-05-09', 'sequence_no' => 101, 'status' => DrawStatus::Cooldown->value, 'start_time' => $t1, 'close_time' => $t1, 'draw_time' => $t1->copy()->addSecond(), 'cooling_end_time' => null, 'result_source' => 'rng', 'current_result_version' => 1, 'settle_version' => 0, 'is_reopened' => false, ], '2'); $t2 = now()->subHour(); seedMinimalPublishedDraw([ 'draw_no' => '20260509-102', 'business_date' => '2026-05-09', 'sequence_no' => 102, 'status' => DrawStatus::Cooldown->value, 'start_time' => $t2, 'close_time' => $t2, 'draw_time' => $t2->copy()->addSecond(), 'cooling_end_time' => null, 'result_source' => 'rng', 'current_result_version' => 1, 'settle_version' => 0, 'is_reopened' => false, ], '3'); $this->getJson('/api/v1/draw/results/20260509-101') ->assertOk() ->assertJsonPath('data.previous_draw_no', '20260509-100') ->assertJsonPath('data.next_draw_no', '20260509-102'); });