Merge remote-tracking branch 'origin/master' into annotate_advancing_teams
This commit is contained in:
commit
34814a837a
|
|
@ -328,6 +328,7 @@ PLATFORMS
|
|||
aarch64-linux-musl
|
||||
arm64-darwin-22
|
||||
arm64-darwin-23
|
||||
arm64-darwin-24
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class MatchesController < ApplicationController
|
|||
elsif match_params['state'] == 'upcoming'
|
||||
# for every group within the tournament find the match with the lowest position that is of state 'not_started'
|
||||
upcoming_matches = @tournament.stages.find_by(level: -1)&.groups&.map { |g| g.matches.select { |m| m.state == 'not_started' }.min_by(&:position) }
|
||||
# filter out nil values (this may happen if one of the groups already has no upcoming matches)
|
||||
upcoming_matches = upcoming_matches.reject(&:nil?)
|
||||
# if there are none, the group stage is over, so we have to look into the playoff stages
|
||||
if upcoming_matches.nil?
|
||||
next_level = 0
|
||||
|
|
@ -34,14 +36,12 @@ class MatchesController < ApplicationController
|
|||
m.state == match_params['state']
|
||||
end
|
||||
end
|
||||
render json: matches, each_serializer: ExtendedMatchSerializer, include: [
|
||||
'match_scores.team', 'bets', 'stage', 'group'
|
||||
]
|
||||
render json: matches, each_serializer: ExtendedMatchSerializer, include: %w[match_scores.team bets stage group]
|
||||
end
|
||||
|
||||
# GET /matches/1
|
||||
def show
|
||||
render json: @match, include: ['match_scores.points', 'match_scores.team', 'bets']
|
||||
render json: @match, include: %w[match_scores.points match_scores.team bets]
|
||||
end
|
||||
|
||||
# PATCH/PUT /matches/1
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TournamentsController < ApplicationController
|
||||
before_action :set_tournament, only: %i[show update destroy]
|
||||
before_action :authenticate_user!, only: %i[create update destroy]
|
||||
before_action -> { require_owner! @tournament.owner }, only: %i[update destroy]
|
||||
before_action :set_tournament, only: %i[show update destroy set_timer_end timer_end]
|
||||
before_action :authenticate_user!, only: %i[create update destroy set_timer_end]
|
||||
before_action -> { require_owner! @tournament.owner }, only: %i[update destroy set_timer_end]
|
||||
before_action :validate_create_params, only: %i[create]
|
||||
before_action :validate_update_params, only: %i[update]
|
||||
before_action :validate_set_timer_end_params, only: %i[set_timer_end]
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found_error
|
||||
|
||||
# GET /tournaments
|
||||
|
|
@ -93,8 +94,27 @@ class TournamentsController < ApplicationController
|
|||
@tournament.destroy
|
||||
end
|
||||
|
||||
# GET /tournaments/:id/timer_end
|
||||
def timer_end
|
||||
render json: { timer_end: @tournament.timer_end }
|
||||
end
|
||||
|
||||
# PATCH /tournaments/:id/set_timer_end
|
||||
def set_timer_end
|
||||
if @tournament.update(timer_end_params)
|
||||
render json: @tournament
|
||||
else
|
||||
render json: @tournament.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def timer_end_params
|
||||
{ timer_end: params[:timer_end] }
|
||||
end
|
||||
|
||||
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|
|
||||
|
|
@ -158,3 +178,39 @@ class TournamentsController < ApplicationController
|
|||
}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def validate_set_timer_end_params
|
||||
timer_end = params[:timer_end]
|
||||
timer_end_seconds = params[:timer_end_seconds]
|
||||
|
||||
# throw error if both timer_end and timer_end_seconds are present
|
||||
if timer_end.present? && timer_end_seconds.present?
|
||||
return render json: { error: 'Only one of timer_end or timer_end_seconds is allowed' }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
if timer_end_seconds.present?
|
||||
begin
|
||||
timer_end_seconds = Integer(timer_end_seconds)
|
||||
rescue ArgumentError
|
||||
return render json: { error: 'Invalid seconds format' }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
return render json: { error: 'Timer end must be in the future' }, status: :unprocessable_entity if timer_end_seconds <= 0
|
||||
|
||||
parsed_time = Time.zone.now + timer_end_seconds
|
||||
params[:timer_end] = parsed_time
|
||||
elsif timer_end.present?
|
||||
begin
|
||||
parsed_time = Time.zone.parse(timer_end)
|
||||
if parsed_time.nil?
|
||||
return render json: { error: 'Invalid datetime format' }, status: :unprocessable_entity
|
||||
elsif !parsed_time.future?
|
||||
return render json: { error: 'Timer end must be in the future' }, status: :unprocessable_entity
|
||||
end
|
||||
rescue ArgumentError
|
||||
return render json: { error: 'Invalid datetime format' }, status: :unprocessable_entity
|
||||
end
|
||||
else
|
||||
return render json: { error: 'Timer end is required' }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class TournamentSerializer < SimpleTournamentSerializer
|
||||
attributes :description, :playoff_teams_amount,
|
||||
:instant_finalists_amount, :intermediate_round_participants_amount
|
||||
:instant_finalists_amount, :intermediate_round_participants_amount, :timer_end
|
||||
has_many :stages
|
||||
|
||||
attribute :owner_username do
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ Rails.application.routes.draw do
|
|||
resources :tournaments do
|
||||
resources :statistics, only: %i[index]
|
||||
resources :matches, only: %i[index]
|
||||
member do
|
||||
get :timer_end
|
||||
patch :set_timer_end
|
||||
end
|
||||
end
|
||||
resources :match_scores, only: %i[show update]
|
||||
resources :groups, only: %i[show]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
class AddTimerEndToTournaments < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :tournaments, :timer_end, :datetime
|
||||
end
|
||||
end
|
||||
|
|
@ -43,6 +43,7 @@ RSpec.describe MatchesController, type: :controller do
|
|||
expect(body.empty?).to be true
|
||||
end
|
||||
end
|
||||
# TODO add test for upcoming once there is test data for a "valid" group stage
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
|
|
|
|||
|
|
@ -102,6 +102,9 @@ RSpec.describe TournamentsController, type: :controller do
|
|||
get :show, params: { id: @tournament.to_param }
|
||||
json = deserialize_response(response)
|
||||
expect(json[:id].to_i).to eq(@tournament.id)
|
||||
expected_keys = %i[id name code public description playoff_teams_amount instant_finalists_amount intermediate_round_participants_amount timer_end owner_username stages teams]
|
||||
expect(json.keys).to match_array(expected_keys)
|
||||
expect(json).to eq(TournamentSerializer.new(@tournament).as_json)
|
||||
expect(json[:name]).to eq(@tournament.name)
|
||||
expect(json[:description]).to eq(@tournament.description)
|
||||
expect(json[:public]).to eq(@tournament.public)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ RSpec.configure do |config|
|
|||
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
||||
|
||||
# Run only focused tests
|
||||
# TODO REVERT ME
|
||||
config.filter_run_when_matching :focus
|
||||
|
||||
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
||||
|
|
|
|||
Loading…
Reference in New Issue