From 8388af20f054504a569d8d2cc4b1e51edd8959c0 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Tue, 7 May 2019 09:51:37 +0200 Subject: [PATCH 01/35] Generalize tournament save interactor It now is responsible for saving all ApplicationRecord objects to the database. This will reduce code duplication one we have other objects that need to be saved. (As we will soon need to save individual matches) --- app/controllers/tournaments_controller.rb | 4 ++-- app/interactors/add_group_stage_to_tournament.rb | 2 +- app/interactors/add_playoffs_to_tournament.rb | 2 +- ...t_to_database.rb => save_application_record_object.rb} | 4 ++-- app/organizers/add_group_stage_to_tournament_and_save.rb | 7 +++++++ ...stage_to_tournament_and_save_tournament_to_database.rb | 7 ------- app/organizers/add_playoffs_to_tournament_and_save.rb | 7 +++++++ ...yoffs_to_tournament_and_save_tournament_to_database.rb | 7 ------- ...lication_record_object_to_database_interactor_spec.rb} | 8 ++++---- 9 files changed, 24 insertions(+), 24 deletions(-) rename app/interactors/{save_tournament_to_database.rb => save_application_record_object.rb} (63%) create mode 100644 app/organizers/add_group_stage_to_tournament_and_save.rb delete mode 100644 app/organizers/add_group_stage_to_tournament_and_save_tournament_to_database.rb create mode 100644 app/organizers/add_playoffs_to_tournament_and_save.rb delete mode 100644 app/organizers/add_playoffs_to_tournament_and_save_tournament_to_database.rb rename spec/interactors/{save_tournament_to_database_interactor_spec.rb => save_application_record_object_to_database_interactor_spec.rb} (72%) diff --git a/app/controllers/tournaments_controller.rb b/app/controllers/tournaments_controller.rb index 6a4a3e5..6f80705 100644 --- a/app/controllers/tournaments_controller.rb +++ b/app/controllers/tournaments_controller.rb @@ -38,14 +38,14 @@ class TournamentsController < ApplicationController if group_stage groups = organize_teams_in_groups(teams) # add groups to tournament - result = AddGroupStageToTournamentAndSaveTournamentToDatabase.call(tournament: tournament, groups: groups) + result = AddGroupStageToTournamentAndSave.call(tournament: tournament, groups: groups) else # convert teams parameter into Team objects teams = teams.map(&method(:find_or_create_team)) # associate provided teams with tournament tournament.teams = teams # add playoff stage to tournament - result = AddPlayoffsToTournamentAndSaveTournamentToDatabase.call(tournament: tournament) + result = AddPlayoffsToTournamentAndSave.call(tournament: tournament) end # validate tournament unless tournament.valid? diff --git a/app/interactors/add_group_stage_to_tournament.rb b/app/interactors/add_group_stage_to_tournament.rb index 14b798c..d1d28e2 100644 --- a/app/interactors/add_group_stage_to_tournament.rb +++ b/app/interactors/add_group_stage_to_tournament.rb @@ -10,7 +10,7 @@ class AddGroupStageToTournament begin group_stage = GroupStageService.generate_group_stage(groups) tournament.stages = [group_stage] - context.tournament = tournament + context.object_to_save = tournament rescue StandardError context.fail! end diff --git a/app/interactors/add_playoffs_to_tournament.rb b/app/interactors/add_playoffs_to_tournament.rb index fbe7f25..9efc2ec 100644 --- a/app/interactors/add_playoffs_to_tournament.rb +++ b/app/interactors/add_playoffs_to_tournament.rb @@ -12,7 +12,7 @@ class AddPlayoffsToTournament else tournament.stages.concat playoff_stages end - context.tournament = tournament + context.object_to_save = tournament else context.fail! end diff --git a/app/interactors/save_tournament_to_database.rb b/app/interactors/save_application_record_object.rb similarity index 63% rename from app/interactors/save_tournament_to_database.rb rename to app/interactors/save_application_record_object.rb index 40acf12..0bc2073 100644 --- a/app/interactors/save_tournament_to_database.rb +++ b/app/interactors/save_application_record_object.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -class SaveTournamentToDatabase +class SaveApplicationRecordObject include Interactor def call - if context.tournament.save + if context.object_to_save.save nil else context.fail! diff --git a/app/organizers/add_group_stage_to_tournament_and_save.rb b/app/organizers/add_group_stage_to_tournament_and_save.rb new file mode 100644 index 0000000..b1f1012 --- /dev/null +++ b/app/organizers/add_group_stage_to_tournament_and_save.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddGroupStageToTournamentAndSave + include Interactor::Organizer + + organize AddGroupStageToTournament, SaveApplicationRecordObject +end diff --git a/app/organizers/add_group_stage_to_tournament_and_save_tournament_to_database.rb b/app/organizers/add_group_stage_to_tournament_and_save_tournament_to_database.rb deleted file mode 100644 index 83710b5..0000000 --- a/app/organizers/add_group_stage_to_tournament_and_save_tournament_to_database.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -class AddGroupStageToTournamentAndSaveTournamentToDatabase - include Interactor::Organizer - - organize AddGroupStageToTournament, SaveTournamentToDatabase -end diff --git a/app/organizers/add_playoffs_to_tournament_and_save.rb b/app/organizers/add_playoffs_to_tournament_and_save.rb new file mode 100644 index 0000000..766add6 --- /dev/null +++ b/app/organizers/add_playoffs_to_tournament_and_save.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddPlayoffsToTournamentAndSave + include Interactor::Organizer + + organize AddPlayoffsToTournament, SaveApplicationRecordObject +end diff --git a/app/organizers/add_playoffs_to_tournament_and_save_tournament_to_database.rb b/app/organizers/add_playoffs_to_tournament_and_save_tournament_to_database.rb deleted file mode 100644 index d4466a0..0000000 --- a/app/organizers/add_playoffs_to_tournament_and_save_tournament_to_database.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -class AddPlayoffsToTournamentAndSaveTournamentToDatabase - include Interactor::Organizer - - organize AddPlayoffsToTournament, SaveTournamentToDatabase -end diff --git a/spec/interactors/save_tournament_to_database_interactor_spec.rb b/spec/interactors/save_application_record_object_to_database_interactor_spec.rb similarity index 72% rename from spec/interactors/save_tournament_to_database_interactor_spec.rb rename to spec/interactors/save_application_record_object_to_database_interactor_spec.rb index b10bba5..ce2edb3 100644 --- a/spec/interactors/save_tournament_to_database_interactor_spec.rb +++ b/spec/interactors/save_application_record_object_to_database_interactor_spec.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true -RSpec.describe SaveTournamentToDatabase do +RSpec.describe SaveApplicationRecordObject do before do @tournament = create(:tournament) end context 'save succeeds' do let(:context) do - SaveTournamentToDatabase.call(tournament: @tournament) + SaveApplicationRecordObject.call(object_to_save: @tournament) end before do expect_any_instance_of(Tournament) @@ -19,13 +19,13 @@ RSpec.describe SaveTournamentToDatabase do end it 'provides the tournament' do - expect(context.tournament).to eq(@tournament) + expect(context.object_to_save).to eq(@tournament) end end context 'save fails' do let(:context) do - SaveTournamentToDatabase.call(tournament: @tournament) + SaveApplicationRecordObject.call(object_to_save: @tournament) end before do expect_any_instance_of(Tournament) From 9cfead9723ff3a804cbb1020ec50dbea367d1c94 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Tue, 14 May 2019 13:30:20 +0200 Subject: [PATCH 02/35] Make save_application_record_object work with arrays --- app/interactors/save_application_record_object.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/interactors/save_application_record_object.rb b/app/interactors/save_application_record_object.rb index 0bc2073..9239a78 100644 --- a/app/interactors/save_application_record_object.rb +++ b/app/interactors/save_application_record_object.rb @@ -4,10 +4,8 @@ class SaveApplicationRecordObject include Interactor def call - if context.object_to_save.save - nil - else - context.fail! + Array(context.object_to_save).flatten.each do |object| + context.fail! unless object.save end end end From 1a2caaedef953b4e450ccda6edd41d1579cd6186 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 8 May 2019 21:55:44 +0200 Subject: [PATCH 03/35] Remove unused evaluate status method --- app/models/match.rb | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/models/match.rb b/app/models/match.rb index 8ab9756..8b3ba33 100644 --- a/app/models/match.rb +++ b/app/models/match.rb @@ -25,16 +25,6 @@ class Match < ApplicationRecord errors.add(:stage_xor_group, 'Stage and Group missing or both present') unless stage.present? ^ group.present? end - def evaluate_status - if score_team1 < score_team2 - :team2_won - elsif score_team2 < score_team1 - :team1_won - else - group_match? ? :undecided : :in_progress - end - end - def group_match? group.present? end From 280b0c1decf82613b02ef9948fda5e3b1f6bbb96 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 8 May 2019 21:57:12 +0200 Subject: [PATCH 04/35] Change status of Match to only represent being finished The winner will be a attribute of the Match instead of something that is written in its status. --- app/controllers/matches_controller.rb | 2 +- app/models/match.rb | 2 +- spec/controllers/matches_controller_spec.rb | 2 +- spec/factories/matches.rb | 4 ++-- .../add_playoffs_to_tournament_interactor_spec.rb | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/matches_controller.rb b/app/controllers/matches_controller.rb index c65b521..0d444fa 100644 --- a/app/controllers/matches_controller.rb +++ b/app/controllers/matches_controller.rb @@ -15,7 +15,7 @@ class MatchesController < ApplicationController new_state = match_params['state'] if new_state == 'finished' # implement logic to move the winning team into the next stage - match_params['state'] = 'team1_won' # or 'team2_won' or 'undecided' + match_params['state'] = 'finished' # or 'team2_won' or 'undecided' render json: {}, status: :not_implemented end if @match.update(match_params) diff --git a/app/models/match.rb b/app/models/match.rb index 8b3ba33..8007619 100644 --- a/app/models/match.rb +++ b/app/models/match.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Match < ApplicationRecord - enum state: %i[single_team not_ready not_started in_progress team1_won team2_won undecided] + enum state: %i[single_team not_ready not_started in_progress finished undecided] belongs_to :stage, optional: true belongs_to :group, optional: true diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index 10b0a30..c75a1c5 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -32,7 +32,7 @@ RSpec.describe MatchesController, type: :controller do let(:invalid_update) do { - state: 'team1_won' + state: 'finished' } end diff --git a/spec/factories/matches.rb b/spec/factories/matches.rb index 030c87c..43fb55d 100644 --- a/spec/factories/matches.rb +++ b/spec/factories/matches.rb @@ -27,7 +27,7 @@ FactoryBot.define do # random number generated by blapplications match.match_scores.first.points += 1 end - state { :team1_won } + state { :finished } end end @@ -51,7 +51,7 @@ FactoryBot.define do after(:create) do |match, evaluator| match.match_scores = create_list(:match_score, evaluator.match_scores_count, points: 3) end - state { :team1_won } + state { :finished } end end end diff --git a/spec/interactors/add_playoffs_to_tournament_interactor_spec.rb b/spec/interactors/add_playoffs_to_tournament_interactor_spec.rb index 056dc2b..884f0e8 100644 --- a/spec/interactors/add_playoffs_to_tournament_interactor_spec.rb +++ b/spec/interactors/add_playoffs_to_tournament_interactor_spec.rb @@ -14,10 +14,10 @@ RSpec.describe AddPlayoffsToTournament do end before do - @group_stage_tournament = create(:stage_tournament) - @playoff_stage_tournament = create(:tournament) - @full_tournament = create(:stage_tournament, stage_count: 5) - @stages = create_list(:stage, 5) + @group_stage_tournament = create(:group_stage_only_tournament, group_count: 0) + @playoff_stage_tournament = create(:stageless_tournament) + @full_tournament = create(:dummy_stage_tournament) + @stages = create_list(:stage, 3) end context 'PlayoffStageService mocked' do From 2f77d2d25b9d24dedb3c598d231222a97cdb8502 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 9 May 2019 09:09:54 +0200 Subject: [PATCH 05/35] Add winner method to match --- app/models/match.rb | 13 ++++++++++--- app/services/playoff_stage_service.rb | 7 +++++++ spec/models/match_spec.rb | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/app/models/match.rb b/app/models/match.rb index 8007619..2779fa7 100644 --- a/app/models/match.rb +++ b/app/models/match.rb @@ -19,13 +19,20 @@ class Match < ApplicationRecord stage ? stage.owner : group.owner end - private + def winner + return nil unless finished? + return nil if match_scores.first.points == match_scores.second.points - def stage_xor_group - errors.add(:stage_xor_group, 'Stage and Group missing or both present') unless stage.present? ^ group.present? + match_scores.max_by(&:points).team end def group_match? group.present? end + + private + + def stage_xor_group + errors.add(:stage_xor_group, 'Stage and Group missing or both present') unless stage.present? ^ group.present? + end end diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 340a9a2..ed0e19a 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -70,4 +70,11 @@ class PlayoffStageService stage_count.to_int end end + + def self.populate_match_below(match) + current_stage = match.stage + next_stage = match.stage.tournament.stages. + + puts + end end diff --git a/spec/models/match_spec.rb b/spec/models/match_spec.rb index 5acec23..0d4656c 100644 --- a/spec/models/match_spec.rb +++ b/spec/models/match_spec.rb @@ -43,6 +43,20 @@ RSpec.describe Match, type: :model do end end + context '#winner' do + it 'returns a winner Team for a decided match' do + decided_playoff_match = create(:decided_playoff_match) + winning_team_match_score = decided_playoff_match.match_scores.first + winning_team_match_score.points = 9999 + winning_team = winning_team_match_score.team + expect(decided_playoff_match.winner).to be winning_team + end + + it 'returns nil for an undecided match' do + expect(create(:undecided_group_match).winner).to be(nil) + end + end + context '#teams' do before do @playoff_match = create(:running_playoff_match) From 2c9e06946db674b51819c7fd70aa9d2e9909ad42 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Fri, 10 May 2019 11:44:11 +0200 Subject: [PATCH 06/35] Call populate_match_below when a match is finished --- app/controllers/matches_controller.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/controllers/matches_controller.rb b/app/controllers/matches_controller.rb index 0d444fa..1cfc05c 100644 --- a/app/controllers/matches_controller.rb +++ b/app/controllers/matches_controller.rb @@ -14,9 +14,7 @@ class MatchesController < ApplicationController def update new_state = match_params['state'] if new_state == 'finished' - # implement logic to move the winning team into the next stage - match_params['state'] = 'finished' # or 'team2_won' or 'undecided' - render json: {}, status: :not_implemented + PlayoffStageService.populate_match_below(@match) unless @match.group_match? end if @match.update(match_params) render json: @match From bc055843d983d5f4046a850007ad573de69e2409 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Fri, 10 May 2019 11:46:19 +0200 Subject: [PATCH 07/35] Test stopping of Matches --- spec/controllers/matches_controller_spec.rb | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index c75a1c5..35dd4e0 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -5,6 +5,8 @@ require 'rails_helper' RSpec.describe MatchesController, type: :controller do before do @match = create(:match, state: :not_started) + @tournament = create(:group_stage_tournament, stage_count: 3) + @running_playoff_match = @tournament.stages.find { |s| s.level == 3 }.matches.first @match.match_scores = create_pair(:match_score) end @@ -65,6 +67,38 @@ RSpec.describe MatchesController, type: :controller do end end + context 'as another owner' do + let(:finished) do + { + state: 'finished' + } + end + + before(:each) do + apply_authentication_headers_for @running_playoff_match.owner + end + + context 'stops the match' do + before do + @running_playoff_match.match_scores.each_with_index { |ms, i| ms.points = i } + @running_playoff_match.save + put :update, params: { id: @running_playoff_match.to_param }.merge(finished) + @running_playoff_match.reload + end + + it 'updates the matches status' do + expect(response).to be_successful + expect(@running_playoff_match.state).to eq(finished[:state]) + end + + it 'populates the match below' do + match_below = @tournament.stages.find { |s| s.level == 2 }.matches + .find { |m| m.position == @running_playoff_match.position / 2 }.reload + expect(match_below.teams).to include(@running_playoff_match.winner) + end + end + end + context 'as another user' do context 'with valid params' do before(:each) do From c9b07f7033f084e57d457e1f4acb240bb439a1ef Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Fri, 10 May 2019 11:48:10 +0200 Subject: [PATCH 08/35] Implement populate_match_below method --- app/services/playoff_stage_service.rb | 52 ++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index ed0e19a..dff0999 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -71,10 +71,54 @@ class PlayoffStageService end end - def self.populate_match_below(match) - current_stage = match.stage - next_stage = match.stage.tournament.stages. + def self.populate_match_with_winners(match, first_match, second_match) + match_scores = match.match_scores.sort_by(&:id) + matches = [first_match, second_match].sort_by(&:position) + winners = matches.map(&:winner) - puts + # depending on the amount of match_scores already present we need to do different things + case match_scores.size + when 0 + # when 0 match_scores are already there we create both of them with the respective winner from above + match_scores = winners.map { |winner| MatchScore.new(team: winner) } + when 1 + # when 1 match_score is present, we need to check which team is contained within and add the other team as well + team = nil + + if match_scores.first.team == winners.first + team = winners.second + elsif match_scores.first.team == winners.second + team = winners.first + else + match_scores.first.team = winners.first + team = winners.second + end + + match_scores.concat MatchScore.new(team: team) + when 2 + match_scores.first.team = winners.first + match_scores.second.team = winners.second + end + + # If a match is not decided yet, it will return nil as winner. + # This is not allowed in Database. The following code replaces MatchScores that contain nil as team with nil. + match_scores.map{ |ms| ms.team.nil? ? nil : ms} + match.match_scores = match_scores + end + + def self.populate_match_below(current_match) + current_stage = current_match.stage + next_stage = current_stage.tournament.stages.find { |s| s.level == current_stage.level - 1 } + return if next_stage.nil? + + current_position = current_match.position + next_position = current_position / 2 + + companion_match_position = current_position.even? ? current_position + 1 : current_position - 1 + companion_match = current_stage.matches.find { |m| m.position == companion_match_position } + + match_below = next_stage.matches.find { |m| m.position == next_position } + + populate_match_with_winners(match_below, current_match, companion_match) end end From d2f5d3594e18947f0c224d114d2042438114ede3 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Fri, 10 May 2019 22:04:20 +0200 Subject: [PATCH 09/35] Test performance optimization In general this generates less unnecessary faker data --- .../add_group_stage_to_tournament_interactor_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb b/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb index b64c752..0170d33 100644 --- a/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb +++ b/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb @@ -10,8 +10,8 @@ RSpec.describe AddGroupStageToTournament do end before do - @empty_tournament = create(:stage_tournament, stage_count: 0) - @group_stage_tournament = create(:group_stage_tournament) + @empty_tournament = create(:stage_less_tournament) + @group_stage_tournament = create(:group_stage_only_tournament, group_count: 0) @group_stage = create(:group_stage) @groups = Hash[1 => create_list(:team, 4), 2 => create_list(:team, 4)].values end From fc69c6e6e611b2cb5deda05bb873f53453e773d2 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sat, 11 May 2019 16:41:59 +0200 Subject: [PATCH 10/35] Implement PopulateMatchBelow Interactor & Organizer --- app/controllers/matches_controller.rb | 2 +- app/interactors/populate_match_below.rb | 15 +++++++++++++++ app/organizers/populate_match_below_and_save.rb | 7 +++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 app/interactors/populate_match_below.rb create mode 100644 app/organizers/populate_match_below_and_save.rb diff --git a/app/controllers/matches_controller.rb b/app/controllers/matches_controller.rb index 1cfc05c..28ee8ed 100644 --- a/app/controllers/matches_controller.rb +++ b/app/controllers/matches_controller.rb @@ -14,7 +14,7 @@ class MatchesController < ApplicationController def update new_state = match_params['state'] if new_state == 'finished' - PlayoffStageService.populate_match_below(@match) unless @match.group_match? + PopulateMatchBelowAndSave.call(match:@match) unless @match.group_match? end if @match.update(match_params) render json: @match diff --git a/app/interactors/populate_match_below.rb b/app/interactors/populate_match_below.rb new file mode 100644 index 0000000..55539f0 --- /dev/null +++ b/app/interactors/populate_match_below.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class PopulateMatchBelow + include Interactor + + def call + match = context.match + begin + PlayoffStageService.populate_match_below(match) + context.object_to_save = match + rescue StandardError + context.fail! + end + end +end diff --git a/app/organizers/populate_match_below_and_save.rb b/app/organizers/populate_match_below_and_save.rb new file mode 100644 index 0000000..e947b90 --- /dev/null +++ b/app/organizers/populate_match_below_and_save.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class PopulateMatchBelowAndSave + include Interactor::Organizer + + organize PopulateMatchBelow, SaveApplicationRecordObject +end From 12daf53599aad304808fb5cfa42f4328b0181024 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sat, 11 May 2019 17:15:23 +0200 Subject: [PATCH 11/35] Check for errors while populating the match below --- app/controllers/matches_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/matches_controller.rb b/app/controllers/matches_controller.rb index 28ee8ed..322387a 100644 --- a/app/controllers/matches_controller.rb +++ b/app/controllers/matches_controller.rb @@ -14,7 +14,11 @@ class MatchesController < ApplicationController def update new_state = match_params['state'] if new_state == 'finished' - PopulateMatchBelowAndSave.call(match:@match) unless @match.group_match? + result = PopulateMatchBelowAndSave.call(match: @match) unless @match.group_match? + unless result.success? + render json: { error: 'Moving Team one stage down failed' }, status: :unprocessable_entity + return + end end if @match.update(match_params) render json: @match From e4c868c150d78b2bd4ea3d3d0a5f353058872068 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sat, 11 May 2019 17:16:19 +0200 Subject: [PATCH 12/35] Fix second match winner advancing, even if match is not finished --- app/services/playoff_stage_service.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index dff0999..481bee5 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -74,7 +74,13 @@ class PlayoffStageService def self.populate_match_with_winners(match, first_match, second_match) match_scores = match.match_scores.sort_by(&:id) matches = [first_match, second_match].sort_by(&:position) - winners = matches.map(&:winner) + winners = [] + if second_match.finished? + winners = matches.map(&:winner) + else + winners = matches.map{ |m| + m == first_match ? m.winner : nil } + end # depending on the amount of match_scores already present we need to do different things case match_scores.size @@ -101,8 +107,8 @@ class PlayoffStageService end # If a match is not decided yet, it will return nil as winner. - # This is not allowed in Database. The following code replaces MatchScores that contain nil as team with nil. - match_scores.map{ |ms| ms.team.nil? ? nil : ms} + # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. + match_scores = match_scores.select { |ms| ms.team.present? } match.match_scores = match_scores end From 4e907b1fc885d8855aad3caf97144d9d9bbaa8e4 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sat, 11 May 2019 17:30:41 +0200 Subject: [PATCH 13/35] Improve Formatting in playoff_stage_service (I guess) ... Rubocop wanted it that way --- app/services/playoff_stage_service.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 481bee5..9d747a6 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -74,13 +74,13 @@ class PlayoffStageService def self.populate_match_with_winners(match, first_match, second_match) match_scores = match.match_scores.sort_by(&:id) matches = [first_match, second_match].sort_by(&:position) - winners = [] - if second_match.finished? - winners = matches.map(&:winner) - else - winners = matches.map{ |m| - m == first_match ? m.winner : nil } - end + winners = if second_match.finished? + matches.map(&:winner) + else + matches.map do |m| + m == first_match ? m.winner : nil + end + end # depending on the amount of match_scores already present we need to do different things case match_scores.size From 27d6269f94e101842e5ef086f18e2a326c35614a Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sun, 12 May 2019 15:16:56 +0200 Subject: [PATCH 14/35] Rearrange new methods into one to split it later on --- app/services/playoff_stage_service.rb | 41 +++++++++++++-------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 9d747a6..4ae90e8 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -71,14 +71,27 @@ class PlayoffStageService end end - def self.populate_match_with_winners(match, first_match, second_match) - match_scores = match.match_scores.sort_by(&:id) - matches = [first_match, second_match].sort_by(&:position) - winners = if second_match.finished? + + def self.populate_match_below(current_match) + current_stage = current_match.stage + next_stage = current_stage.tournament.stages.find { |s| s.level == current_stage.level - 1 } + return if next_stage.nil? + + current_position = current_match.position + next_position = current_position / 2 + + companion_match_position = current_position.even? ? current_position + 1 : current_position - 1 + companion_match = current_stage.matches.find { |m| m.position == companion_match_position } + + match_below = next_stage.matches.find { |m| m.position == next_position } + + match_scores = match_below.match_scores.sort_by(&:id) + matches = [current_match, companion_match].sort_by(&:position) + winners = if companion_match.finished? matches.map(&:winner) else matches.map do |m| - m == first_match ? m.winner : nil + m == current_match ? m.winner : nil end end @@ -109,22 +122,6 @@ class PlayoffStageService # If a match is not decided yet, it will return nil as winner. # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. match_scores = match_scores.select { |ms| ms.team.present? } - match.match_scores = match_scores - end - - def self.populate_match_below(current_match) - current_stage = current_match.stage - next_stage = current_stage.tournament.stages.find { |s| s.level == current_stage.level - 1 } - return if next_stage.nil? - - current_position = current_match.position - next_position = current_position / 2 - - companion_match_position = current_position.even? ? current_position + 1 : current_position - 1 - companion_match = current_stage.matches.find { |m| m.position == companion_match_position } - - match_below = next_stage.matches.find { |m| m.position == next_position } - - populate_match_with_winners(match_below, current_match, companion_match) + match_below.match_scores = match_scores end end From 7a9da4e22d12958d3def242c5e1e4c085b91827f Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sun, 12 May 2019 16:24:56 +0200 Subject: [PATCH 15/35] Rearrange methods in playoff_stage_service --- app/services/playoff_stage_service.rb | 56 ++++++++++++++++++--------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 4ae90e8..ce75551 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -71,31 +71,43 @@ class PlayoffStageService end end - def self.populate_match_below(current_match) current_stage = current_match.stage next_stage = current_stage.tournament.stages.find { |s| s.level == current_stage.level - 1 } + # return if next stage does not exist (there are no matches after the finale) return if next_stage.nil? current_position = current_match.position - next_position = current_position / 2 - companion_match_position = current_position.even? ? current_position + 1 : current_position - 1 - companion_match = current_stage.matches.find { |m| m.position == companion_match_position } - - match_below = next_stage.matches.find { |m| m.position == next_position } + # a "companion" match is the one that with the selected match makes up the two matches of which the winners advance + # into the match below + # depending on the position of the match, the companion match is either on the left or right of it + companion_match = find_companion_match(current_position, current_stage) + match_below = next_stage.matches.find { |m| m.position == current_position / 2 } match_scores = match_below.match_scores.sort_by(&:id) - matches = [current_match, companion_match].sort_by(&:position) - winners = if companion_match.finished? - matches.map(&:winner) - else - matches.map do |m| - m == current_match ? m.winner : nil - end - end + + winners = get_winners_of(companion_match, current_match) # depending on the amount of match_scores already present we need to do different things + match_scores = assign_correct_match_scores!(match_scores, winners) + + # If a match is not decided yet, it will return nil as winner. + # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. + match_scores = match_scores.select { |ms| ms.team.present? } + match_below.match_scores = match_scores + match_below.save + match_below + end + + private + + def self.find_companion_match(current_position, current_stage) + companion_match_position = current_position.even? ? current_position + 1 : current_position - 1 + current_stage.matches.find { |m| m.position == companion_match_position } + end + + def self.assign_correct_match_scores!(match_scores, winners) case match_scores.size when 0 # when 0 match_scores are already there we create both of them with the respective winner from above @@ -115,13 +127,21 @@ class PlayoffStageService match_scores.concat MatchScore.new(team: team) when 2 + # when 2 match_scores are present, the teams just get overwritten match_scores.first.team = winners.first match_scores.second.team = winners.second end + match_scores + end - # If a match is not decided yet, it will return nil as winner. - # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. - match_scores = match_scores.select { |ms| ms.team.present? } - match_below.match_scores = match_scores + def self.get_winners_of(companion_match, current_match) + matches = [current_match, companion_match].sort_by(&:position) + if companion_match.finished? + matches.map(&:winner) + else + matches.map do |m| + m == current_match ? m.winner : nil + end + end end end From 2b39bb15213b9bed8d679bb83b7402b4259cfda9 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Mon, 13 May 2019 11:04:44 +0200 Subject: [PATCH 16/35] Move populating the match below to when the state is changed --- app/controllers/matches_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/matches_controller.rb b/app/controllers/matches_controller.rb index 322387a..d64c60d 100644 --- a/app/controllers/matches_controller.rb +++ b/app/controllers/matches_controller.rb @@ -13,14 +13,14 @@ class MatchesController < ApplicationController # PATCH/PUT /matches/1 def update new_state = match_params['state'] - if new_state == 'finished' - result = PopulateMatchBelowAndSave.call(match: @match) unless @match.group_match? - unless result.success? - render json: { error: 'Moving Team one stage down failed' }, status: :unprocessable_entity - return - end - end if @match.update(match_params) + if new_state == 'finished' + result = PopulateMatchBelowAndSave.call(match: @match) unless @match.group_match? + unless result.success? + render json: { error: 'Moving Team one stage down failed' }, status: :unprocessable_entity + return + end + end render json: @match else render json: @match.errors, status: :unprocessable_entity From 93cea002f97cfc00b85e70f90d0b1a97c23f4f8c Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Mon, 13 May 2019 11:06:34 +0200 Subject: [PATCH 17/35] Change the way, existing match_scores are handled --- app/services/playoff_stage_service.rb | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index ce75551..ce86980 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -114,18 +114,14 @@ class PlayoffStageService match_scores = winners.map { |winner| MatchScore.new(team: winner) } when 1 # when 1 match_score is present, we need to check which team is contained within and add the other team as well - team = nil - if match_scores.first.team == winners.first - team = winners.second + match_scores.push MatchScore.new(team: winners.second) elsif match_scores.first.team == winners.second - team = winners.first + match_scores.push MatchScore.new(team: winners.first) else - match_scores.first.team = winners.first - team = winners.second + match_scores.first.destroy + match_scores = winners.map { |winner| MatchScore.new(team: winner) } end - - match_scores.concat MatchScore.new(team: team) when 2 # when 2 match_scores are present, the teams just get overwritten match_scores.first.team = winners.first @@ -136,12 +132,6 @@ class PlayoffStageService def self.get_winners_of(companion_match, current_match) matches = [current_match, companion_match].sort_by(&:position) - if companion_match.finished? - matches.map(&:winner) - else - matches.map do |m| - m == current_match ? m.winner : nil - end - end + matches.map(&:winner) end end From cda7d168f5c98872cd5e5e7434750f300b00ecf8 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Mon, 13 May 2019 11:06:52 +0200 Subject: [PATCH 18/35] Save match_scores explicitly after changing them --- app/services/playoff_stage_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index ce86980..8cd5bc3 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -95,6 +95,7 @@ class PlayoffStageService # If a match is not decided yet, it will return nil as winner. # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. match_scores = match_scores.select { |ms| ms.team.present? } + match_scores.each(&:save) match_below.match_scores = match_scores match_below.save match_below From e0ef39cc4b2aeb4ee358e86a973e788cee4efce2 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Mon, 13 May 2019 11:07:13 +0200 Subject: [PATCH 19/35] Test populate_match_below method --- spec/services/playoff_stage_service_spec.rb | 69 +++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/spec/services/playoff_stage_service_spec.rb b/spec/services/playoff_stage_service_spec.rb index 46dfe55..a5de8fd 100644 --- a/spec/services/playoff_stage_service_spec.rb +++ b/spec/services/playoff_stage_service_spec.rb @@ -80,4 +80,73 @@ RSpec.describe PlayoffStageService do end end end + + describe '#populate_match_below' do + before :each do + @tournament = create(:stage_tournament, stage_count: 2) + @match = @tournament.stages.find { |s| s.level == 2 }.matches.first + @match.state = :finished + @match.match_scores.each_with_index { |ms, i| ms.points = i } + @match.save + @companion_match = @tournament.stages.find { |s| s.level == 2 }.matches.second + @companion_match.match_scores.each_with_index { |ms, i| ms.points = i } + @companion_match.save + @match_to_find = @tournament.stages.find { |s| s.level == 1 }.matches.first + end + + context 'match below has no match_scores' do + it 'finds the correct match and adds two new match_scores to it' do + @match_to_find.match_scores = [] + @match_to_find.save + PlayoffStageService.populate_match_below(@match) + @match_to_find.reload + expect(@match_to_find.teams).to match_array(@match.winner) + end + end + + context 'match below has one match_score with the winning team' do + it 'finds the correct match and adds no match_score' do + @match_to_find.match_scores = create_list(:match_score, 1, team: @match.winner) + @match_to_find.save + PlayoffStageService.populate_match_below(@match) + @match_to_find.reload + expect(@match_to_find.teams).to match_array(@match.winner) + end + end + + context 'match below has one match_score with an unknown team' do + it 'finds the correct match and replaces the match_score' do + @match_to_find.match_scores = create_list(:match_score, 1, team: create(:team), points: 1337) + @match_to_find.save + PlayoffStageService.populate_match_below(@match) + @match_to_find.reload + expect(@match_to_find.teams).to match_array(@match.winner) + expect(@match_to_find.match_scores.first.points).to_not be(1337) + end + end + + context 'match below has one match_score with the correct team' do + it 'finds the correct match and replaces nothing' do + @match_to_find.match_scores = create_list(:match_score, 1, team: @match.winner, points: 42) + @match_to_find.save + PlayoffStageService.populate_match_below(@match) + @match_to_find.reload + expect(@match_to_find.teams).to match_array(@match.winner) + expect(@match_to_find.match_scores.first.points).to be(42) + end + end + + context 'match below has two match_scores with the correct teams' do + it 'finds the correct match and replaces nothing' do + @companion_match.state = :finished + @companion_match.save + @match_to_find.match_scores = [create(:match_score, team: @match.winner), + create(:match_score, team: @companion_match.winner)] + @match_to_find.save + PlayoffStageService.populate_match_below(@match) + @match_to_find.reload + expect(@match_to_find.teams).to match_array([@match.winner, @companion_match.winner]) + end + end + end end From 95bed3959f15d327963ea69ce6f28addfc9aad17 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Mon, 13 May 2019 13:57:23 +0200 Subject: [PATCH 20/35] Actually make singleton_methods private (Rubocop told me so and I trust the police) --- app/services/playoff_stage_service.rb | 62 ++++++++++++++------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 8cd5bc3..f6beb54 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -101,38 +101,40 @@ class PlayoffStageService match_below end - private + class << self + private - def self.find_companion_match(current_position, current_stage) - companion_match_position = current_position.even? ? current_position + 1 : current_position - 1 - current_stage.matches.find { |m| m.position == companion_match_position } - end - - def self.assign_correct_match_scores!(match_scores, winners) - case match_scores.size - when 0 - # when 0 match_scores are already there we create both of them with the respective winner from above - match_scores = winners.map { |winner| MatchScore.new(team: winner) } - when 1 - # when 1 match_score is present, we need to check which team is contained within and add the other team as well - if match_scores.first.team == winners.first - match_scores.push MatchScore.new(team: winners.second) - elsif match_scores.first.team == winners.second - match_scores.push MatchScore.new(team: winners.first) - else - match_scores.first.destroy - match_scores = winners.map { |winner| MatchScore.new(team: winner) } - end - when 2 - # when 2 match_scores are present, the teams just get overwritten - match_scores.first.team = winners.first - match_scores.second.team = winners.second + def find_companion_match(current_position, current_stage) + companion_match_position = current_position.even? ? current_position + 1 : current_position - 1 + current_stage.matches.find { |m| m.position == companion_match_position } end - match_scores - end - def self.get_winners_of(companion_match, current_match) - matches = [current_match, companion_match].sort_by(&:position) - matches.map(&:winner) + def assign_correct_match_scores!(match_scores, winners) + case match_scores.size + when 0 + # when 0 match_scores are already there we create both of them with the respective winner from above + match_scores = winners.map { |winner| MatchScore.new(team: winner) } + when 1 + # when 1 match_score is present, we need to check which team is contained within and add the other team as well + if match_scores.first.team == winners.first + match_scores.push MatchScore.new(team: winners.second) + elsif match_scores.first.team == winners.second + match_scores.push MatchScore.new(team: winners.first) + else + match_scores.first.destroy + match_scores = winners.map { |winner| MatchScore.new(team: winner) } + end + when 2 + # when 2 match_scores are present, the teams just get overwritten + match_scores.first.team = winners.first + match_scores.second.team = winners.second + end + match_scores + end + + def get_winners_of(companion_match, current_match) + matches = [current_match, companion_match].sort_by(&:position) + matches.map(&:winner) + end end end From 645f3d080099fdef6b1adc31a0affe7f1875c376 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Tue, 14 May 2019 13:43:44 +0200 Subject: [PATCH 21/35] Return changed objects in populate_match_below --- app/interactors/populate_match_below.rb | 4 ++-- app/services/playoff_stage_service.rb | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/interactors/populate_match_below.rb b/app/interactors/populate_match_below.rb index 55539f0..96a58c3 100644 --- a/app/interactors/populate_match_below.rb +++ b/app/interactors/populate_match_below.rb @@ -6,8 +6,8 @@ class PopulateMatchBelow def call match = context.match begin - PlayoffStageService.populate_match_below(match) - context.object_to_save = match + objects_to_save = PlayoffStageService.populate_match_below(match) + context.object_to_save = objects_to_save rescue StandardError context.fail! end diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index f6beb54..60d236b 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -71,6 +71,10 @@ class PlayoffStageService end end + # Populates the match below given match with the winners of the matches above + # + # @param current_match [Match] The Match which finished, the match below it gets populated + # @return [Array] the objects that changed and need to be saved def self.populate_match_below(current_match) current_stage = current_match.stage next_stage = current_stage.tournament.stages.find { |s| s.level == current_stage.level - 1 } @@ -95,10 +99,8 @@ class PlayoffStageService # If a match is not decided yet, it will return nil as winner. # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. match_scores = match_scores.select { |ms| ms.team.present? } - match_scores.each(&:save) match_below.match_scores = match_scores - match_below.save - match_below + [match_below, match_scores].flatten end class << self From d0d38a79728018713491782fca871cd7e1ed25ec Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Tue, 14 May 2019 13:44:02 +0200 Subject: [PATCH 22/35] Test populate_match_below Interactor --- .../populate_match_below_interactor_spec.rb | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 spec/interactors/populate_match_below_interactor_spec.rb diff --git a/spec/interactors/populate_match_below_interactor_spec.rb b/spec/interactors/populate_match_below_interactor_spec.rb new file mode 100644 index 0000000..8b751e0 --- /dev/null +++ b/spec/interactors/populate_match_below_interactor_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +RSpec.describe PopulateMatchBelow do + before do + @match = create(:match) + @objects_to_save = [create(:match), create_list(:match_score, 2)] + end + + context 'no exception' do + let(:context) do + PopulateMatchBelow.call(match: @match) + end + before do + allow(PlayoffStageService) + .to receive(:populate_match_below).with(@match) + .and_return(@objects_to_save) + end + + it 'succeeds' do + expect(context).to be_a_success + end + + it 'provides the objects to save' do + expect(context.object_to_save).to match_array(@objects_to_save) + end + end + + context 'exception is thrown' do + let(:context) do + PopulateMatchBelow.call(match: @match) + end + before do + allow(PlayoffStageService) + .to receive(:populate_match_below).with(@match) + .and_throw('This failed :(') + end + + it 'fails' do + test = context.failure? + expect(test).to eq(true) + end + end +end From 0337b6fad8d2b4700eff59810b347b22d37f92d6 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Tue, 14 May 2019 14:57:13 +0200 Subject: [PATCH 23/35] Save match_scores after editing them in tests --- spec/controllers/matches_controller_spec.rb | 6 ++++-- spec/services/playoff_stage_service_spec.rb | 11 ++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index 35dd4e0..ee47017 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -80,8 +80,10 @@ RSpec.describe MatchesController, type: :controller do context 'stops the match' do before do - @running_playoff_match.match_scores.each_with_index { |ms, i| ms.points = i } - @running_playoff_match.save + @running_playoff_match.match_scores.each_with_index do |ms, i| + ms.points = i + ms.save + end put :update, params: { id: @running_playoff_match.to_param }.merge(finished) @running_playoff_match.reload end diff --git a/spec/services/playoff_stage_service_spec.rb b/spec/services/playoff_stage_service_spec.rb index a5de8fd..3e8812f 100644 --- a/spec/services/playoff_stage_service_spec.rb +++ b/spec/services/playoff_stage_service_spec.rb @@ -86,11 +86,16 @@ RSpec.describe PlayoffStageService do @tournament = create(:stage_tournament, stage_count: 2) @match = @tournament.stages.find { |s| s.level == 2 }.matches.first @match.state = :finished - @match.match_scores.each_with_index { |ms, i| ms.points = i } + @match.match_scores.each_with_index do |ms, i| + ms.points = i + ms.save + end @match.save @companion_match = @tournament.stages.find { |s| s.level == 2 }.matches.second - @companion_match.match_scores.each_with_index { |ms, i| ms.points = i } - @companion_match.save + @companion_match.match_scores.each_with_index do |ms, i| + ms.points = i + ms.save + end @match_to_find = @tournament.stages.find { |s| s.level == 1 }.matches.first end From 5457d50277d2f7da8a97fcaedad130a064b62cc9 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 22 May 2019 09:00:28 +0200 Subject: [PATCH 24/35] Simplify code finding the tournament Co-Authored-By: Thor77 --- spec/controllers/matches_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index ee47017..74f2da5 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe MatchesController, type: :controller do before do @match = create(:match, state: :not_started) @tournament = create(:group_stage_tournament, stage_count: 3) - @running_playoff_match = @tournament.stages.find { |s| s.level == 3 }.matches.first + @running_playoff_match = @tournament.stages.find_by(level: 3).matches.first @match.match_scores = create_pair(:match_score) end From 74b345dce4dd7f49be96f390fe199e7c1004278e Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 23 May 2019 11:57:48 +0200 Subject: [PATCH 25/35] Fix factory name for stage tournament --- spec/controllers/matches_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index 74f2da5..63e6abc 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -5,8 +5,8 @@ require 'rails_helper' RSpec.describe MatchesController, type: :controller do before do @match = create(:match, state: :not_started) - @tournament = create(:group_stage_tournament, stage_count: 3) - @running_playoff_match = @tournament.stages.find_by(level: 3).matches.first + @tournament = create(:stage_tournament, stage_count: 2) + @running_playoff_match = @tournament.stages.find_by(level: 2).matches.first @match.match_scores = create_pair(:match_score) end From 21c79665e1c48e04fb2c7d029ff9f0e709cb99e7 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sun, 26 May 2019 20:01:14 +0200 Subject: [PATCH 26/35] Check if .winner returns a Team This is done to prevent Test from succeeding if both .winner and .teams return nil --- spec/controllers/matches_controller_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index 63e6abc..ff12c79 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -96,6 +96,7 @@ RSpec.describe MatchesController, type: :controller do it 'populates the match below' do match_below = @tournament.stages.find { |s| s.level == 2 }.matches .find { |m| m.position == @running_playoff_match.position / 2 }.reload + expect(@running_playoff_match.winner).to be_a(Team) expect(match_below.teams).to include(@running_playoff_match.winner) end end From d61b3b2b639b4c1592f96905a06d8c1da15384d3 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 23 May 2019 12:01:34 +0200 Subject: [PATCH 27/35] Fix factory name for stageless tournament --- .../add_group_stage_to_tournament_interactor_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb b/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb index 0170d33..d7a3208 100644 --- a/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb +++ b/spec/interactors/add_group_stage_to_tournament_interactor_spec.rb @@ -10,7 +10,7 @@ RSpec.describe AddGroupStageToTournament do end before do - @empty_tournament = create(:stage_less_tournament) + @empty_tournament = create(:stageless_tournament) @group_stage_tournament = create(:group_stage_only_tournament, group_count: 0) @group_stage = create(:group_stage) @groups = Hash[1 => create_list(:team, 4), 2 => create_list(:team, 4)].values From 9f92ca7e5bbd85ad73febd4ccda3adc4b47bc251 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 23 May 2019 13:20:59 +0200 Subject: [PATCH 28/35] Move stopping of matches test --- spec/controllers/matches_controller_spec.rb | 68 ++++++++++----------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index ff12c79..9e3a26e 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -57,6 +57,39 @@ RSpec.describe MatchesController, type: :controller do body = deserialize_response response expect(body[:state]).to eq(valid_update[:state]) end + + context 'on a running playoff match' do + let(:finished) do + { + state: 'finished' + } + end + + before(:each) do + apply_authentication_headers_for @running_playoff_match.owner + end + + before do + @running_playoff_match.match_scores.each_with_index do |ms, i| + ms.points = i + ms.save + end + put :update, params: { id: @running_playoff_match.to_param }.merge(finished) + @running_playoff_match.reload + end + + it 'updates the matches status' do + expect(response).to be_successful + expect(@running_playoff_match.state).to eq(finished[:state]) + end + + it 'populates the match below' do + match_below = @tournament.stages.find { |s| s.level == 2 }.matches + .find { |m| m.position == @running_playoff_match.position / 2 }.reload + expect(@running_playoff_match.winner).to be_a(Team) + expect(match_below.teams).to include(@running_playoff_match.winner) + end + end end context 'with invalid params' do @@ -67,41 +100,6 @@ RSpec.describe MatchesController, type: :controller do end end - context 'as another owner' do - let(:finished) do - { - state: 'finished' - } - end - - before(:each) do - apply_authentication_headers_for @running_playoff_match.owner - end - - context 'stops the match' do - before do - @running_playoff_match.match_scores.each_with_index do |ms, i| - ms.points = i - ms.save - end - put :update, params: { id: @running_playoff_match.to_param }.merge(finished) - @running_playoff_match.reload - end - - it 'updates the matches status' do - expect(response).to be_successful - expect(@running_playoff_match.state).to eq(finished[:state]) - end - - it 'populates the match below' do - match_below = @tournament.stages.find { |s| s.level == 2 }.matches - .find { |m| m.position == @running_playoff_match.position / 2 }.reload - expect(@running_playoff_match.winner).to be_a(Team) - expect(match_below.teams).to include(@running_playoff_match.winner) - end - end - end - context 'as another user' do context 'with valid params' do before(:each) do From 8bdcd51e6632aeb3254320a2d05195fc064624a1 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 23 May 2019 13:32:22 +0200 Subject: [PATCH 29/35] Move all methods in playoff_stage_service into self block --- app/services/playoff_stage_service.rb | 204 +++++++++++++------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 60d236b..080df96 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -1,109 +1,109 @@ # frozen_string_literal: true class PlayoffStageService - # Generates the playoff stage given the tournament - # - # @param teams [Array] The teams to generate the playoff stages with - # @return [Array] the generated playoff stages - def self.generate_playoff_stages(teams) - playoffs = [] - stage_count = calculate_required_stage_count(teams.size) - # initial_matches are the matches in the first stage; this is the only stage filled with teams from the start on - initial_matches = MatchService.generate_matches(teams) - initial_stage = Stage.new level: stage_count - 1, matches: initial_matches - playoffs << initial_stage - # empty stages are the stages, the tournament is filled with to have the matches ready for later - empty_stages = generate_stages_with_empty_matches(stage_count - 1) - empty_stages.each do |stage| - playoffs << stage - end - playoffs - end - - # Generates the playoff stage given the tournament - # - # @param tournament [Tournament] The tournament to generate the playoff stages from - # @return [Array] the generated playoff stages - def self.generate_playoff_stages_from_tournament(tournament) - generate_playoff_stages tournament.teams - end - - # Generates given number of empty stages - # - # @param stage_count [Integer] number of stages to generate - # @return [Array] the generated stages - def self.generate_stages_with_empty_matches(stage_count) - empty_stages = [] - stage_count.times do |i| - stage = Stage.new level: i, matches: generate_empty_matches(2**i) - empty_stages << stage - end - # as we are generating the stages in the wrong order (starting with the lowest number of matches (which is - # the final stage)) they need to be reversed - empty_stages.reverse! - end - - # Generates a number of empty matches to fill later stages - # - # @param amount [Integer] the amount of matches to generate - # @return [Array] the generated matches - def self.generate_empty_matches(amount) - matches = [] - amount.times do |i| - match = Match.new state: :not_ready, position: i - matches << match - end - matches - end - - # Calculates how many stages are required for given number of teams - # - # @param number_of_teams [Integer] the teams number of teams to calculate amount of stages - # @return [Integer] amount of required stages - def self.calculate_required_stage_count(number_of_teams) - if number_of_teams == 1 - 1 - else - # black voodoo magic - stage_count = Math.log(Utils.next_power_of_two(number_of_teams)) / Math.log(2) - stage_count -= 1 if Utils.po2?(number_of_teams) - stage_count.to_int - end - end - - # Populates the match below given match with the winners of the matches above - # - # @param current_match [Match] The Match which finished, the match below it gets populated - # @return [Array] the objects that changed and need to be saved - def self.populate_match_below(current_match) - current_stage = current_match.stage - next_stage = current_stage.tournament.stages.find { |s| s.level == current_stage.level - 1 } - # return if next stage does not exist (there are no matches after the finale) - return if next_stage.nil? - - current_position = current_match.position - - # a "companion" match is the one that with the selected match makes up the two matches of which the winners advance - # into the match below - # depending on the position of the match, the companion match is either on the left or right of it - companion_match = find_companion_match(current_position, current_stage) - - match_below = next_stage.matches.find { |m| m.position == current_position / 2 } - match_scores = match_below.match_scores.sort_by(&:id) - - winners = get_winners_of(companion_match, current_match) - - # depending on the amount of match_scores already present we need to do different things - match_scores = assign_correct_match_scores!(match_scores, winners) - - # If a match is not decided yet, it will return nil as winner. - # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. - match_scores = match_scores.select { |ms| ms.team.present? } - match_below.match_scores = match_scores - [match_below, match_scores].flatten - end - class << self + # Generates the playoff stage given the tournament + # + # @param teams [Array] The teams to generate the playoff stages with + # @return [Array] the generated playoff stages + def generate_playoff_stages(teams) + playoffs = [] + stage_count = calculate_required_stage_count(teams.size) + # initial_matches are the matches in the first stage; this is the only stage filled with teams from the start on + initial_matches = MatchService.generate_matches(teams) + initial_stage = Stage.new level: stage_count - 1, matches: initial_matches + playoffs << initial_stage + # empty stages are the stages, the tournament is filled with to have the matches ready for later + empty_stages = generate_stages_with_empty_matches(stage_count - 1) + empty_stages.each do |stage| + playoffs << stage + end + playoffs + end + + # Generates the playoff stage given the tournament + # + # @param tournament [Tournament] The tournament to generate the playoff stages from + # @return [Array] the generated playoff stages + def generate_playoff_stages_from_tournament(tournament) + generate_playoff_stages tournament.teams + end + + # Generates given number of empty stages + # + # @param stage_count [Integer] number of stages to generate + # @return [Array] the generated stages + def generate_stages_with_empty_matches(stage_count) + empty_stages = [] + stage_count.times do |i| + stage = Stage.new level: i, matches: generate_empty_matches(2**i) + empty_stages << stage + end + # as we are generating the stages in the wrong order (starting with the lowest number of matches (which is + # the final stage)) they need to be reversed + empty_stages.reverse! + end + + # Generates a number of empty matches to fill later stages + # + # @param amount [Integer] the amount of matches to generate + # @return [Array] the generated matches + def generate_empty_matches(amount) + matches = [] + amount.times do |i| + match = Match.new state: :not_ready, position: i + matches << match + end + matches + end + + # Calculates how many stages are required for given number of teams + # + # @param number_of_teams [Integer] the teams number of teams to calculate amount of stages + # @return [Integer] amount of required stages + def calculate_required_stage_count(number_of_teams) + if number_of_teams == 1 + 1 + else + # black voodoo magic + stage_count = Math.log(Utils.next_power_of_two(number_of_teams)) / Math.log(2) + stage_count -= 1 if Utils.po2?(number_of_teams) + stage_count.to_int + end + end + + # Populates the match below given match with the winners of the matches above + # + # @param current_match [Match] The Match which finished, the match below it gets populated + # @return [Array] the objects that changed and need to be saved + def populate_match_below(current_match) + current_stage = current_match.stage + next_stage = current_stage.tournament.stages.find { |s| s.level == current_stage.level - 1 } + # return if next stage does not exist (there are no matches after the finale) + return if next_stage.nil? + + current_position = current_match.position + + # a "companion" match is the one that with the selected match makes up the two matches + # of which the winners advance into the match below + # depending on the position of the match, the companion match is either on the left or right of it + companion_match = find_companion_match(current_position, current_stage) + + match_below = next_stage.matches.find { |m| m.position == current_position / 2 } + match_scores = match_below.match_scores.sort_by(&:id) + + winners = get_winners_of(companion_match, current_match) + + # depending on the amount of match_scores already present we need to do different things + match_scores = assign_correct_match_scores!(match_scores, winners) + + # If a match is not decided yet, it will return nil as winner. + # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. + match_scores = match_scores.select { |ms| ms.team.present? } + match_below.match_scores = match_scores + [match_below, match_scores].flatten + end + private def find_companion_match(current_position, current_stage) From 8dd1f0b07ca9637829802b7c061f69d0a5ec6ddc Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Fri, 24 May 2019 13:15:47 +0200 Subject: [PATCH 30/35] Rearrange Test Code --- spec/controllers/matches_controller_spec.rb | 20 +++++--- spec/services/playoff_stage_service_spec.rb | 52 ++++++++++++--------- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index 9e3a26e..c034a1a 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -5,8 +5,9 @@ require 'rails_helper' RSpec.describe MatchesController, type: :controller do before do @match = create(:match, state: :not_started) - @tournament = create(:stage_tournament, stage_count: 2) - @running_playoff_match = @tournament.stages.find_by(level: 2).matches.first + @amount_of_stages = 2 + @tournament = create(:stage_tournament, stage_count: @amount_of_stages) + @running_playoff_match = @tournament.stages.find_by(level: @amount_of_stages).matches.first @match.match_scores = create_pair(:match_score) end @@ -83,11 +84,16 @@ RSpec.describe MatchesController, type: :controller do expect(@running_playoff_match.state).to eq(finished[:state]) end - it 'populates the match below' do - match_below = @tournament.stages.find { |s| s.level == 2 }.matches - .find { |m| m.position == @running_playoff_match.position / 2 }.reload - expect(@running_playoff_match.winner).to be_a(Team) - expect(match_below.teams).to include(@running_playoff_match.winner) + describe 'updates the match below' do + before do + @match_below = @tournament.stages.find_by(level: @amount_of_stages - 1).matches + .find_by(position: @running_playoff_match.position / 2).reload + end + + it 'with the right teams' do + expect(@running_playoff_match.winner).to be_a(Team) + expect(@match_below.teams).to include(@running_playoff_match.winner) + end end end end diff --git a/spec/services/playoff_stage_service_spec.rb b/spec/services/playoff_stage_service_spec.rb index 3e8812f..ccab2d3 100644 --- a/spec/services/playoff_stage_service_spec.rb +++ b/spec/services/playoff_stage_service_spec.rb @@ -100,57 +100,67 @@ RSpec.describe PlayoffStageService do end context 'match below has no match_scores' do - it 'finds the correct match and adds two new match_scores to it' do + before do @match_to_find.match_scores = [] @match_to_find.save - PlayoffStageService.populate_match_below(@match) - @match_to_find.reload + @test = PlayoffStageService.populate_match_below(@match).first + end + + it 'finds the correct match and adds two new match_scores to it' do expect(@match_to_find.teams).to match_array(@match.winner) end end context 'match below has one match_score with the winning team' do - it 'finds the correct match and adds no match_score' do + before do @match_to_find.match_scores = create_list(:match_score, 1, team: @match.winner) @match_to_find.save - PlayoffStageService.populate_match_below(@match) - @match_to_find.reload - expect(@match_to_find.teams).to match_array(@match.winner) + @test = PlayoffStageService.populate_match_below(@match).first + end + + it 'finds the correct match and adds no match_score' do + expect(@test.teams).to match_array(@match.winner) end end context 'match below has one match_score with an unknown team' do - it 'finds the correct match and replaces the match_score' do + before do @match_to_find.match_scores = create_list(:match_score, 1, team: create(:team), points: 1337) @match_to_find.save - PlayoffStageService.populate_match_below(@match) - @match_to_find.reload - expect(@match_to_find.teams).to match_array(@match.winner) - expect(@match_to_find.match_scores.first.points).to_not be(1337) + @test = PlayoffStageService.populate_match_below(@match).first + end + + it 'finds the correct match and replaces the match_score' do + expect(@test.teams).to match_array(@match.winner) + expect(@test.match_scores.first.points).to_not be(1337) end end context 'match below has one match_score with the correct team' do - it 'finds the correct match and replaces nothing' do + before do @match_to_find.match_scores = create_list(:match_score, 1, team: @match.winner, points: 42) @match_to_find.save - PlayoffStageService.populate_match_below(@match) - @match_to_find.reload - expect(@match_to_find.teams).to match_array(@match.winner) - expect(@match_to_find.match_scores.first.points).to be(42) + @test = PlayoffStageService.populate_match_below(@match).first + end + + it 'finds the correct match and replaces nothing' do + expect(@test.teams).to match_array(@match.winner) + expect(@test.match_scores.first.points).to be(42) end end context 'match below has two match_scores with the correct teams' do - it 'finds the correct match and replaces nothing' do + before do @companion_match.state = :finished @companion_match.save @match_to_find.match_scores = [create(:match_score, team: @match.winner), create(:match_score, team: @companion_match.winner)] @match_to_find.save - PlayoffStageService.populate_match_below(@match) - @match_to_find.reload - expect(@match_to_find.teams).to match_array([@match.winner, @companion_match.winner]) + @test = PlayoffStageService.populate_match_below(@match).first + end + + it 'finds the correct match and replaces nothing' do + expect(@test.teams).to match_array([@match.winner, @companion_match.winner]) end end end From 6f44823bc60ca95fd3c125a885fd80c009403476 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Fri, 24 May 2019 13:32:40 +0200 Subject: [PATCH 31/35] Change match state of match below --- app/services/playoff_stage_service.rb | 7 +++++++ spec/controllers/matches_controller_spec.rb | 4 ++++ spec/services/playoff_stage_service_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 080df96..38ccabc 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -101,6 +101,13 @@ class PlayoffStageService # This is not allowed in Database. The following code filters out MatchScores that contain nil as team. match_scores = match_scores.select { |ms| ms.team.present? } match_below.match_scores = match_scores + match_below.state = if match_below.match_scores.empty? || match_below.match_scores.size == 1 + :not_ready + elsif match_below.match_scores.size == 2 + :not_started + else + raise 'Unprocessable amount of match_scores found' + end [match_below, match_scores].flatten end diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index c034a1a..f50e67a 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -94,6 +94,10 @@ RSpec.describe MatchesController, type: :controller do expect(@running_playoff_match.winner).to be_a(Team) expect(@match_below.teams).to include(@running_playoff_match.winner) end + + it 'with the right status' do + expect(@match_below.state).to eq('not_ready') + end end end end diff --git a/spec/services/playoff_stage_service_spec.rb b/spec/services/playoff_stage_service_spec.rb index ccab2d3..91e3149 100644 --- a/spec/services/playoff_stage_service_spec.rb +++ b/spec/services/playoff_stage_service_spec.rb @@ -109,6 +109,10 @@ RSpec.describe PlayoffStageService do it 'finds the correct match and adds two new match_scores to it' do expect(@match_to_find.teams).to match_array(@match.winner) end + + it 'finds the correct match and changes its state' do + expect(@match_to_find.state).to eq('not_ready') + end end context 'match below has one match_score with the winning team' do @@ -121,6 +125,10 @@ RSpec.describe PlayoffStageService do it 'finds the correct match and adds no match_score' do expect(@test.teams).to match_array(@match.winner) end + + it 'finds the correct match and changes its state' do + expect(@test.state).to eq('not_ready') + end end context 'match below has one match_score with an unknown team' do @@ -134,6 +142,10 @@ RSpec.describe PlayoffStageService do expect(@test.teams).to match_array(@match.winner) expect(@test.match_scores.first.points).to_not be(1337) end + + it 'finds the correct match and changes its state' do + expect(@test.state).to eq('not_ready') + end end context 'match below has one match_score with the correct team' do @@ -147,6 +159,10 @@ RSpec.describe PlayoffStageService do expect(@test.teams).to match_array(@match.winner) expect(@test.match_scores.first.points).to be(42) end + + it 'finds the correct match and changes its state' do + expect(@test.state).to eq('not_ready') + end end context 'match below has two match_scores with the correct teams' do @@ -162,6 +178,10 @@ RSpec.describe PlayoffStageService do it 'finds the correct match and replaces nothing' do expect(@test.teams).to match_array([@match.winner, @companion_match.winner]) end + + it 'finds the correct match and changes its state' do + expect(@test.state).to eq('not_started') + end end end end From 537cccfa9ea47acdb6971acb313c8e5b25f1f4b0 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sun, 26 May 2019 20:08:04 +0200 Subject: [PATCH 32/35] Force save match_scores --- spec/controllers/matches_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/matches_controller_spec.rb b/spec/controllers/matches_controller_spec.rb index f50e67a..7606be1 100644 --- a/spec/controllers/matches_controller_spec.rb +++ b/spec/controllers/matches_controller_spec.rb @@ -73,7 +73,7 @@ RSpec.describe MatchesController, type: :controller do before do @running_playoff_match.match_scores.each_with_index do |ms, i| ms.points = i - ms.save + ms.save! end put :update, params: { id: @running_playoff_match.to_param }.merge(finished) @running_playoff_match.reload From 9f3fb532a5f13b1c1816ac59151baf726650459a Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sun, 26 May 2019 20:24:47 +0200 Subject: [PATCH 33/35] Move sonar-scanner to bottom of travis scripts This is necessary to correctly submit coverage result to sonarqube --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 09c5056..d413499 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,9 @@ addons: env: - RAILS_ENV=test script: - - sonar-scanner - bundle exec rails db:migrate - bundle exec rails spec + - sonar-scanner notifications: slack: secure: EDlQKAXSltE2d4vdOtwVdFhPScjFU2rsSSgAGSqV24br4Jb/KihpjracavZW5wnmloiWe0ulj19j7LOtJSCNJOGqeAnct+axNyBRTI+9ctpeBDMHHtiOH9IX2EBsnEBpHdL4gMgOrPFfMoyn+sqbZ7EJgOFU41f/c7X0XUf1QeJ02Gh/uY1+m8Qo0eT9x4u8W+wnCFYCQeTWOB9/4aemkgbELOEDCbLYr5n+HCGK1vi+glmYoyldVr2yQBnbfME2fcNSOb7ytPDzjBI00cdGVhj8e/AMsF84W+Q+U3RIF0zjestQeFp3lPtTcHDt/MRH39MV1fjRaZB4A8+QYrjuECJ6wjzvzXJbGWUjE++6OmbRmszPlkFxXDiiiAe/Vs1NzUr4i7c2aWZhq8Q/6HDwYXx+/OUJY3THpCHjel/PC49s+KZqMrmq53nd6NWSCtZSPCXN/1uqb3m/zUq7i4wSNFirN+9E8reYkEq6GrpG1VwZkpKp9SkjWnd88cgM0JQEpC/dxRrmeI3o+uPRSIXV+RIaGCXIAdWO7eWBIJdpVQNrA4GDjWc+zj0X02qgbn6d6iByFCDtXzB+ognZwmKUnpJ4tF3oh5xv7j6cFw/GNirgThTLwEoXMfC/Q9OmhlYByOsZ+PBApsj0hfs74YXfN753eCglmtOKGqkpRT6kwG8= From a710addde7ddc21e873b36b5598c3058536ca608 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Sun, 26 May 2019 22:03:22 +0200 Subject: [PATCH 34/35] Create :stage_tournaments with realistic match positions --- spec/factories/tournaments.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/factories/tournaments.rb b/spec/factories/tournaments.rb index 6d7098e..626a552 100644 --- a/spec/factories/tournaments.rb +++ b/spec/factories/tournaments.rb @@ -34,6 +34,12 @@ FactoryBot.define do match_count: -1, match_type: evaluator.stage_count ? :running_playoff_match : :empty_prepared_playoff_match ) + tournament.stages.each do |stage| + stage.matches.each_with_index do |match, i| + match.position = i + match.save! + end + end end end From 990361a25b8a1152577e44acaab61c82a62b375c Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Mon, 27 May 2019 13:25:14 +0200 Subject: [PATCH 35/35] Fix comparison that got lost in refactoring --- spec/factories/tournaments.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/factories/tournaments.rb b/spec/factories/tournaments.rb index 626a552..637564c 100644 --- a/spec/factories/tournaments.rb +++ b/spec/factories/tournaments.rb @@ -32,7 +32,7 @@ FactoryBot.define do :playoff_stage, level: level, match_count: -1, - match_type: evaluator.stage_count ? :running_playoff_match : :empty_prepared_playoff_match + match_type: level == evaluator.stage_count ? :running_playoff_match : :empty_prepared_playoff_match ) tournament.stages.each do |stage| stage.matches.each_with_index do |match, i|