feat(matches): stop in-progress matches
This commit is contained in:
parent
0141d78e4e
commit
df227f9397
|
|
@ -45,12 +45,8 @@ class MatchesController < ApplicationController
|
|||
Match.transaction do
|
||||
if @match.update(match_params)
|
||||
handle_match_end if new_state == 'finished'
|
||||
if @match.group_match? && new_state == 'in_progress'
|
||||
group = @match.group
|
||||
unless UpdateGroupsGroupScoresAndSave.call(group: group).success?
|
||||
logger.warn "Updating groups group score failed for #{group}"
|
||||
end
|
||||
end
|
||||
handle_match_stop if new_state == 'not_started'
|
||||
update_group_scores if @match.group_match? && %w[in_progress not_started].include?(new_state)
|
||||
|
||||
render json: @match
|
||||
synced_tournament = @match.tournament
|
||||
|
|
@ -113,6 +109,19 @@ class MatchesController < ApplicationController
|
|||
raise ActiveRecord::Rollback
|
||||
end
|
||||
|
||||
def handle_match_stop
|
||||
@match.match_scores.each do |match_score|
|
||||
match_score.update!(points: 0, hidden_points: 0)
|
||||
end
|
||||
end
|
||||
|
||||
def update_group_scores
|
||||
group = @match.group
|
||||
return if UpdateGroupsGroupScoresAndSave.call(group: group).success?
|
||||
|
||||
logger.warn "Updating groups group score failed for #{group}"
|
||||
end
|
||||
|
||||
def validate_params
|
||||
case match_params['state']
|
||||
when 'in_progress'
|
||||
|
|
@ -121,6 +130,9 @@ class MatchesController < ApplicationController
|
|||
when 'finished'
|
||||
render json: { error: 'Match can\'t finish in this state' }, status: :unprocessable_content \
|
||||
unless @match.in_progress?
|
||||
when 'not_started'
|
||||
render json: { error: 'Match can\'t stop in this state' }, status: :unprocessable_content \
|
||||
unless @match.in_progress?
|
||||
else
|
||||
render json: { error: 'Invalid target state' }, status: :unprocessable_content
|
||||
end
|
||||
|
|
|
|||
|
|
@ -233,6 +233,21 @@ RSpec.describe MatchesController, type: :controller do
|
|||
expect(body[:state]).to eq(valid_update[:state])
|
||||
end
|
||||
|
||||
it 'stops an in-progress match and resets its scores' do
|
||||
@match.update!(state: :in_progress)
|
||||
@match.match_scores.each do |match_score|
|
||||
match_score.update!(points: 7, hidden_points: 5)
|
||||
end
|
||||
|
||||
expect(TournamentLiveBroadcast).to receive(:call).with(@match.tournament.id)
|
||||
put :update, params: { id: @match.to_param, state: 'not_started' }
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(@match.reload.state).to eq('not_started')
|
||||
expect(@match.match_scores.reload.map(&:points)).to all(eq(0))
|
||||
expect(@match.match_scores.reload.map(&:hidden_points)).to all(eq(0))
|
||||
end
|
||||
|
||||
context 'on a running playoff match' do
|
||||
let(:finished) do
|
||||
{
|
||||
|
|
@ -385,6 +400,14 @@ RSpec.describe MatchesController, type: :controller do
|
|||
expect(response).to have_http_status(:unprocessable_content)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with stop params on a not-started match' do
|
||||
it 'renders an unprocessable entity response' do
|
||||
put :update, params: { id: @match.to_param, state: 'not_started' }
|
||||
expect(response).to have_http_status(:unprocessable_content)
|
||||
expect(deserialize_response(response)[:error]).to eq("Match can't stop in this state")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'as another user' do
|
||||
|
|
@ -401,6 +424,34 @@ RSpec.describe MatchesController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
context 'on a running group match' do
|
||||
let(:tournament) { create(:group_stage_tournament, group_count: 1, match_factory: :filled_group_match) }
|
||||
let(:group) { tournament.stages.find_by(level: -1).groups.first }
|
||||
let(:group_match) { group.matches.first }
|
||||
|
||||
before do
|
||||
apply_authentication_headers_for tournament.owner
|
||||
group_match.update!(state: :in_progress)
|
||||
group_match.match_scores.order(:id).each_with_index do |match_score, index|
|
||||
match_score.update!(points: index.zero? ? 9 : 2, hidden_points: index.zero? ? 4 : 1)
|
||||
end
|
||||
UpdateGroupsGroupScoresAndSave.call(group: group)
|
||||
end
|
||||
|
||||
it 'stops the match, clears scores, and recalculates group scores' do
|
||||
put :update, params: { id: group_match.to_param, state: 'not_started' }
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(group_match.reload.state).to eq('not_started')
|
||||
expect(group_match.match_scores.reload.map(&:points)).to all(eq(0))
|
||||
expect(group_match.match_scores.reload.map(&:hidden_points)).to all(eq(0))
|
||||
involved_group_scores = group.group_scores.reload.select { |score| group_match.teams.include?(score.team) }
|
||||
expect(involved_group_scores.map(&:group_points)).to all(eq(0))
|
||||
expect(involved_group_scores.map(&:scored_points)).to all(eq(0))
|
||||
expect(involved_group_scores.map(&:received_points)).to all(eq(0))
|
||||
end
|
||||
end
|
||||
|
||||
context 'on a playoff match that isn\'t ready yet' do
|
||||
let(:invalid_update) do
|
||||
{
|
||||
|
|
|
|||
|
|
@ -270,11 +270,14 @@ RSpec.describe 'Backend API surface HTTP E2E' do
|
|||
started_match = anonymous_client.get("/matches/#{match.fetch(:id)}")
|
||||
score_to_update = started_match.fetch(:json).fetch(:match_scores).first
|
||||
score_show = anonymous_client.get("/match_scores/#{score_to_update.fetch(:id)}")
|
||||
score_update = owner_client.patch("/match_scores/#{score_to_update.fetch(:id)}", body: { points: 7 })
|
||||
score_update = owner_client.patch("/match_scores/#{score_to_update.fetch(:id)}", body: { points: 7, hidden_points: 11 })
|
||||
forbidden_score_update = other_client.patch("/match_scores/#{score_to_update.fetch(:id)}", body: { points: 3 })
|
||||
unauthenticated_score_update = anonymous_client.patch("/match_scores/#{score_to_update.fetch(:id)}", body: { points: 3 })
|
||||
bet_while_running = owner_client.post("/matches/#{match.fetch(:id)}/bets", body: { team: team.fetch(:id) })
|
||||
restart_started_match = owner_client.patch("/matches/#{match.fetch(:id)}", body: { state: 'in_progress' })
|
||||
stop_started_match = owner_client.patch("/matches/#{match.fetch(:id)}", body: { state: 'not_started' })
|
||||
stopped_match = anonymous_client.get("/matches/#{match.fetch(:id)}")
|
||||
restop_match = owner_client.patch("/matches/#{match.fetch(:id)}", body: { state: 'not_started' })
|
||||
playoff_stats = anonymous_client.get("/tournaments/#{playoff_only.fetch(:id)}/statistics")
|
||||
tied_playoff_match = playoff_only.fetch(:stages)
|
||||
.flat_map { |stage| stage.fetch(:matches) }
|
||||
|
|
@ -349,12 +352,21 @@ RSpec.describe 'Backend API surface HTTP E2E' do
|
|||
expect(score_show[:status]).to eq(200)
|
||||
expect(score_update[:status]).to eq(200)
|
||||
expect(score_update.dig(:json, :points)).to eq(7)
|
||||
expect(score_update.dig(:json, :hidden_points)).to eq(11)
|
||||
expect(forbidden_score_update[:status]).to eq(403)
|
||||
expect(unauthenticated_score_update[:status]).to eq(401)
|
||||
expect(bet_while_running[:status]).to eq(422)
|
||||
expect(bet_while_running.dig(:json, :error)).to eq('Betting is not allowed while match is in_progress')
|
||||
expect(restart_started_match[:status]).to eq(422)
|
||||
expect(restart_started_match.dig(:json, :error)).to eq("Match can't start in this state")
|
||||
expect(stop_started_match[:status]).to eq(200)
|
||||
expect(stop_started_match.dig(:json, :state)).to eq('not_started')
|
||||
expect(stopped_match[:status]).to eq(200)
|
||||
expect(stopped_match.dig(:json, :state)).to eq('not_started')
|
||||
expect(stopped_match.dig(:json, :match_scores).map { |score| score.fetch(:points) }).to all(eq(0))
|
||||
expect(stopped_match.dig(:json, :match_scores).map { |score| score.fetch(:hidden_points) }).to all(eq(0))
|
||||
expect(restop_match[:status]).to eq(422)
|
||||
expect(restop_match.dig(:json, :error)).to eq("Match can't stop in this state")
|
||||
|
||||
expect(playoff_stats[:status]).to eq(501)
|
||||
expect(playoff_stats[:json]).to eq({})
|
||||
|
|
|
|||
Loading…
Reference in New Issue