'horse_racing'], [ 'name' => 'Horse Racing', 'icon' => 'horse', 'description' => 'Horse Racing Game', 'enabled' => true, 'params' => [ 'min_bet' => 100, 'max_bet' => 100000, 'house_take_percent' => 5, ], ] ); } public function test_can_get_current_race() { /** @var \App\Models\User $user */ $user = User::factory()->create(); $race = HorseRace::create([ 'status' => 'betting', 'bet_opens_at' => now(), 'bet_closes_at' => now()->addMinutes(1), 'horses' => [ ['id' => 1, 'name' => 'Horse A', 'emoji' => '🐎'], ['id' => 2, 'name' => 'Horse B', 'emoji' => '🏇'], ], 'total_bets' => 0, 'total_pool' => 0, ]); $response = $this->actingAs($user)->getJson(route('horse-race.current')); $response->assertStatus(200); $response->assertJsonStructure(['race' => ['id', 'status', 'bet_closes_at', 'horses']]); $this->assertEquals($race->id, $response->json('race.id')); } public function test_can_bet() { Event::fake(); /** @var \App\Models\User $user */ $user = User::factory()->create(['jjb' => 500]); $race = HorseRace::create([ 'status' => 'betting', 'bet_opens_at' => now(), 'bet_closes_at' => now()->addMinutes(1), 'horses' => [ ['id' => 1, 'name' => 'Horse A', 'emoji' => '🐎'], ['id' => 2, 'name' => 'Horse B', 'emoji' => '🏇'], ], 'total_bets' => 0, 'total_pool' => 0, ]); $response = $this->actingAs($user)->postJson(route('horse-race.bet'), [ 'race_id' => $race->id, 'horse_id' => 1, 'amount' => 100, ]); $response->assertStatus(200); $response->assertJson(['ok' => true]); $this->assertEquals(400, $user->fresh()->jjb); $this->assertDatabaseHas('horse_bets', [ 'race_id' => $race->id, 'user_id' => $user->id, 'horse_id' => 1, 'amount' => 100, ]); } public function test_cannot_bet_out_of_range() { /** @var \App\Models\User $user */ $user = User::factory()->create(['jjb' => 500]); $race = HorseRace::create([ 'status' => 'betting', 'bet_opens_at' => now(), 'bet_closes_at' => now()->addMinutes(1), 'horses' => [ ['id' => 1, 'name' => 'Horse A', 'emoji' => '🐎'], ['id' => 2, 'name' => 'Horse B', 'emoji' => '🏇'], ], 'total_bets' => 0, 'total_pool' => 0, ]); $response = $this->actingAs($user)->postJson(route('horse-race.bet'), [ 'race_id' => $race->id, 'horse_id' => 1, 'amount' => 50, // Less than min_bet ]); $response->assertStatus(200); $response->assertJson(['ok' => false]); } public function test_cannot_bet_twice_in_same_race() { /** @var \App\Models\User $user */ $user = User::factory()->create(['jjb' => 500]); $race = HorseRace::create([ 'status' => 'betting', 'bet_opens_at' => now(), 'bet_closes_at' => now()->addMinutes(1), 'horses' => [ ['id' => 1, 'name' => 'Horse A', 'emoji' => '🐎'], ['id' => 2, 'name' => 'Horse B', 'emoji' => '🏇'], ], 'total_bets' => 0, 'total_pool' => 0, ]); HorseBet::forceCreate([ 'race_id' => $race->id, 'user_id' => $user->id, 'horse_id' => 1, 'amount' => 100, 'status' => 'pending', ]); $response = $this->actingAs($user)->postJson(route('horse-race.bet'), [ 'race_id' => $race->id, 'horse_id' => 2, 'amount' => 100, ]); $response->assertStatus(200); $response->assertJson(['ok' => false]); } public function test_can_get_history() { /** @var \App\Models\User $user */ $user = User::factory()->create(); HorseRace::create([ 'status' => 'settled', 'bet_opens_at' => now()->subMinutes(2), 'bet_closes_at' => now()->subMinutes(1), 'settled_at' => now(), 'winner_horse_id' => 1, 'horses' => [ ['id' => 1, 'name' => 'Horse A', 'emoji' => '🐎'], ['id' => 2, 'name' => 'Horse B', 'emoji' => '🏇'], ], 'total_bets' => 1, 'total_pool' => 100, ]); $response = $this->actingAs($user)->getJson(route('horse-race.history')); $response->assertStatus(200); $response->assertJsonStructure(['history']); $this->assertCount(1, $response->json('history')); } }