diff --git a/app/controllers/weights_controller.rb b/app/controllers/weights_controller.rb index d4284d0..3914c00 100644 --- a/app/controllers/weights_controller.rb +++ b/app/controllers/weights_controller.rb @@ -8,15 +8,21 @@ class WeightsController < ApplicationController # GET /weights/1.json def show if params[:wrestler] + check_access_manage respond_to do |format| - Wrestler.update(params[:wrestler].keys, params[:wrestler].values) + # Sanitize the wrestler parameters + sanitized_wrestlers = params.require(:wrestler).to_unsafe_h.transform_values do |attributes| + ActionController::Parameters.new(attributes).permit(:original_seed) + end + + Wrestler.update(sanitized_wrestlers.keys, sanitized_wrestlers.values) format.html { redirect_to @weight, notice: 'Seeds were successfully updated.' } end end @wrestlers = @weight.wrestlers @tournament = @weight.tournament session[:return_path] = "/weights/#{@weight.id}" - end + end # GET /weights/new def new diff --git a/app/models/tournament.rb b/app/models/tournament.rb index f743dbf..4b37445 100644 --- a/app/models/tournament.rb +++ b/app/models/tournament.rb @@ -129,7 +129,7 @@ class Tournament < ApplicationRecord end end - def pool_to_bracket_number_of_wrestlers + def pool_to_bracket_number_of_wrestlers_error error_string = "" if self.tournament_type.include? "Pool to bracket" weights_with_too_many_wrestlers = weights.select{|w| w.wrestlers.size > 24} @@ -144,7 +144,7 @@ class Tournament < ApplicationRecord return error_string end - def modified_sixteen_man_number_of_wrestlers + def modified_sixteen_man_number_of_wrestlers_error error_string = "" if self.tournament_type.include? "Modified 16 Man Double Elimination" weights_with_too_many_wrestlers = weights.select{|w| w.wrestlers.size > 16} @@ -159,7 +159,7 @@ class Tournament < ApplicationRecord return error_string end - def double_elim_number_of_wrestlers + def double_elim_number_of_wrestlers_error error_string = "" if self.tournament_type == "Double Elimination 1-6" or self.tournament_type == "Double Elimination 1-8" weights_with_too_many_wrestlers = weights.select{|w| w.wrestlers.size > 16} @@ -173,21 +173,35 @@ class Tournament < ApplicationRecord end return error_string end + + def wrestlers_with_higher_seed_than_bracket_size_error + error_string = "" + weights.each do |weight| + weight.wrestlers.each do |wrestler| + if wrestler.original_seed != nil && wrestler.original_seed > weight.wrestlers.size + error_string += "Wrestler: #{wrestler.name} has a seed of #{wrestler.original_seed} which is greater than the amount of wrestlers (#{weight.wrestlers.size}) in the weight class #{weight.max}." + end + end + end + return error_string + end def match_generation_error - error_string = "There is a tournament error." - modified_sixteen_man_error = modified_sixteen_man_number_of_wrestlers - double_elim_error = double_elim_number_of_wrestlers - pool_to_bracket_error = pool_to_bracket_number_of_wrestlers - if pool_to_bracket_error.length > 0 - return error_string + pool_to_bracket_error - elsif modified_sixteen_man_error.length > 0 - return error_string + modified_sixteen_man_error - elsif double_elim_error.length > 0 - return error_string + double_elim_error - else - nil + error_string = "" + if pool_to_bracket_number_of_wrestlers_error.length > 0 + error_string += pool_to_bracket_number_of_wrestlers_error + elsif modified_sixteen_man_number_of_wrestlers_error.length > 0 + error_string += modified_sixteen_man_number_of_wrestlers_error + elsif double_elim_number_of_wrestlers_error.length > 0 + error_string += double_elim_number_of_wrestlers_error + elsif wrestlers_with_higher_seed_than_bracket_size_error.length > 0 + error_string += wrestlers_with_higher_seed_than_bracket_size_error end + if error_string.length > 0 + return "There is a tournament error. #{error_string}" + else + return nil + end end def reset_and_fill_bout_board diff --git a/app/services/tournament_services/double_elimination_generate_loser_names.rb b/app/services/tournament_services/double_elimination_generate_loser_names.rb index 550bef7..e1d4c56 100644 --- a/app/services/tournament_services/double_elimination_generate_loser_names.rb +++ b/app/services/tournament_services/double_elimination_generate_loser_names.rb @@ -15,7 +15,12 @@ class DoubleEliminationGenerateLoserNames # cross_bracket is true or false. crossing should happen every other round. # both_wrestlers defines if you're filling out loser1_name and loser2_name or just loser1_name # don't need to define 3/4, 5/6, or 7/8 those happen in the assign_loser_names_for_weight method + # except for bracket_size of 4 case bracket_size + when 4 then + return [ + [@tournament.total_rounds, "3/4", 1, "Semis", false, true] + ] when 8 then return [ [2, "Conso Quarter", 1, "Quarter", false, true], @@ -24,8 +29,8 @@ class DoubleEliminationGenerateLoserNames when 16 then return [ [2, "Conso", 1, "Bracket", false, true], - [3, "Conso", 2, "Quarter", true], - [5, "Conso Semis", 4, "Semis", false] + [3, "Conso", 2, "Quarter", true, false], + [5, "Conso Semis", 4, "Semis", false, false] ] else return nil @@ -35,7 +40,7 @@ class DoubleEliminationGenerateLoserNames def assign_loser_names_for_weight(weight) number_of_placers = @tournament.number_of_placers bracket_size = weight.calculate_bracket_size - matches_by_weight = weight.matches + matches_by_weight = weight.matches.reload loser_name_championship_mappings = define_losername_championship_mappings(bracket_size) @@ -68,14 +73,14 @@ class DoubleEliminationGenerateLoserNames conso_semi_matches = matches_by_weight.select{|match| match.bracket_position == "Conso Semis"} conso_quarter_matches = matches_by_weight.select{|match| match.bracket_position == "Conso Quarter"} - if number_of_placers >= 6 + if number_of_placers >= 6 && weight.wrestlers.size >= 5 five_six_match = matches_by_weight.select{|match| match.bracket_position == "5/6"}.first bout_number1 = conso_semi_matches.select{|match| match.bracket_position_number == 1}.first.bout_number bout_number2 = conso_semi_matches.select{|match| match.bracket_position_number == 2}.first.bout_number five_six_match.loser1_name = "Loser of #{bout_number1}" five_six_match.loser2_name = "Loser of #{bout_number2}" end - if number_of_placers >= 8 + if number_of_placers >= 8 && weight.wrestlers.size >= 7 seven_eight_match = matches_by_weight.select{|match| match.bracket_position == "7/8"}.first bout_number1 = conso_quarter_matches.select{|match| match.bracket_position_number == 1}.first.bout_number bout_number2 = conso_quarter_matches.select{|match| match.bracket_position_number == 2}.first.bout_number diff --git a/app/services/tournament_services/double_elimination_match_generation.rb b/app/services/tournament_services/double_elimination_match_generation.rb index 087aa2c..00ab7fd 100644 --- a/app/services/tournament_services/double_elimination_match_generation.rb +++ b/app/services/tournament_services/double_elimination_match_generation.rb @@ -19,6 +19,12 @@ class DoubleEliminationMatchGeneration # consolation_rounds define [round_number, number_of_matches_in_round, bracket_position] case bracket_size + when 4 then + return BracketMatchups.new( + [[1, 4, "Semis"], [2, 3, "Semis"]], + [[2, 1, "1/2"]], + [[2, 1, "3/4"]] + ) when 8 then return BracketMatchups.new( [[1, 8, "Quarter"], [4, 5, "Quarter"], [3, 6, "Quarter"], [2, 7, "Quarter"]], @@ -75,8 +81,12 @@ class DoubleEliminationMatchGeneration matches_this_round.times do |bracket_position_number| create_matchup(nil, nil, bracket_position, bracket_position_number + 1, round, weight) end - create_matchup(nil, nil, "5/6", 1, round, weight) if @tournament.number_of_placers >= 6 && matches_this_round == 1 - create_matchup(nil, nil, "7/8", 1, round, weight) if @tournament.number_of_placers >= 8 && matches_this_round == 1 + if weight.wrestlers.size >=5 + create_matchup(nil, nil, "5/6", 1, round, weight) if @tournament.number_of_placers >= 6 && matches_this_round == 1 + end + if weight.wrestlers.size >= 7 + create_matchup(nil, nil, "7/8", 1, round, weight) if @tournament.number_of_placers >= 8 && matches_this_round == 1 + end end end diff --git a/app/views/tournaments/_bracket_final.html.erb b/app/views/tournaments/_bracket_final.html.erb index 97a672e..67f8080 100644 --- a/app/views/tournaments/_bracket_final.html.erb +++ b/app/views/tournaments/_bracket_final.html.erb @@ -1,15 +1,9 @@ +<% @final_match.each do |match| %>
- <% @final_match.each do |match| %>
<%= match.w1_bracket_name.html_safe %>

<%= match.bout_number %> <%= match.bracket_score_string %>

<%= @winner_place %> Place Winner

<%= match.w2_bracket_name.html_safe %>
- \ No newline at end of file +<% end %> diff --git a/app/views/tournaments/_double_elimination_bracket.html.erb b/app/views/tournaments/_double_elimination_bracket.html.erb index e1fe057..0f7fc12 100644 --- a/app/views/tournaments/_double_elimination_bracket.html.erb +++ b/app/views/tournaments/_double_elimination_bracket.html.erb @@ -32,7 +32,6 @@

5/6 place match

- <% @final_match = @matches.select{|m|m.bracket_position == "5/6"} %> <% @winner_place = "5th" %> <%= render 'bracket_final' %> @@ -40,7 +39,6 @@ <% if @tournament.number_of_placers >= 8 %>

7/8 place match

- <% @final_match = @matches.select{|m|m.bracket_position == "7/8"} %> <% @winner_place = "7th" %> <%= render 'bracket_final' %> diff --git a/db/seeds.rb b/db/seeds.rb index 58f3210..2c3d79d 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -47,6 +47,8 @@ number_of_wrestlers = 12 elsif index == 4 number_of_wrestlers = 24 + elsif index == 5 + number_of_wrestlers = 2 else number_of_wrestlers = 16 end @@ -72,9 +74,15 @@ weight_classes=Weight::HS_WEIGHT_CLASSES.split(",") tournament.create_pre_defined_weights(weight_classes) wrestler_name_number = 1 - tournament.weights.each do |weight| - create_wrestlers_for_weight(weight, tournament, 16, wrestler_name_number) - wrestler_name_number += 16 + tournament.weights.each_with_index do |weight, index| + if index == 0 + number_of_wrestlers = 12 + else + number_of_wrestlers = 16 + end + + create_wrestlers_for_weight(weight, tournament, number_of_wrestlers, wrestler_name_number) + wrestler_name_number += number_of_wrestlers end # Regular Double Elimination 1-6 diff --git a/test/controllers/tournaments_controller_test.rb b/test/controllers/tournaments_controller_test.rb index a6eaf2a..89debae 100644 --- a/test/controllers/tournaments_controller_test.rb +++ b/test/controllers/tournaments_controller_test.rb @@ -55,6 +55,10 @@ class TournamentsControllerTest < ActionController::TestCase assert_redirected_to '/static_pages/not_allowed' end + def redirect_tournament_error + assert_redirected_to "/tournaments/#{@tournament.id}/error" + end + def destroy delete :destroy, params: { id: 1 } end @@ -664,4 +668,83 @@ class TournamentsControllerTest < ActionController::TestCase updated_tournament = Tournament.find(new_tournament.id) assert_equal users(:one).id, updated_tournament.user_id, "The user_id should not change when the tournament is edited by a non-owner" end + + test "tournament generation error when a wrestler has an original seed higher than the amount of wrestlers in the weight" do + sign_in_owner + create_double_elim_tournament_single_weight(14, "Regular Double Elimination 1-8") + @tournament.destroy_all_matches + @tournament.user_id = 1 + @tournament.save + wrestler = @tournament.weights.first.wrestlers.first + wrestler.original_seed = 15 + wrestler.save + get :generate_matches, params: { id: @tournament.id } + redirect_tournament_error + end + + test "tournament generation error when a double elimination tournament has too many wrestlers" do + sign_in_owner + create_double_elim_tournament_single_weight(16, "Regular Double Elimination 1-8") + @tournament.destroy_all_matches + @tournament.user_id = 1 + @tournament.save + create_wrestlers_for_weight_for_double_elim(@tournament.weights.first, @tournament.schools.first, 1, 20) + get :generate_matches, params: { id: @tournament.id } + redirect_tournament_error + end + + test "tournament generation error when a double elimination tournament has too few wrestlers" do + sign_in_owner + create_double_elim_tournament_single_weight(4, "Regular Double Elimination 1-8") + @tournament.destroy_all_matches + @tournament.user_id = 1 + @tournament.save + @tournament.weights.first.wrestlers.first.destroy + get :generate_matches, params: { id: @tournament.id } + redirect_tournament_error + end + + test "tournament generation error when a Modified 16 Man Double Elimination tournament has too many wrestlers" do + sign_in_owner + create_double_elim_tournament_single_weight(16, "Modified 16 Man Double Elimination 1-8") + @tournament.destroy_all_matches + @tournament.user_id = 1 + @tournament.save + create_wrestlers_for_weight_for_double_elim(@tournament.weights.first, @tournament.schools.first, 1, 20) + get :generate_matches, params: { id: @tournament.id } + redirect_tournament_error + end + + test "tournament generation error when a Modified 16 Man Double Elimination tournament has too few wrestlers" do + sign_in_owner + create_double_elim_tournament_single_weight(12, "Modified 16 Man Double Elimination 1-8") + @tournament.destroy_all_matches + @tournament.user_id = 1 + @tournament.save + @tournament.weights.first.wrestlers.first.destroy + get :generate_matches, params: { id: @tournament.id } + redirect_tournament_error + end + + test "tournament generation error when a pool to bracket tournament has too many wrestlers" do + sign_in_owner + create_pool_tournament_single_weight(24) + @tournament.destroy_all_matches + @tournament.user_id = 1 + @tournament.save + create_wrestlers_for_weight(@tournament.weights.first, @tournament.schools.first, 1, 20) + get :generate_matches, params: { id: @tournament.id } + redirect_tournament_error + end + + test "tournament generation error when a pool to bracket tournament has too few wrestlers" do + sign_in_owner + create_pool_tournament_single_weight(2) + @tournament.destroy_all_matches + @tournament.user_id = 1 + @tournament.save + @tournament.weights.first.wrestlers.first.destroy + get :generate_matches, params: { id: @tournament.id } + redirect_tournament_error + end end diff --git a/test/controllers/weights_controller_test.rb b/test/controllers/weights_controller_test.rb index 6c8df59..8b835f1 100644 --- a/test/controllers/weights_controller_test.rb +++ b/test/controllers/weights_controller_test.rb @@ -300,4 +300,109 @@ class WeightsControllerTest < ActionController::TestCase success end + test "tournament owner can update wrestler seeds" do + @tournament.is_public = true + @tournament.save + sign_in_owner + + # Prepare updated seed data for wrestlers + updated_seeds = { + @wrestler.id.to_s => { original_seed: "5" }, + @weight.wrestlers.second.id.to_s => { original_seed: "6" }, + @weight.wrestlers.third.id.to_s => { original_seed: "7" } + } + + # Submit the form with the updated seeds + post :show, params: { id: @weight.id, wrestler: updated_seeds } + + # Check if response is successful + assert_redirected_to weight_path(@weight.id) + + # Reload wrestlers to verify changes + @wrestler.reload + @weight.wrestlers.second.reload + @weight.wrestlers.third.reload + + # Verify seeds are updated + assert_equal 5, @wrestler.original_seed + assert_equal 6, @weight.wrestlers.second.original_seed + assert_equal 7, @weight.wrestlers.third.original_seed + end + + test "tournament delegate can update wrestler seeds" do + @tournament.is_public = true + @tournament.save + sign_in_tournament_delegate + + # Prepare updated seed data for wrestlers + updated_seeds = { + @wrestler.id.to_s => { original_seed: "8" }, + @weight.wrestlers.second.id.to_s => { original_seed: "9" }, + @weight.wrestlers.third.id.to_s => { original_seed: "10" } + } + + # Submit the form with the updated seeds + post :show, params: { id: @weight.id, wrestler: updated_seeds } + + # Check if response is successful + assert_redirected_to weight_path(@weight.id) + + # Reload wrestlers to verify changes + @wrestler.reload + @weight.wrestlers.second.reload + @weight.wrestlers.third.reload + + # Verify seeds are updated + assert_equal 8, @wrestler.original_seed + assert_equal 9, @weight.wrestlers.second.original_seed + assert_equal 10, @weight.wrestlers.third.original_seed + end + + test "unauthorized user cannot update wrestler seeds" do + @tournament.is_public = true + @tournament.save + sign_in_non_owner + + # Prepare updated seed data for wrestlers + updated_seeds = { + @wrestler.id.to_s => { original_seed: "11" }, + @weight.wrestlers.second.id.to_s => { original_seed: "12" } + } + + # Attempt to submit the form + post :show, params: { id: @weight.id, wrestler: updated_seeds } + + # Check if user is redirected due to lack of permissions + assert_redirected_to "/static_pages/not_allowed" + + # Verify seeds are not updated + @wrestler.reload + @weight.wrestlers.second.reload + assert_not_equal 11, @wrestler.original_seed + assert_not_equal 12, @weight.wrestlers.second.original_seed + end + + test "non logged in user cannot update wrestler seeds" do + @tournament.is_public = true + @tournament.save + + # Prepare updated seed data for wrestlers + updated_seeds = { + @wrestler.id.to_s => { original_seed: "11" }, + @weight.wrestlers.second.id.to_s => { original_seed: "12" } + } + + # Attempt to submit the form + post :show, params: { id: @weight.id, wrestler: updated_seeds } + + # Check if user is redirected due to lack of permissions + assert_redirected_to "/static_pages/not_allowed" + + # Verify seeds are not updated + @wrestler.reload + @weight.wrestlers.second.reload + assert_not_equal 11, @wrestler.original_seed + assert_not_equal 12, @weight.wrestlers.second.original_seed + end + end diff --git a/test/integration/pool_order_test.rb b/test/integration/pool_order_test.rb index b87c3af..1026167 100644 --- a/test/integration/pool_order_test.rb +++ b/test/integration/pool_order_test.rb @@ -468,4 +468,22 @@ class PoolAdvancementTest < ActionDispatch::IntegrationTest assert Wrestler.find(translate_name_to_id("Test2")).pool_placement_tiebreaker == "Head to Head" assert Wrestler.find(translate_name_to_id("Test1")).pool_placement == 4 end + + test "Pool order with 2 wrestlers" do + # Setup + Wrestler.find(translate_name_to_id("Test3")).destroy + Wrestler.find(translate_name_to_id("Test4")).destroy + Wrestler.find(translate_name_to_id("Test5")).destroy + Wrestler.find(translate_name_to_id("Test6")).destroy + GenerateTournamentMatches.new(Wrestler.find(translate_name_to_id("Test1")).tournament).generate + weight = Wrestler.find(translate_name_to_id("Test1")).weight + + # Match results + # Test1 is the best wrestler but got injured after round 1 and forfeited out + end_match_custom(match_wrestler_vs("Test1","Test2"),"Tech Fall","0-16","Test2") + + + assert Wrestler.find(translate_name_to_id("Test2")).pool_placement == 1 + assert Wrestler.find(translate_name_to_id("Test1")).pool_placement == 2 + end end \ No newline at end of file