Merge pull request #35 from turniere/ticket/TURNIERE-147
Implement Group Stage creation Logic
This commit is contained in:
commit
be24b1bc39
|
|
@ -1,4 +1,4 @@
|
|||
# turniere-backend [](https://gitlab.com/turniere/turniere-backend/commits/master) [](https://coveralls.io/gitlab/turniere/turniere-backend?branch=ticket%2FTURNIERE-155)
|
||||
# turniere-backend [](https://travis-ci.org/turniere/turniere-backend) [](https://gitlab.com/turniere/turniere-backend/commits/master) [](https://coveralls.io/gitlab/turniere/turniere-backend?branch=master) [](https://houndci.com)
|
||||
Ruby on Rails application serving as backend for turnie.re
|
||||
|
||||
# Installation
|
||||
|
|
|
|||
|
|
@ -31,25 +31,27 @@ class TournamentsController < ApplicationController
|
|||
def create
|
||||
params = tournament_params
|
||||
params.require(:teams)
|
||||
# convert teams parameter into Team objects
|
||||
teams = params.delete('teams').map do |team|
|
||||
if team[:id]
|
||||
Team.find team[:id]
|
||||
elsif team[:name]
|
||||
Team.create name: team[:name]
|
||||
end
|
||||
end
|
||||
group_stage = params.delete(:group_stage)
|
||||
teams = params.delete('teams')
|
||||
# create tournament
|
||||
tournament = current_user.tournaments.new params
|
||||
# associate provided teams with tournament
|
||||
tournament.teams = teams
|
||||
if group_stage
|
||||
groups = organize_teams_in_groups(teams)
|
||||
# add groups to tournament
|
||||
result = AddGroupStageToTournamentAndSaveTournamentToDatabase.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)
|
||||
end
|
||||
# validate tournament
|
||||
unless tournament.valid?
|
||||
render json: tournament.errors, status: :unprocessable_entity
|
||||
return
|
||||
end
|
||||
# add playoff stage to tournament
|
||||
result = AddPlayoffsToTournamentAndSaveTournamentToDatabase.call(tournament: tournament)
|
||||
# return appropriate result
|
||||
if result.success?
|
||||
render json: result.tournament, status: :created, location: result.tournament
|
||||
|
|
@ -74,6 +76,24 @@ class TournamentsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def organize_teams_in_groups(teams)
|
||||
# each team gets put into a array of teams depending on the group specified in team[:group]
|
||||
teams.group_by { |team| team['group'] }.values.map do |group|
|
||||
group.map do |team|
|
||||
find_or_create_team(team)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def find_or_create_team(team)
|
||||
# convert teams parameter into Team objects
|
||||
if team[:id]
|
||||
Team.find team[:id]
|
||||
elsif team[:name]
|
||||
Team.create name: team[:name]
|
||||
end
|
||||
end
|
||||
|
||||
def set_tournament
|
||||
@tournament = Tournament.find(params[:id])
|
||||
end
|
||||
|
|
@ -83,7 +103,7 @@ class TournamentsController < ApplicationController
|
|||
end
|
||||
|
||||
def tournament_params
|
||||
params.slice(:name, :description, :public, :teams).permit!
|
||||
params.slice(:name, :description, :public, :teams, :group_stage).permit!
|
||||
end
|
||||
|
||||
def validate_create_params
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddGroupStageToTournament
|
||||
include Interactor
|
||||
|
||||
def call
|
||||
tournament = context.tournament
|
||||
groups = context.groups
|
||||
context.fail! unless tournament.stages.empty?
|
||||
begin
|
||||
group_stage = GroupStageService.generate_group_stage(groups)
|
||||
tournament.stages = [group_stage]
|
||||
context.tournament = tournament
|
||||
rescue StandardError
|
||||
context.fail!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,4 +4,8 @@ class Group < ApplicationRecord
|
|||
belongs_to :stage
|
||||
has_many :matches, dependent: :destroy
|
||||
has_many :group_scores, dependent: :destroy
|
||||
|
||||
def teams
|
||||
matches.map(&:teams).flatten.uniq
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ class Match < ApplicationRecord
|
|||
|
||||
validate :stage_xor_group
|
||||
|
||||
def teams
|
||||
match_scores.map(&:team).flatten.uniq
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stage_xor_group
|
||||
|
|
|
|||
|
|
@ -4,4 +4,10 @@ class Stage < ApplicationRecord
|
|||
belongs_to :tournament
|
||||
has_many :matches, dependent: :destroy
|
||||
has_many :groups, dependent: :destroy
|
||||
|
||||
def teams
|
||||
return matches.map(&:teams).flatten.uniq unless matches.size.zero?
|
||||
|
||||
groups.map(&:teams).flatten.uniq unless groups.size.zero?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddGroupStageToTournamentAndSaveTournamentToDatabase
|
||||
include Interactor::Organizer
|
||||
|
||||
organize AddGroupStageToTournament, SaveTournamentToDatabase
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class GroupStageService
|
||||
def self.generate_group_stage(groups)
|
||||
raise 'Cannot generate group stage without groups' if groups.length.zero?
|
||||
|
||||
# raise an error if the average group size is not a whole number
|
||||
raise 'Groups need to be equal size' unless (groups.flatten.length.to_f / groups.length.to_f % 1).zero?
|
||||
|
||||
groups = groups.map(&method(:get_group_object_from))
|
||||
Stage.new level: -1, groups: groups
|
||||
end
|
||||
|
||||
def self.get_group_object_from(team_array)
|
||||
Group.new matches: generate_all_matches_between(team_array)
|
||||
end
|
||||
|
||||
def self.generate_all_matches_between(teams)
|
||||
matches = []
|
||||
teams.combination(2).to_a # = matchups
|
||||
.each_with_index do |matchup, i|
|
||||
match = Match.new state: :not_started,
|
||||
position: i,
|
||||
match_scores: [
|
||||
MatchScore.new(team: matchup.first),
|
||||
MatchScore.new(team: matchup.second)
|
||||
]
|
||||
matches << match
|
||||
end
|
||||
matches
|
||||
end
|
||||
end
|
||||
|
|
@ -9,6 +9,8 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
@another_user = create(:user)
|
||||
@private_tournament = create(:tournament, user: @another_user, public: false)
|
||||
@teams = create_list(:detached_team, 4)
|
||||
@teams16 = create_list(:detached_team, 16)
|
||||
@groups = create_list(:group, 4)
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
|
|
@ -103,7 +105,7 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
let(:create_data) do
|
||||
let(:create_playoff_tournament_data) do
|
||||
{
|
||||
name: Faker::Creature::Dog.name,
|
||||
description: Faker::Lorem.sentence,
|
||||
|
|
@ -112,9 +114,20 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
}
|
||||
end
|
||||
|
||||
let(:create_group_tournament_data) do
|
||||
teams_with_groups = @teams16.each_with_index.map { |team, i| { id: team.id, group: (i / 4).floor } }
|
||||
{
|
||||
name: Faker::TvShows::FamilyGuy.character,
|
||||
description: Faker::Movies::HarryPotter.quote,
|
||||
public: false,
|
||||
group_stage: true,
|
||||
teams: teams_with_groups
|
||||
}
|
||||
end
|
||||
|
||||
context 'without authentication headers' do
|
||||
it 'renders an unauthorized error response' do
|
||||
put :create, params: create_data
|
||||
put :create, params: create_playoff_tournament_data
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
|
@ -127,40 +140,58 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
context 'with existing teams' do
|
||||
it 'creates a new Tournament' do
|
||||
expect do
|
||||
post :create, params: create_data
|
||||
post :create, params: create_playoff_tournament_data
|
||||
end.to change(Tournament, :count).by(1)
|
||||
end
|
||||
|
||||
it 'associates the new tournament with the authenticated user' do
|
||||
expect do
|
||||
post :create, params: create_data
|
||||
post :create, params: create_playoff_tournament_data
|
||||
end.to change(@user.tournaments, :count).by(1)
|
||||
end
|
||||
|
||||
it 'associates the given teams with the created tournament' do
|
||||
post :create, params: create_data
|
||||
post :create, params: create_playoff_tournament_data
|
||||
body = deserialize_response response
|
||||
tournament = Tournament.find(body[:id])
|
||||
expect(tournament.teams).to match_array(@teams)
|
||||
end
|
||||
|
||||
it 'generates a playoff stage' do
|
||||
post :create, params: create_data
|
||||
post :create, params: create_playoff_tournament_data
|
||||
body = deserialize_response response
|
||||
tournament = Tournament.find(body[:id])
|
||||
expect(tournament.stages.first).to be_a(Stage)
|
||||
end
|
||||
|
||||
it 'generates a playoff stage with all given teams' do
|
||||
post :create, params: create_data
|
||||
post :create, params: create_playoff_tournament_data
|
||||
body = deserialize_response response
|
||||
tournament = Tournament.find(body[:id])
|
||||
included_teams = tournament.stages.first.matches.map { |m| m.match_scores.map(&:team) }.flatten.uniq
|
||||
expect(included_teams).to match_array(@teams)
|
||||
end
|
||||
|
||||
context 'with parameter group_stage=true' do
|
||||
before do
|
||||
post :create, params: create_group_tournament_data
|
||||
body = deserialize_response response
|
||||
@group_stage_tournament = Tournament.find(body[:id])
|
||||
end
|
||||
|
||||
it 'generates a group stage with all teams given in parameters' do
|
||||
included_teams = @group_stage_tournament.stages.find_by(level: -1).teams
|
||||
expect(included_teams).to match_array(@teams16)
|
||||
end
|
||||
|
||||
it 'generates a group stage' do
|
||||
group_stage = @group_stage_tournament.stages.find_by(level: -1)
|
||||
expect(group_stage).to be_a(Stage)
|
||||
end
|
||||
end
|
||||
|
||||
it 'renders a JSON response with the new tournament' do
|
||||
post :create, params: create_data
|
||||
post :create, params: create_playoff_tournament_data
|
||||
expect(response).to have_http_status(:created)
|
||||
expect(response.content_type).to eq('application/json')
|
||||
expect(response.location).to eq(tournament_url(Tournament.last))
|
||||
|
|
@ -169,16 +200,25 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
|
||||
context 'with missing teams' do
|
||||
it 'returns an error response' do
|
||||
data = create_data
|
||||
data = create_playoff_tournament_data
|
||||
data[:teams] << { id: Team.last.id + 1 }
|
||||
post :create, params: data
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with unequal group sizes' do
|
||||
it 'returns an error response' do
|
||||
data = create_group_tournament_data
|
||||
data[:teams].pop
|
||||
post :create, params: data
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with team names' do
|
||||
it 'creates teams for given names' do
|
||||
data = create_data
|
||||
data = create_playoff_tournament_data
|
||||
data.delete :teams
|
||||
data[:teams] = (1..12).collect { { name: Faker::Creature::Dog.name } }
|
||||
expect do
|
||||
|
|
@ -193,6 +233,15 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with empty team objects' do
|
||||
it 'renders an unprocessable entity response' do
|
||||
data = create_group_tournament_data
|
||||
data[:teams] = [{ group: 1 }, { group: 1 }, { group: 2 }, { group: 2 }]
|
||||
post :create, params: data
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,15 @@
|
|||
|
||||
FactoryBot.define do
|
||||
factory :group do
|
||||
number { 0 }
|
||||
transient do
|
||||
match_count { 4 }
|
||||
end
|
||||
|
||||
sequence(:number)
|
||||
stage
|
||||
|
||||
after(:create) do |group, evaluator|
|
||||
create_list(:group_match, evaluator.match_count, group: group)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,5 +16,14 @@ FactoryBot.define do
|
|||
|
||||
factory :group_match, class: Match do
|
||||
group
|
||||
factory :running_group_match do
|
||||
transient do
|
||||
match_scores_count { 2 }
|
||||
end
|
||||
after(:create) do |match, evaluator|
|
||||
match.match_scores = create_list(:match_score, evaluator.match_scores_count)
|
||||
end
|
||||
state { 3 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,5 +3,24 @@
|
|||
FactoryBot.define do
|
||||
factory :stage do
|
||||
tournament
|
||||
factory :group_stage do
|
||||
level { -1 }
|
||||
transient do
|
||||
group_count { 4 }
|
||||
end
|
||||
after(:create) do |stage, evaluator|
|
||||
stage.groups = create_list(:group, evaluator.group_count)
|
||||
end
|
||||
end
|
||||
|
||||
factory :playoff_stage do
|
||||
level { rand(10) }
|
||||
transient do
|
||||
match_count { 4 }
|
||||
end
|
||||
after(:create) do |stage, evaluator|
|
||||
stage.matches = create_list(:match, evaluator.match_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ FactoryBot.define do
|
|||
after(:create) do |tournament, evaluator|
|
||||
tournament.teams = create_list(:team, evaluator.teams_count, tournament: tournament)
|
||||
end
|
||||
|
||||
factory :stage_tournament do
|
||||
transient do
|
||||
stage_count { 1 }
|
||||
|
|
@ -19,5 +20,11 @@ FactoryBot.define do
|
|||
tournament.stages = create_list(:stage, evaluator.stage_count)
|
||||
end
|
||||
end
|
||||
|
||||
factory :group_stage_tournament do
|
||||
after(:create) do |tournament, _evaluator|
|
||||
tournament.stages = create_list(:group_stage, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe AddGroupStageToTournament do
|
||||
let(:empty_tournament_context) do
|
||||
AddGroupStageToTournament.call(tournament: @empty_tournament, groups: @groups)
|
||||
end
|
||||
|
||||
let(:group_stage_tournament_context) do
|
||||
AddGroupStageToTournament.call(tournament: @group_stage_tournament, groups: @groups)
|
||||
end
|
||||
|
||||
before do
|
||||
@empty_tournament = create(:stage_tournament, stage_count: 0)
|
||||
@group_stage_tournament = create(:group_stage_tournament)
|
||||
@group_stage = create(:group_stage)
|
||||
@groups = Hash[1 => create_list(:team, 4), 2 => create_list(:team, 4)].values
|
||||
end
|
||||
|
||||
context 'GroupStageService mocked' do
|
||||
before do
|
||||
expect(class_double('GroupStageService').as_stubbed_const(transfer_nested_constants: true))
|
||||
.to receive(:generate_group_stage).with(@groups)
|
||||
.and_return(@group_stage)
|
||||
end
|
||||
|
||||
context 'empty tournament' do
|
||||
it 'succeeds' do
|
||||
expect(empty_tournament_context).to be_a_success
|
||||
end
|
||||
|
||||
it 'adds group stage to the tournament' do
|
||||
test = empty_tournament_context.tournament.stages.first
|
||||
expect(test).to eq(@group_stage)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'empty groups' do
|
||||
before do
|
||||
expect(class_double('GroupStageService').as_stubbed_const(transfer_nested_constants: true))
|
||||
.to receive(:generate_group_stage).with(@groups)
|
||||
.and_raise('Cannot generate group stage without groups')
|
||||
end
|
||||
|
||||
it 'playoff generation fails' do
|
||||
expect(empty_tournament_context).to be_a_failure
|
||||
end
|
||||
end
|
||||
|
||||
context 'unequal group sizes' do
|
||||
before do
|
||||
expect(class_double('GroupStageService').as_stubbed_const(transfer_nested_constants: true))
|
||||
.to receive(:generate_group_stage).with(@groups)
|
||||
.and_raise('Groups need to be equal size')
|
||||
end
|
||||
|
||||
it 'playoff generation fails' do
|
||||
expect(empty_tournament_context).to be_a_failure
|
||||
end
|
||||
end
|
||||
|
||||
context 'tournament where group stage is already generated' do
|
||||
it 'does not add group stage' do
|
||||
expect(group_stage_tournament_context).to be_a_failure
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -20,7 +20,7 @@ RSpec.describe AddPlayoffsToTournament do
|
|||
@stages = create_list(:stage, 5)
|
||||
end
|
||||
|
||||
context 'ez lyfe' do
|
||||
context 'PlayoffStageService mocked' do
|
||||
before do
|
||||
expect(class_double('PlayoffStageService').as_stubbed_const(transfer_nested_constants: true))
|
||||
.to receive(:generate_playoff_stages_from_tournament)
|
||||
|
|
|
|||
|
|
@ -12,4 +12,19 @@ RSpec.describe Group, type: :model do
|
|||
it 'has a valid factory' do
|
||||
expect(build(:group)).to be_valid
|
||||
end
|
||||
|
||||
describe '#teams' do
|
||||
before do
|
||||
@group = create(:group, match_count: 1) # this is getting stubbed anyways
|
||||
@teams = create_list(:team, 4)
|
||||
expect_any_instance_of(Match)
|
||||
.to receive(:teams)
|
||||
.and_return(@teams)
|
||||
end
|
||||
|
||||
it 'returns all teams from the matches within the matches below' do
|
||||
teams = @group.teams
|
||||
expect(teams).to match_array(@teams)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -43,7 +43,43 @@ RSpec.describe Match, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context '#teams' do
|
||||
before do
|
||||
@playoff_match = create(:running_playoff_match)
|
||||
@group_match = create(:running_group_match)
|
||||
@teams = create_list(:team, 2)
|
||||
@match_scores = create_list(:match_score, 2)
|
||||
@match_scores.each_with_index { |match, i| match.team = @teams[i] }
|
||||
@playoff_match.match_scores = @match_scores
|
||||
@group_match.match_scores = @match_scores
|
||||
end
|
||||
|
||||
context 'called on group match' do
|
||||
let(:call_teams_on_group_match) do
|
||||
@group_match.teams
|
||||
end
|
||||
|
||||
it 'returns 2 team objects' do
|
||||
teams = call_teams_on_group_match
|
||||
expect(teams).to match_array(@teams)
|
||||
end
|
||||
end
|
||||
|
||||
context 'called on playoff match' do
|
||||
let(:call_teams_on_playoff_match) do
|
||||
@playoff_match.teams
|
||||
end
|
||||
|
||||
it 'returns 2 team objects' do
|
||||
teams = call_teams_on_playoff_match
|
||||
expect(teams).to match_array(@teams)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:match)).to be_valid
|
||||
expect(build(:running_playoff_match)).to be_valid
|
||||
expect(build(:group_match)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,5 +11,38 @@ RSpec.describe Stage, type: :model do
|
|||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:stage)).to be_valid
|
||||
expect(build(:group_stage)).to be_valid
|
||||
end
|
||||
|
||||
describe '#teams' do
|
||||
context 'group stage' do
|
||||
before do
|
||||
@stage = create(:group_stage, group_count: 1) # this is getting stubbed anyways
|
||||
@teams = create_list(:team, 4)
|
||||
expect_any_instance_of(Group)
|
||||
.to receive(:teams)
|
||||
.and_return(@teams)
|
||||
end
|
||||
|
||||
it 'returns all teams from the matches within the groups below' do
|
||||
teams = @stage.teams
|
||||
expect(teams).to match_array(@teams)
|
||||
end
|
||||
end
|
||||
|
||||
context 'playoff stage' do
|
||||
before do
|
||||
@stage = create(:playoff_stage, match_count: 1) # this is getting stubbed anyways
|
||||
@teams = create_list(:team, 4)
|
||||
expect_any_instance_of(Match)
|
||||
.to receive(:teams)
|
||||
.and_return(@teams)
|
||||
end
|
||||
|
||||
it 'returns all teams from the matches within the matches below' do
|
||||
teams = @stage.teams
|
||||
expect(teams).to match_array(@teams)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,5 +15,6 @@ RSpec.describe Team, type: :model do
|
|||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:team)).to be_valid
|
||||
expect(build(:detached_team)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,5 +33,7 @@ RSpec.describe Tournament, type: :model do
|
|||
|
||||
it 'has valid factory' do
|
||||
expect(build(:tournament)).to be_valid
|
||||
expect(build(:stage_tournament)).to be_valid
|
||||
expect(build(:group_stage_tournament)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe GroupStageService do
|
||||
before do
|
||||
@stage = create(:stage)
|
||||
@teams1 = create_list(:team, 4)
|
||||
@teams2 = create_list(:team, 4)
|
||||
@groups = Hash[1 => @teams1, 2 => @teams2].values
|
||||
end
|
||||
describe '#generate_group_stage method' do
|
||||
it 'returns a stage object' do
|
||||
group_stage = GroupStageService.generate_group_stage(@groups)
|
||||
expect(group_stage).to be_a(Stage)
|
||||
end
|
||||
|
||||
it 'returns a stage object with level -1' do
|
||||
group_stage_level = GroupStageService.generate_group_stage(@groups).level
|
||||
expect(group_stage_level).to be(-1)
|
||||
end
|
||||
|
||||
it 'adds the provided groups to the stage' do
|
||||
group_stage_teams = GroupStageService.generate_group_stage(@groups).teams
|
||||
expect(group_stage_teams).to match_array(@groups.flatten)
|
||||
end
|
||||
|
||||
it 'raises exception when given different sizes of groups' do
|
||||
unequal_groups = @groups
|
||||
unequal_groups.first.pop
|
||||
expect { GroupStageService.generate_group_stage(unequal_groups) }
|
||||
.to raise_exception 'Groups need to be equal size'
|
||||
end
|
||||
|
||||
it 'raises exception when given no groups' do
|
||||
expect { GroupStageService.generate_group_stage([]) }
|
||||
.to raise_exception 'Cannot generate group stage without groups'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#get_group_object_from' do
|
||||
it 'returns a group' do
|
||||
group = GroupStageService.get_group_object_from(@teams1)
|
||||
expect(group).to be_a(Group)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#generate_all_matches_between' do
|
||||
it 'generates a list of not started matches' do
|
||||
matches = GroupStageService.generate_all_matches_between(@teams2)
|
||||
matches.each do |match|
|
||||
expect(match).to be_a(Match)
|
||||
match_state = match.state
|
||||
expect(match_state).to eq('not_started')
|
||||
end
|
||||
end
|
||||
|
||||
it 'generates the right amount of matches' do
|
||||
matches = GroupStageService.generate_all_matches_between(@teams2)
|
||||
# (1..@teams2.size-1).sum -> 1. Team has to play against n-1 teams; second against n-2 ....
|
||||
expect(matches.size).to be((1..@teams2.size - 1).sum)
|
||||
end
|
||||
|
||||
it 'gives matches exclusive positions' do
|
||||
matches = GroupStageService.generate_all_matches_between(@teams2)
|
||||
match_positions = matches.map(&:position)
|
||||
expect(match_positions.length).to eq(match_positions.uniq.length)
|
||||
end
|
||||
|
||||
it 'doesn\'t match a team against itself' do
|
||||
matches = GroupStageService.generate_all_matches_between(@teams1)
|
||||
matches.each do |match|
|
||||
expect(match.teams.first).to_not eq(match.teams.second)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue