Implement stages controller (GET UPDATE)

This commit is contained in:
Daniel Schädler 2019-06-17 13:10:42 +02:00
parent 3dfeae8bf3
commit b28561043e
3 changed files with 140 additions and 0 deletions

View File

@ -0,0 +1,62 @@
# frozen_string_literal: true
class StagesController < ApplicationController
before_action :set_stage, only: %i[show update]
before_action :authenticate_user!, only: %i[update]
before_action -> { require_owner! @stage.owner }, only: %i[update]
# GET /stages/1
def show
render json: @stage, include: '**'
end
# PUT /stages/1
def update
if stage_params[:state] == 'finished'
unless @stage.state == 'in_progress'
render json: { error: 'Only running group stages can be finished' }, status: :unprocessable_entity
return
end
Stage.transaction do
if @stage.update(stage_params)
handle_group_stage_end
render json: @stage
else
render json: @stage.errors, status: :unprocessable_entity
raise ActiveRecord::Rollback
end
end
else
render json: {
error: 'The state attribute may only be changed to finished'
}, status: :unprocessable_entity
end
end
private
def handle_group_stage_end
unless @stage.over?
render json: {
error: 'Group Stage still has some matches that are not over yet. Finish them to generate playoffs'
}, status: :unprocessable_entity
raise ActiveRecord::Rollback
end
return if AddPlayoffsToTournamentAndSave.call(tournament: @stage.tournament,
teams: GroupStageService.get_advancing_teams(@stage)).success?
render json: { error: 'Generating group stage failed' }, status: :unprocessable_entity
raise ActiveRecord::Rollback
end
def set_stage
@stage = Stage.find(params[:id])
end
def stage_params
params.slice(:state).permit!
end
end

View File

@ -9,6 +9,7 @@ Rails.application.routes.draw do
resources :matches, only: %i[show update] do
resources :bets, only: %i[index create]
end
resources :stages, only: %i[show update]
resources :teams, only: %i[show update]
resources :tournaments do
resources :statistics, only: %i[index]

View File

@ -0,0 +1,77 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe StagesController, type: :controller do
before do
@stage = create(:playoff_stage)
end
describe 'GET #show' do
it 'returns a success response' do
get :show, params: { id: @stage.to_param }
expect(response).to be_successful
end
it 'should return the correct stage' do
get :show, params: { id: @stage.to_param }
body = deserialize_response response
expect(Stage.find_by(id: body[:id])).to eq(@stage)
expect(body[:level]).to eq(@stage.level)
expect(body[:state]).to eq(@stage.state)
end
end
describe 'PUT #update' do
context 'group_stage with matches that are done' do
before do
@running_group_stage = create(:group_stage, match_factory: :finished_group_match)
end
FINISHED = { state: 'finished' }.freeze
it 'doesn\'t have any other stages besides it before update' do
expect(@running_group_stage.tournament.stages.size).to eq(1)
end
context 'as owner' do
before(:each) do
apply_authentication_headers_for @running_group_stage.owner
end
before do
put :update, params: { id: @running_group_stage.to_param }.merge(FINISHED)
@running_group_stage.reload
end
it 'succeeds' do
expect(response).to be_successful
end
it 'stops the stage' do
expect(@running_group_stage.state).to eq(FINISHED[:state])
end
it 'adds new stages to the tournament' do
expect(@running_group_stage.tournament.stages.size).to be > 1
end
it 'adds the right teams' do
expect(@running_group_stage.tournament.stages.max_by(&:level).teams)
.to match_array(GroupStageService.get_advancing_teams(@running_group_stage))
end
end
context 'as another user' do
before(:each) do
apply_authentication_headers_for create(:user)
end
it 'returns an error' do
put :update, params: { id: @stage.to_param }.merge(FINISHED)
expect(response).to have_http_status(:forbidden)
end
end
end
end
end