Skip to content
This repository was archived by the owner on Jan 9, 2024. It is now read-only.

Commit 3278672

Browse files
committed
Use a dedicated page for joining game
1 parent 5a2c516 commit 3278672

File tree

7 files changed

+154
-31
lines changed

7 files changed

+154
-31
lines changed

app/controllers/games_controller.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@ def create
1616

1717
def join_game
1818
return if @game.state == 'finished'
19-
enlist = Players::Enlist.new(game: @game, player: current_player)
19+
enlist = Players::Enlist.new(game: @game, player: current_player)
2020

2121
if enlist.game_full?
2222
return render FullGame.template_path
23-
else # try to enter the game
24-
payload = enlist.assign_game_to_player!
25-
set_current_player(enlist.player)
26-
27-
ActionCable.server.broadcast "game_#{current_player.game_id}", payload
23+
else
24+
return render AwaitingOpponentGame.template_path
2825
end
2926
end
3027

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class OpponentController < ApplicationController
2+
before_action :set_game, only: [:create]
3+
4+
def create
5+
enlist = Players::Enlist.new(game: @game, player: current_player)
6+
return redirect_to game_path(@game) if enlist.game_full?
7+
8+
payload = enlist.assign_game_to_player!
9+
set_current_player(enlist.player)
10+
ActionCable.server.broadcast "game_#{current_player.game_id}", payload
11+
12+
redirect_to game_path(@game)
13+
end
14+
15+
private
16+
17+
def set_game
18+
@game = Game.find_by(slug: params[:game_id].parameterize)
19+
return redirect_to root_path unless @game
20+
return redirect_to game_path(@game) if @game.state != 'awaiting_opponent'
21+
end
22+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AwaitingOpponentGame < Game
2+
def self.template_path
3+
"games/awaiting_opponent"
4+
end
5+
end
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<div class="row">
2+
<%= render "games/stars" %>
3+
<div class="wrapper">
4+
<div class="join_us">
5+
<div class="mothership">
6+
<div class="ship">
7+
<%= render "games/ships/svg/mothership" %>
8+
</div>
9+
</div>
10+
</div>
11+
<div class="too_late">
12+
<h1>You've been challenged to a battle!</h1>
13+
<p>Your opponent is waiting for you. Join the room <strong><%= @game.name %></strong> right now!</p>
14+
15+
<%= form_tag game_opponent_path(@game), method: :post do %>
16+
<%= submit_tag "Join Game", class: "button green" %>
17+
<% end %>
18+
</div>
19+
</div>
20+
</div>

config/routes.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
resources :attacks, only: [:create]
77
resources :bombings, only: [:create]
88
resources :defenses, only: [:create]
9-
resources :games, only: [:show, :create]
9+
10+
resources :games, only: [:show, :create] do
11+
resource :opponent, only: [:create], controller: 'opponent'
12+
end
13+
1014
resources :players, only: [:update]
1115

1216
#Lets's encrypt

spec/requests/games_spec.rb

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,43 +49,38 @@
4949
get "/games/#{other_game.to_param}"
5050
end
5151

52-
it { expect(Player.count).to eq(2) }
53-
it { expect(Player.last.id).not_to eq(player.id) }
54-
it { expect(Player.last.nickname).to eq("Rico") }
55-
it { expect(Player.last.life).to eq(10) }
5652
it { expect(response).to have_http_status(200) }
57-
it { expect(response.body).to_not include("already full") }
53+
it { expect(response.body).to include("Join Game") }
54+
55+
it { expect(Player.last.id).to eq(player.id) }
56+
it { expect(Player.last.nickname).to eq("Rico") }
57+
58+
it 'does not create a new player' do
59+
expect(Player.count).to eq(1)
60+
end
61+
62+
it "does not update player's life" do
63+
expect(Player.last.life).to eq(3)
64+
end
65+
66+
it 'does not change game of current player' do
67+
expect(Player.last.game).to eq(game)
68+
end
5869
end
5970
end
6071

6172
context "player is not signed in" do
6273
context "game is not full" do
6374
before :each do
6475
game.update(state: 'awaiting_opponent')
65-
allow(ActionCable.server).to receive(:broadcast)
6676
get "/games/#{game.to_param}"
6777
end
6878

6979
it { expect(response).to have_http_status(200) }
70-
it { expect(Player.count).to eq(1) }
7180
it { expect(response.body).to include(game.name) }
72-
it { expect(Player.last.game).to eq(game) }
73-
it { expect(Player.last.life).to eq(10) }
74-
75-
it 'sets game state to running' do
76-
expect(game.reload.state).to eq('running')
77-
end
78-
79-
it 'broadcasts a player joined payload' do
80-
expect(ActionCable.server).to have_received(:broadcast).with(
81-
anything,
82-
{
83-
code: 'player_joined',
84-
player_id: Player.last.id,
85-
nickname: Player.last.nickname
86-
}
87-
)
88-
end
81+
it { expect(response.body).to include("Join Game") }
82+
it { expect(Player.count).to eq(0) }
83+
it { expect(game.reload.state).to eq('awaiting_opponent') }
8984
end
9085

9186
context "game is already full" do

spec/requests/opponent_spec.rb

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
require "rails_helper"
2+
3+
RSpec.describe "Opponent", type: :request do
4+
describe 'POST create' do
5+
let(:game) { Game.create!(name: 'Starship Battle', slug: 'starship-battle', state: 'awaiting_opponent') }
6+
7+
before :each do
8+
game.players.create!
9+
end
10+
11+
context 'when game is not full' do
12+
before :each do
13+
allow(ActionCable.server).to receive(:broadcast)
14+
post "/games/starship-battle/opponent"
15+
end
16+
17+
it { expect(response).to redirect_to("/games/starship-battle") }
18+
it { expect(Player.count).to eq(2) }
19+
it { expect(Player.last.game).to eq(game) }
20+
it { expect(Player.last.life).to eq(10) }
21+
22+
it 'sets game state to running' do
23+
expect(game.reload.state).to eq('running')
24+
end
25+
26+
it 'broadcasts a player joined payload' do
27+
expect(ActionCable.server).to have_received(:broadcast).with(
28+
anything,
29+
{
30+
code: 'player_joined',
31+
player_id: Player.last.id,
32+
nickname: Player.last.nickname
33+
}
34+
)
35+
end
36+
end
37+
38+
context 'when game is full' do
39+
before :each do
40+
game.update(state: 'running')
41+
game.players.create!
42+
post "/games/starship-battle/opponent"
43+
end
44+
45+
it { expect(response).to redirect_to("/games/starship-battle") }
46+
it { expect(Player.count).to eq(2) }
47+
it { expect(Game.last.state).to eq('running') }
48+
49+
it 'tells game is full' do
50+
follow_redirect!
51+
expect(response.body).to include('already full')
52+
end
53+
end
54+
55+
context 'when game is already finished' do
56+
before :each do
57+
game.update(state: 'finished')
58+
post "/games/starship-battle/opponent"
59+
end
60+
61+
it { expect(response).to redirect_to("/games/starship-battle") }
62+
it { expect(Player.count).to eq(1) }
63+
it { expect(Game.last.state).to eq('finished') }
64+
65+
it 'tells game is finished' do
66+
follow_redirect!
67+
expect(response.body).to include('Game Finished')
68+
end
69+
end
70+
71+
context "game doesn't exist" do
72+
before :each do
73+
post "/games/foo/opponent"
74+
end
75+
76+
it { expect(response).to redirect_to(root_path) }
77+
it { expect(Player.count).to eq(1) }
78+
end
79+
end
80+
end

0 commit comments

Comments
 (0)