Merge pull request #24 from turniere/ticket/TURNIERE-129
Add endpoint for tournament creation
This commit is contained in:
commit
b201503437
|
|
@ -24,4 +24,8 @@ class ApplicationController < ActionController::API
|
||||||
]
|
]
|
||||||
}, status: :forbidden
|
}, status: :forbidden
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_not_found_error(exception)
|
||||||
|
render json: { error: exception.to_s }, status: :not_found
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ class TournamentsController < ApplicationController
|
||||||
before_action :set_tournament, only: %i[show update destroy]
|
before_action :set_tournament, only: %i[show update destroy]
|
||||||
before_action :authenticate_user!, only: %i[create update destroy]
|
before_action :authenticate_user!, only: %i[create update destroy]
|
||||||
before_action -> { require_owner! @tournament.owner }, only: %i[update destroy]
|
before_action -> { require_owner! @tournament.owner }, only: %i[update destroy]
|
||||||
|
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found_error
|
||||||
|
|
||||||
# GET /tournaments
|
# GET /tournaments
|
||||||
def index
|
def index
|
||||||
|
|
@ -18,12 +19,32 @@ class TournamentsController < ApplicationController
|
||||||
|
|
||||||
# POST /tournaments
|
# POST /tournaments
|
||||||
def create
|
def create
|
||||||
tournament = current_user.tournaments.new tournament_params
|
params = tournament_params
|
||||||
|
params.require(:teams)
|
||||||
if tournament.save
|
# convert teams parameter into Team objects
|
||||||
render json: tournament, status: :created, location: tournament
|
teams = params.delete('teams').map do |team|
|
||||||
else
|
if team[:id]
|
||||||
|
Team.find team[:id]
|
||||||
|
elsif team[:name]
|
||||||
|
Team.create name: team[:name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# create tournament
|
||||||
|
tournament = current_user.tournaments.new params
|
||||||
|
# associate provided teams with tournament
|
||||||
|
tournament.teams = teams
|
||||||
|
# validate tournament
|
||||||
|
unless tournament.valid?
|
||||||
render json: tournament.errors, status: :unprocessable_entity
|
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
|
||||||
|
else
|
||||||
|
render json: { error: 'Tournament generation failed' }, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,6 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe TournamentsController, type: :controller do
|
RSpec.describe TournamentsController, type: :controller do
|
||||||
def tournament_ids(response)
|
|
||||||
deserialize_response(response).map { |t| t[:id].to_i }
|
|
||||||
end
|
|
||||||
before do
|
before do
|
||||||
@tournament = create(:tournament)
|
@tournament = create(:tournament)
|
||||||
@user = @tournament.owner
|
@user = @tournament.owner
|
||||||
|
|
@ -24,7 +21,7 @@ RSpec.describe TournamentsController, type: :controller do
|
||||||
get :index
|
get :index
|
||||||
tournaments = deserialize_response response
|
tournaments = deserialize_response response
|
||||||
public_tournaments = tournaments.select { |t| t[:public] }
|
public_tournaments = tournaments.select { |t| t[:public] }
|
||||||
expect(public_tournaments.size).to eq((Tournament.where public: true).size)
|
expect(public_tournaments.map { |t| t[:id] }).to match_array(Tournament.where(public: true).map { |t| t[:id] })
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns no private tournaments for unauthenticated users' do
|
it 'returns no private tournaments for unauthenticated users' do
|
||||||
|
|
@ -35,15 +32,17 @@ RSpec.describe TournamentsController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns private tournaments owned by the authenticated user' do
|
it 'returns private tournaments owned by the authenticated user' do
|
||||||
apply_authentication_headers_for @another_user
|
apply_authentication_headers_for @user
|
||||||
get :index
|
get :index
|
||||||
expect(tournament_ids(response)).to include(@private_tournament.id)
|
tournaments = deserialize_response response
|
||||||
|
expect(tournaments.filter { |t| !t[:public] }).to match_array(Tournament.where(owner: @owner, public: false))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns no private tournaments owned by another user' do
|
it 'returns no private tournaments owned by another user' do
|
||||||
apply_authentication_headers_for @user
|
apply_authentication_headers_for @user
|
||||||
get :index
|
get :index
|
||||||
expect(tournament_ids(response)).not_to include(@private_tournament.id)
|
tournaments = deserialize_response response
|
||||||
|
expect(tournaments.map { |t| t[:id] }).not_to include(@private_tournament.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -59,49 +58,74 @@ RSpec.describe TournamentsController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'POST #create', skip: true do
|
describe 'POST #create' do
|
||||||
let(:create_data) do
|
let(:create_data) do
|
||||||
{
|
{
|
||||||
name: Faker::Creature::Dog.name,
|
name: Faker::Creature::Dog.name,
|
||||||
description: Faker::Lorem.sentence,
|
description: Faker::Lorem.sentence,
|
||||||
public: false,
|
public: false,
|
||||||
teams: {
|
teams: @teams.map { |team| { id: team.id } }
|
||||||
data: @teams.map { |team| { type: 'teams', id: team.id } }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:each) do
|
context 'without authentication headers' do
|
||||||
apply_authentication_headers_for @user
|
it 'renders an unauthorized error response' do
|
||||||
|
put :create, params: create_data
|
||||||
|
expect(response).to have_http_status(:unauthorized)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with valid params' do
|
context 'with authentication headers' do
|
||||||
it 'creates a new Tournament' do
|
before(:each) do
|
||||||
expect do
|
apply_authentication_headers_for @user
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with existing teams' do
|
||||||
|
it 'creates a new Tournament' do
|
||||||
|
expect do
|
||||||
|
post :create, params: create_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
|
||||||
|
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_data
|
||||||
end.to change(Tournament, :count).by(1)
|
body = deserialize_response response
|
||||||
end
|
tournament = Tournament.find(body[:id])
|
||||||
|
expect(tournament.teams).to match_array(@teams)
|
||||||
|
end
|
||||||
|
|
||||||
it 'associates the new tournament with the authenticated user' do
|
it 'renders a JSON response with the new tournament' do
|
||||||
expect do
|
|
||||||
post :create, params: create_data
|
post :create, params: create_data
|
||||||
end.to change(@user.tournaments, :size).by(1)
|
expect(response).to have_http_status(:created)
|
||||||
|
expect(response.content_type).to eq('application/json')
|
||||||
|
expect(response.location).to eq(tournament_url(Tournament.last))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'associates the given teams with the created tournament' do
|
context 'with missing teams' do
|
||||||
new_teams = create_list(:detached_team, 4)
|
it 'returns an error response' do
|
||||||
new_teams_create_data = create_data
|
data = create_data
|
||||||
new_teams_create_data[:data][:relationships][:teams][:data] = \
|
data[:teams] << { id: Team.last.id + 1 }
|
||||||
new_teams.map { |team| { type: 'teams', id: team.id } }
|
post :create, params: data
|
||||||
post :create, params: new_teams_create_data
|
expect(response).to have_http_status(:not_found)
|
||||||
expect(Tournament.last.teams).to match_array(new_teams)
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders a JSON response with the new tournament' do
|
context 'with team names' do
|
||||||
post :create, params: create_data
|
it 'creates teams for given names' do
|
||||||
expect(response).to have_http_status(:created)
|
data = create_data
|
||||||
expect(response.content_type).to eq('application/json')
|
data.delete :teams
|
||||||
expect(response.location).to eq(tournament_url(Tournament.last))
|
data[:teams] = (1..12).collect { { name: Faker::Creature::Dog.name } }
|
||||||
|
expect do
|
||||||
|
post :create, params: data
|
||||||
|
end.to change(Team, :count).by(data[:teams].count)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue