'Sprint Planning', 'deck_config' => [ 'name' => 'Fibonacci', 'cards' => [ ['key' => '3', 'label' => '3'], ['key' => '5', 'label' => '5'], ['key' => '8', 'label' => '8'], ], ], ]); $moderator = $room->players()->create([ 'name' => 'Eric', 'is_moderator' => true, ]); $player = $room->players()->create([ 'name' => 'Anna', 'is_moderator' => false, ]); return [$room, $moderator, $player]; } test('a participant can vote and change their vote in the current round', function () { [$room, $moderator] = createVotingRoom(); $session = ["room_players.{$room->id}" => $moderator->id]; $this->withSession($session) ->post(route('room.vote.store', $room), ['value' => '5']) ->assertRedirect(); $this->assertDatabaseHas('votes', [ 'room_id' => $room->id, 'player_id' => $moderator->id, 'round' => 1, 'value' => '5', ]); $this->withSession($session) ->post(route('room.vote.store', $room), ['value' => '8']) ->assertRedirect(); expect(Vote::query()->count())->toBe(1); expect(Vote::query()->value('value'))->toBe('8'); }); test('a participant cannot vote with a card outside the room deck', function () { [$room, $moderator] = createVotingRoom(); $this->withSession(["room_players.{$room->id}" => $moderator->id]) ->post(route('room.vote.store', $room), ['value' => '100']) ->assertSessionHasErrors('value'); $this->assertDatabaseCount('votes', 0); }); test('other votes stay hidden until the moderator reveals the round', function () { [$room, $moderator, $player] = createVotingRoom(); $player->votes()->create([ 'room_id' => $room->id, 'round' => 1, 'value' => '8', ]); $session = ["room_players.{$room->id}" => $moderator->id]; $this->withSession($session) ->get(route('room.show', $room)) ->assertInertia(fn (Assert $page) => $page ->component('rooms/Show') ->where('room.revealed', false) ->where('room.players.1.has_voted', true) ->where('room.players.1.vote', null)); $this->withSession($session) ->post(route('room.reveal', $room)) ->assertRedirect(); $this->withSession($session) ->get(route('room.show', $room)) ->assertInertia(fn (Assert $page) => $page ->where('room.revealed', true) ->where('room.players.1.vote', '8')); }); test('only the moderator may reveal cards', function () { [$room, , $player] = createVotingRoom(); $this->withSession(["room_players.{$room->id}" => $player->id]) ->post(route('room.reveal', $room)) ->assertForbidden(); expect($room->fresh()->revealed_at)->toBeNull(); }); test('starting the next round clears the revealed state', function () { [$room, $moderator] = createVotingRoom(); $room->update(['revealed_at' => now()]); $this->withSession(["room_players.{$room->id}" => $moderator->id]) ->post(route('room.next-round', $room)) ->assertRedirect(); $room->refresh(); expect($room->current_round)->toBe(2) ->and($room->revealed_at)->toBeNull(); }); test('the moderator can reset only the votes from the current round', function () { [$room, $moderator, $player] = createVotingRoom(); $room->update([ 'current_round' => 2, 'revealed_at' => now(), ]); $player->votes()->create([ 'room_id' => $room->id, 'round' => 1, 'value' => '3', ]); $player->votes()->create([ 'room_id' => $room->id, 'round' => 2, 'value' => '8', ]); $this->withSession(["room_players.{$room->id}" => $moderator->id]) ->post(route('room.reset', $room)) ->assertRedirect(); $this->assertDatabaseHas('votes', [ 'room_id' => $room->id, 'player_id' => $player->id, 'round' => 1, 'value' => '3', ]); $this->assertDatabaseMissing('votes', [ 'room_id' => $room->id, 'round' => 2, ]); expect($room->fresh()->revealed_at)->toBeNull(); });