turniere-backend/spec/services/tournament_group_match_star...

74 lines
2.8 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe TournamentGroupMatchStarter do
let(:tournament) { create(:group_stage_tournament, group_count: 4, match_factory: :filled_group_match) }
let(:groups) { tournament.group_stage.groups.sort_by(&:number) }
before do
groups.each { |group| set_group_match_states(group, Array.new(4, :not_started)) }
end
describe '.upcoming_matches' do
it 'returns only groups whose next unstarted match is at the lowest pending position' do
start_group_positions(groups[0], [0, 1, 2])
start_group_positions(groups[1], [0, 1])
start_group_positions(groups[2], [0, 1])
start_group_positions(groups[3], [0, 1])
matches = described_class.upcoming_matches(tournament)
expect(matches.map(&:group)).to match_array(groups.drop(1))
expect(matches.map(&:position).uniq).to eq([2])
end
end
describe '.start_next!' do
it 'starts only a single lagging group before all groups can advance' do
start_group_positions(groups[0], [0, 1])
start_group_positions(groups[1], [0])
start_group_positions(groups[2], [0, 1])
start_group_positions(groups[3], [0, 1])
first_start = described_class.start_next!(tournament, logger: Logger.new(nil))
second_start = described_class.start_next!(tournament, logger: Logger.new(nil))
expect_group_positions(first_start, [[groups[1], 1]])
expect_group_positions(second_start, groups.map { |group| [group, 2] })
end
it 'starts catch-up waves before the next position is started everywhere' do
start_group_positions(groups[0], [0, 1, 2])
start_group_positions(groups[1], [0])
start_group_positions(groups[2], [0, 1, 2])
start_group_positions(groups[3], [0, 1])
first_start = described_class.start_next!(tournament, logger: Logger.new(nil))
second_start = described_class.start_next!(tournament, logger: Logger.new(nil))
third_start = described_class.start_next!(tournament, logger: Logger.new(nil))
expect_group_positions(first_start, [[groups[1], 1]])
expect_group_positions(second_start, [[groups[1], 2], [groups[3], 2]])
expect_group_positions(third_start, groups.map { |group| [group, 3] })
end
end
def set_group_match_states(group, states)
group.matches.order(:id).each_with_index do |match, index|
match.update!(position: index, state: states.fetch(index))
end
end
def start_group_positions(group, positions)
positions.each do |position|
group.matches.find_by!(position:).update!(state: :in_progress)
end
end
def expect_group_positions(matches, expected_pairs)
expect(matches.map { |match| [match.group, match.position] }).to match_array(expected_pairs)
expect(matches.map { |match| match.reload.state }.uniq).to eq(['in_progress'])
end
end