Skip to content

Commit 7e9547e

Browse files
author
Mike Firesheets
committedFeb 4, 2015
Adding old foosball app for reference
1 parent 493e521 commit 7e9547e

33 files changed

+688
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class ApplicationController < ActionController::Base
2+
# Prevent CSRF attacks by raising an exception.
3+
# For APIs, you may want to use :null_session instead.
4+
protect_from_forgery with: :exception
5+
6+
def index
7+
end
8+
end

‎old_foosball/controllers/concerns/.keep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
class GamesController < ApplicationController
2+
before_action :set_game, only: [:show, :destroy]
3+
4+
# GET /games
5+
# GET /games.json
6+
def index
7+
@games = Game.all
8+
end
9+
10+
# GET /games/1
11+
# GET /games/1.json
12+
def show
13+
end
14+
15+
# GET /games/new
16+
def new
17+
@game = Game.new
18+
end
19+
20+
# POST /games
21+
# POST /games.json
22+
def create
23+
@game = Game.new(game_params)
24+
25+
respond_to do |format|
26+
if @game.save
27+
format.html { redirect_to teams_url, notice: 'Game was successfully created.' }
28+
format.json { render :show, status: :created, location: teams_url }
29+
else
30+
format.html { render :new }
31+
format.json { render json: @game.errors, status: :unprocessable_entity }
32+
end
33+
end
34+
end
35+
36+
# DELETE /games/1
37+
# DELETE /games/1.json
38+
def destroy
39+
@game.destroy
40+
respond_to do |format|
41+
format.html { redirect_to games_url, notice: 'Game was successfully destroyed.' }
42+
format.json { head :no_content }
43+
end
44+
end
45+
46+
private
47+
# Use callbacks to share common setup or constraints between actions.
48+
def set_game
49+
@game = Game.find(params[:id])
50+
end
51+
52+
# Never trust parameters from the scary internet, only allow the white list through.
53+
def game_params
54+
params.require(:game).permit(:tournament_id, :complete, matchups_attributes: [:id, :score, :team_id])
55+
end
56+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
class PlayersController < ApplicationController
2+
before_action :set_player, only: [:show, :edit, :update, :destroy]
3+
4+
# GET /players
5+
# GET /players.json
6+
def index
7+
@players = Player.all
8+
end
9+
10+
# GET /players/1
11+
# GET /players/1.json
12+
def show
13+
end
14+
15+
# GET /players/new
16+
def new
17+
@player = Player.new
18+
end
19+
20+
# GET /players/1/edit
21+
def edit
22+
end
23+
24+
# POST /players
25+
# POST /players.json
26+
def create
27+
@player = Player.new(player_params)
28+
29+
respond_to do |format|
30+
if @player.save
31+
format.html { redirect_to @player, notice: 'Player was successfully created.' }
32+
format.json { render :show, status: :created, location: @player }
33+
else
34+
format.html { render :new }
35+
format.json { render json: @player.errors, status: :unprocessable_entity }
36+
end
37+
end
38+
end
39+
40+
# PATCH/PUT /players/1
41+
# PATCH/PUT /players/1.json
42+
def update
43+
respond_to do |format|
44+
if @player.update(player_params)
45+
format.html { redirect_to @player, notice: 'Player was successfully updated.' }
46+
format.json { render :show, status: :ok, location: @player }
47+
else
48+
format.html { render :edit }
49+
format.json { render json: @player.errors, status: :unprocessable_entity }
50+
end
51+
end
52+
end
53+
54+
# DELETE /players/1
55+
# DELETE /players/1.json
56+
def destroy
57+
@player.destroy
58+
respond_to do |format|
59+
format.html { redirect_to players_url, notice: 'Player was successfully destroyed.' }
60+
format.json { head :no_content }
61+
end
62+
end
63+
64+
private
65+
# Use callbacks to share common setup or constraints between actions.
66+
def set_player
67+
@player = Player.find(params[:id])
68+
end
69+
70+
# Never trust parameters from the scary internet, only allow the white list through.
71+
def player_params
72+
params.require(:player).permit(:first, :last, :email)
73+
end
74+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
class TeamsController < ApplicationController
2+
before_action :set_team, only: [:show, :edit, :update, :destroy]
3+
4+
# GET /teams
5+
# GET /teams.json
6+
def index
7+
@teams = Team.all
8+
end
9+
10+
# GET /teams/1
11+
# GET /teams/1.json
12+
def show
13+
end
14+
15+
# GET /teams/new
16+
def new
17+
@team = Team.new
18+
end
19+
20+
# GET /teams/1/edit
21+
def edit
22+
end
23+
24+
# POST /teams
25+
# POST /teams.json
26+
def create
27+
@team = Team.new(team_params)
28+
29+
respond_to do |format|
30+
if @team.save
31+
format.html { redirect_to @team, notice: 'Team was successfully created.' }
32+
format.json { render :show, status: :created, location: @team }
33+
else
34+
format.html { render :new }
35+
format.json { render json: @team.errors, status: :unprocessable_entity }
36+
end
37+
end
38+
end
39+
40+
# PATCH/PUT /teams/1
41+
# PATCH/PUT /teams/1.json
42+
def update
43+
respond_to do |format|
44+
if @team.update(team_params)
45+
format.html { redirect_to @team, notice: 'Team was successfully updated.' }
46+
format.json { render :show, status: :ok, location: @team }
47+
else
48+
format.html { render :edit }
49+
format.json { render json: @team.errors, status: :unprocessable_entity }
50+
end
51+
end
52+
end
53+
54+
# DELETE /teams/1
55+
# DELETE /teams/1.json
56+
def destroy
57+
@team.destroy
58+
respond_to do |format|
59+
format.html { redirect_to teams_url, notice: 'Team was successfully destroyed.' }
60+
format.json { head :no_content }
61+
end
62+
end
63+
64+
# GET /teams/random
65+
# GET /teams/random.json
66+
def assign_random
67+
Team.destroy_all
68+
players = Player.all.to_a.shuffle
69+
# Assign as many teams as possible
70+
players.pop unless players.count.even?
71+
until players.empty? do
72+
p1, p2 = players.pop, players.pop
73+
name = p1.last < p2.last ? "#{p1.last} - #{p2.last}" : "#{p2.last} - #{p1.last}"
74+
team = Team.new(name: name)
75+
team.players = p1, p2
76+
team.save
77+
end
78+
respond_to do |format|
79+
format.html { redirect_to teams_url, notice: 'Teams have been randomly reassigned' }
80+
format.json { render :index, status: :ok }
81+
end
82+
end
83+
84+
private
85+
# Use callbacks to share common setup or constraints between actions.
86+
def set_team
87+
@team = Team.find(params[:id])
88+
end
89+
90+
# Never trust parameters from the scary internet, only allow the white list through.
91+
def team_params
92+
params.require(:team).permit(:name, player_ids: [])
93+
end
94+
end
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module ApplicationHelper
2+
3+
# Returns the full title on a per-page basis.
4+
def full_title(page_title = '')
5+
base_title = Rails.application.config.site_title
6+
if page_title.empty?
7+
base_title
8+
else
9+
"#{page_title} | #{base_title}"
10+
end
11+
end
12+
13+
def short_form
14+
@game = Game.new
15+
@game.matchups.build.build_team
16+
@game.matchups.build.build_team
17+
end
18+
end

‎old_foosball/helpers/games_helper.rb

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module GamesHelper
2+
end
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module PlayersHelper
2+
3+
# Returns the Gravatar for the given user.
4+
def gravatar_for(player, options = { size: 80 })
5+
gravatar_id = Digest::MD5::hexdigest(player.email.downcase)
6+
size = options[:size]
7+
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
8+
image_tag(gravatar_url, alt: player.name, class: "gravatar")
9+
end
10+
end

‎old_foosball/helpers/teams_helper.rb

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module TeamsHelper
2+
end

‎old_foosball/models/.keep

Whitespace-only changes.

‎old_foosball/models/concerns/.keep

Whitespace-only changes.

‎old_foosball/models/game.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Game < ActiveRecord::Base
2+
3+
# Relationships
4+
has_many :matchups, class_name: "GameTeam", inverse_of: :game
5+
accepts_nested_attributes_for :matchups, reject_if: :all_blank
6+
has_many :teams, through: :matchups
7+
8+
# # Validation
9+
# validates :team1_score, numericality: { only_integer: true,
10+
# greater_than_or_equal_to: 0,
11+
# less_than_or_equal_to: 5 }
12+
# validates :team2_score, numericality: { only_integer: true,
13+
# greater_than_or_equal_to: 0,
14+
# less_than_or_equal_to: 5 }
15+
end

‎old_foosball/models/game_team.rb

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class GameTeam < ActiveRecord::Base
2+
self.table_name = 'games_teams'
3+
4+
# Relationships
5+
belongs_to :game
6+
belongs_to :team
7+
accepts_nested_attributes_for :team, reject_if: :all_blank
8+
end

‎old_foosball/models/player.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Player < ActiveRecord::Base
2+
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
3+
4+
# Relationships
5+
belongs_to :team
6+
7+
# Callbacks
8+
before_save { email.downcase! }
9+
10+
# Validation
11+
validates :first, presence: true, length: { maximum: 50 }
12+
validates :last, presence: true, length: { maximum: 50 }
13+
validates :email, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX },
14+
uniqueness: { case_sensitive: false }
15+
16+
# Virtual properties
17+
def name
18+
@name ||= "#{first} #{last}"
19+
end
20+
21+
end

‎old_foosball/models/team.rb

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
class Team < ActiveRecord::Base
2+
INITIAL_TEAM_NAME = 'A'
3+
@next_name = INITIAL_TEAM_NAME
4+
5+
# Relationships
6+
has_many :players
7+
has_many :matchups, class_name: "GameTeam", inverse_of: :team
8+
has_many :games, through: :matchups
9+
10+
# Validation
11+
validates :name, presence: true, length: { maximum: 50 }, uniqueness: { case_sensitive: false }
12+
validates :players, length: { minimum: 2, maximum: 2 }
13+
14+
# Class methods
15+
class << self
16+
attr_reader :next_name
17+
18+
def take_name!
19+
name = @next_name
20+
@next_name = @next_name.next
21+
name
22+
end
23+
24+
def reset_names!
25+
@next_name = INITIAL_TEAM_NAME
26+
end
27+
end
28+
29+
# Virtual Properties
30+
def goals_scored
31+
games.sum(:score)
32+
end
33+
34+
def goals_allowed
35+
GameTeam.where(game_id: matchups.map(&:game_id)).where.not(team_id: id).sum(:score)
36+
end
37+
38+
def goal_differential
39+
sprintf "%+d", goals_scored - goals_allowed
40+
end
41+
end

‎old_foosball/test/controllers/.keep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require 'test_helper'
2+
3+
class GameControllerTest < ActionController::TestCase
4+
test "should get index" do
5+
get :index
6+
assert_response :success
7+
end
8+
9+
test "should get new" do
10+
get :new
11+
assert_response :success
12+
end
13+
14+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require 'test_helper'
2+
3+
class PlayersControllerTest < ActionController::TestCase
4+
setup do
5+
@player = players(:one)
6+
end
7+
8+
test "should get index" do
9+
get :index
10+
assert_response :success
11+
assert_select "title", full_title("Players")
12+
assert_not_nil assigns(:players)
13+
end
14+
15+
test "should get new" do
16+
get :new
17+
assert_response :success
18+
end
19+
20+
test "should create player" do
21+
assert_difference('Player.count') do
22+
post :create, player: { email: @player.email, first: @player.first, last: @player.last }
23+
end
24+
25+
assert_redirected_to player_path(assigns(:player))
26+
end
27+
28+
test "should show player" do
29+
get :show, id: @player
30+
assert_response :success
31+
end
32+
33+
test "should get edit" do
34+
get :edit, id: @player
35+
assert_response :success
36+
end
37+
38+
test "should update player" do
39+
patch :update, id: @player, player: { email: @player.email, first: @player.first, last: @player.last }
40+
assert_redirected_to player_path(assigns(:player))
41+
end
42+
43+
test "should destroy player" do
44+
assert_difference('Player.count', -1) do
45+
delete :destroy, id: @player
46+
end
47+
48+
assert_redirected_to players_path
49+
end
50+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
require 'test_helper'
2+
3+
class TeamsControllerTest < ActionController::TestCase
4+
setup do
5+
@team = teams(:one)
6+
end
7+
8+
test "should get index" do
9+
get :index
10+
assert_response :success
11+
assert_not_nil assigns(:teams)
12+
end
13+
14+
test "should get new" do
15+
get :new
16+
assert_response :success
17+
end
18+
19+
test "should create team" do
20+
assert_difference('Team.count') do
21+
post :create, team: { name: 'Example' }
22+
end
23+
24+
assert_redirected_to team_path(assigns(:team))
25+
end
26+
27+
test "should show team" do
28+
get :show, id: @team
29+
assert_response :success
30+
end
31+
32+
test "should get edit" do
33+
get :edit, id: @team
34+
assert_response :success
35+
end
36+
37+
# test "should update team" do
38+
# patch :update, id: @team, team: { name: @team.name, player1_id: @team.player1, player2_id: @team.player2 }
39+
# assert_redirected_to team_path(assigns(:team))
40+
# end
41+
42+
test "should destroy team" do
43+
assert_difference('Team.count', -1) do
44+
delete :destroy, id: @team
45+
end
46+
47+
assert_redirected_to teams_path
48+
end
49+
50+
test "should randomly assign teams" do
51+
p Player.all.count
52+
end
53+
end

‎old_foosball/test/fixtures/.keep

Whitespace-only changes.

‎old_foosball/test/fixtures/games.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
3+
one:
4+
team1_score: 1
5+
team2_score: 1
6+
7+
two:
8+
team1_score: 1
9+
team2_score: 1
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
3+
test:
4+
first: Test
5+
last: User
6+
email: test@example.com
7+
8+
mike:
9+
first: Mike
10+
last: Firesheets
11+
email: mike@example.com
12+
team: one
13+
14+
noah:
15+
first: Noah
16+
last: Bass
17+
email: noah@example.com
18+
team: one
19+
20+
chris:
21+
first: Chris
22+
last: Costanza
23+
email: chris@example.com
24+
team: two
25+
26+
luke:
27+
first: Luke
28+
last: Moderwell
29+
email: luke@example.com
30+
team: two

‎old_foosball/test/fixtures/teams.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
test:
3+
name: Test
4+
5+
one:
6+
name: A
7+
8+
two:
9+
name: B

‎old_foosball/test/helpers/.keep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
require 'test_helper'
2+
3+
class ApplicationHelperTest < ActionView::TestCase
4+
5+
test "full title helper" do
6+
assert_equal full_title, @base_title
7+
assert_equal full_title("Test"), "Test | #{@base_title}"
8+
end
9+
end

‎old_foosball/test/integration/.keep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
require 'test_helper'
2+
3+
class SiteLayoutTest < ActionDispatch::IntegrationTest
4+
5+
test "header links" do
6+
get root_path
7+
assert_template 'players/index'
8+
assert_select "a[href=?]", root_path, count: 2
9+
assert_select "a[href=?]", players_path
10+
assert_select "a[href=?]", teams_path, count: 2
11+
assert_select "a[href=?]", new_team_path
12+
end
13+
14+
# test "footer form" do
15+
# # Do the test here
16+
# end
17+
end

‎old_foosball/test/mailers/.keep

Whitespace-only changes.

‎old_foosball/test/models/.keep

Whitespace-only changes.

‎old_foosball/test/models/game_test.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require 'test_helper'
2+
3+
class GameTest < ActiveSupport::TestCase
4+
# test "the truth" do
5+
# assert true
6+
# end
7+
end
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
require 'test_helper'
2+
3+
class PlayerTest < ActiveSupport::TestCase
4+
def setup
5+
@player = players(:test)
6+
end
7+
8+
test "player should be valid" do
9+
assert @player.valid?, @player.errors.full_messages.join(' ')
10+
end
11+
12+
test "name should be present" do
13+
@player.first = " "
14+
@player.last = " "
15+
assert_not @player.valid?
16+
end
17+
18+
test "name should not be too long" do
19+
@player.first = 'a' * 51;
20+
assert_not @player.valid?
21+
@player.first = 'test'
22+
assert @player.valid?
23+
@player.last = 'a' * 51
24+
assert_not @player.valid?
25+
end
26+
27+
test "email should not be too long" do
28+
@player.email = 'a' * 256
29+
assert_not @player.valid?
30+
end
31+
32+
test "email validation should accept valid addresses" do
33+
valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
34+
first.last@foo.jp alice+bob@baz.cn]
35+
valid_addresses.each do |valid_address|
36+
@player.email = valid_address
37+
assert @player.valid?, "#{valid_address.inspect} should be valid"
38+
end
39+
end
40+
41+
test "email validation should reject invalid addresses" do
42+
invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
43+
foo@bar_baz.com foo@bar+baz.com foo@bar..com]
44+
invalid_addresses.each do |invalid_address|
45+
@player.email = invalid_address
46+
assert_not @player.valid?, "#{invalid_address.inspect} should be invalid"
47+
end
48+
end
49+
50+
test "email addresses should be unique" do
51+
duplicate_player = @player.dup
52+
duplicate_player.email = @player.email.upcase
53+
@player.save
54+
assert_not duplicate_player.valid?
55+
end
56+
57+
test "email addresses should be saved as lower-case" do
58+
mixed_case_email = "Foo@ExAMPle.CoM"
59+
@player.email = mixed_case_email
60+
@player.save
61+
assert_equal mixed_case_email.downcase, @player.reload.email
62+
end
63+
end

‎old_foosball/test/models/team_test.rb

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
require 'test_helper'
2+
3+
class TeamTest < ActiveSupport::TestCase
4+
def setup
5+
@team = teams(:test)
6+
@team.players = players(:mike), players(:noah)
7+
end
8+
9+
test "class method should reset name" do
10+
Team.reset_names!
11+
assert_equal Team.next_name, Team::INITIAL_TEAM_NAME
12+
end
13+
14+
test "class method should give name" do
15+
assert_not_nil Team.next_name
16+
end
17+
18+
test "class method should take and change name" do
19+
Team.reset_names!
20+
name = Team.take_name!
21+
assert_not_equal Team.next_name, Team::INITIAL_TEAM_NAME
22+
end
23+
24+
test "team should be valid" do
25+
assert @team.valid?, @team.errors.full_messages.join(' ')
26+
end
27+
28+
test "name should be present" do
29+
@team.name = ' '
30+
assert_not @team.valid?
31+
end
32+
33+
test "name should not be too long" do
34+
@team.name = 'a' * 51
35+
assert_not @team.valid?
36+
end
37+
38+
test "name should be unique" do
39+
duplicate_team = @team.dup
40+
duplicate_team.name = @team.name.downcase
41+
@team.save
42+
assert_not duplicate_team.valid?
43+
end
44+
45+
test "name should be saved as capitalized" do
46+
mixed_case_name = "The TeRminaTors"
47+
@team.name = mixed_case_name
48+
@team.save
49+
assert_equal mixed_case_name.downcase.capitalize, @team.reload.name
50+
end
51+
52+
test "must have exactly two players" do
53+
@team.players.clear
54+
assert_not @team.valid?
55+
@team.players << players(:mike)
56+
assert_not @team.valid?
57+
@team.players << players(:noah)
58+
assert @team.valid?
59+
@team.players << players(:luke)
60+
assert_not @team.valid?
61+
end
62+
end

‎old_foosball/test/test_helper.rb

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ENV['RAILS_ENV'] ||= 'test'
2+
require File.expand_path('../../config/environment', __FILE__)
3+
require 'rails/test_help'
4+
require "minitest/reporters"
5+
Minitest::Reporters.use!
6+
7+
class ActiveSupport::TestCase
8+
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
9+
fixtures :all
10+
include ApplicationHelper
11+
12+
# Add more helper methods to be used by all tests here...
13+
setup do
14+
@base_title = Rails.application.config.site_title
15+
end
16+
end

0 commit comments

Comments
 (0)
Please sign in to comment.