diff --git a/app/controllers/scores_controller.rb b/app/controllers/scores_controller.rb new file mode 100644 index 0000000..08e1350 --- /dev/null +++ b/app/controllers/scores_controller.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +class ScoresController < ApplicationController + before_action :set_score, only: %i[show update] + before_action :authenticate_user!, only: %i[update] + before_action -> { require_owner! @score.owner }, only: %i[update] + + # GET /scores/1 + def show + render json: @score + end + + # PATCH/PUT /scores/1 + def update + if @score.update(score_params) + render json: @score + else + render json: @score.errors, status: :unprocessable_entity + end + end + + private + + # Use callbacks to share common setup or constraints between actions. + def set_score + @score = Score.find(params[:id]) + end + + # Only allow a trusted parameter "white list" through. + def score_params + deserialize_params only: %i[score] + end +end diff --git a/config/routes.rb b/config/routes.rb index 12e7419..f3f3498 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,4 +6,5 @@ Rails.application.routes.draw do resources :matches, only: %i[show] resources :teams, only: %i[show update] resources :tournaments + resources :scores, only: %i[show update] end diff --git a/spec/controllers/scores_controller_spec.rb b/spec/controllers/scores_controller_spec.rb new file mode 100644 index 0000000..0b13b2a --- /dev/null +++ b/spec/controllers/scores_controller_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ScoresController, type: :controller do + before do + @score = create(:score) + @owner = @score.owner + end + + describe 'GET #show' do + it 'returns a success response' do + get :show, params: { id: @score.to_param } + expect(response).to be_successful + end + + it 'should return the correct score' do + get :show, params: { id: @score.to_param } + body = deserialize_response response + expect(body[:score]).to eq(@score.score) + expect(body[:team_id]).to eq(@score.team.id.to_s) + expect(body[:match_id]).to eq(@score.match.id.to_s) + end + end + + describe 'PUT #update' do + let(:valid_update) do + { + data: { + id: @score.id, + type: 'scores', + attributes: { + score: 42 + } + } + } + end + + context 'with valid params' do + context 'as owner' do + before(:each) do + apply_authentication_headers_for @owner + end + + it 'updates the requested score' do + put :update, params: { id: @score.to_param }.merge(valid_update) + @score.reload + expect(@score.score).to eq(valid_update[:data][:attributes][:score]) + end + + it 'renders a response with the updated team' do + put :update, params: { id: @score.to_param }.merge(valid_update) + expect(response).to be_successful + body = deserialize_response response + expect(body[:score]).to eq(valid_update[:data][:attributes][:score]) + end + end + + context 'as another user' do + before(:each) do + apply_authentication_headers_for create(:user) + end + + it 'renders a forbidden error response' do + put :update, params: { id: @score.to_param }.merge(valid_update) + expect(response).to have_http_status(:forbidden) + end + end + end + end +end diff --git a/spec/routing/scores_routing_spec.rb b/spec/routing/scores_routing_spec.rb new file mode 100644 index 0000000..679f0c9 --- /dev/null +++ b/spec/routing/scores_routing_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ScoresController, type: :routing do + describe 'routing' do + it 'routes to #show' do + expect(get: '/scores/1').to route_to('scores#show', id: '1') + end + + it 'routes to #update via PUT' do + expect(put: '/scores/1').to route_to('scores#update', id: '1') + end + + it 'routes to #update via PATCH' do + expect(patch: '/scores/1').to route_to('scores#update', id: '1') + end + end +end