From ed8738d60efaf23c5919d8673b9372f3d07e58e9 Mon Sep 17 00:00:00 2001 From: Thor77 Date: Fri, 14 Jun 2019 14:25:22 +0200 Subject: [PATCH] Add BetsController --- app/controllers/bets_controller.rb | 34 +++++++++ spec/controllers/bets_controller_spec.rb | 91 ++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 app/controllers/bets_controller.rb create mode 100644 spec/controllers/bets_controller_spec.rb diff --git a/app/controllers/bets_controller.rb b/app/controllers/bets_controller.rb new file mode 100644 index 0000000..cc6e250 --- /dev/null +++ b/app/controllers/bets_controller.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +class BetsController < ApplicationController + before_action :set_match, only: %i[index create] + before_action :authenticate_user!, only: %i[create] + rescue_from UserServiceError, with: :handle_user_service_error + + def index + render json: @match.bets.group_by(&:team).map { |team, bets| + { + team: ActiveModelSerializers::SerializableResource.new(team).as_json, + bets: bets.size + } + } + end + + def create + render json: user_service.bet!(@match, Team.find_by(id: params[:team])) + end + + private + + def user_service + @user_service ||= UserService.new current_user + end + + def set_match + @match = Match.find params[:match_id] + end + + def handle_user_service_error(exception) + render json: { error: exception.message }, status: :unprocessable_entity + end +end diff --git a/spec/controllers/bets_controller_spec.rb b/spec/controllers/bets_controller_spec.rb new file mode 100644 index 0000000..c414241 --- /dev/null +++ b/spec/controllers/bets_controller_spec.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe BetsController, type: :controller do + let(:team) do + create(:team) + end + + let(:match) do + match = create(:playoff_match) + match.bets << create(:bet, team: team) + match + end + + let(:params) do + { + match_id: match.to_param + } + end + + describe 'GET #index' do + it 'returns a list of bet counts' do + get :index, params: params + body = deserialize_response response + expect(body.size).to eq(1) + expect(body.first[:team][:id]).to eq(team.id) + expect(body.first[:bets]).to eq(1) + end + end + + describe 'POST #create' do + let(:create_params) do + params.merge(team: team.to_param) + end + + let(:user_service) do + instance_double('UserService') + end + + before do + allow(controller).to receive(:user_service).and_return(user_service) + end + + context 'without authentication headers' do + it 'renders an unauthorized error response' do + post :create, params: params + expect(response).to have_http_status(:unauthorized) + end + end + + context 'with authentication headers' do + before(:each) do + apply_authentication_headers_for create(:user) + end + + it 'returns the created bet' do + bet = create(:bet) + expect(user_service).to receive(:bet!).and_return(bet) + post :create, params: create_params + expect(response).to be_successful + body = deserialize_response(response) + expect(body[:id]).to eq(bet.id) + end + + context 'given a team' do + it 'calls the service' do + expect(user_service).to receive(:bet!).with(match, team) + post :create, params: create_params + end + end + + context 'given no team' do + it 'calls the service' do + expect(user_service).to receive(:bet!).with(match, nil) + post :create, params: params.merge(team: nil) + end + end + + context 'on service exception' do + it 'returns an error response' do + msg = 'an error' + expect(user_service).to receive(:bet!).and_throw(UserServiceError.new(msg)) + post :create, params: create_params + expect(response).to have_http_status(:unprocessable_entity) + expect(deserialize_response(response)[:error]).to eq(msg) + end + end + end + end +end