From e02dd8b22649f72b69b84ea5982a3d9b760311f3 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Thu, 20 Jun 2024 14:24:09 +0300 Subject: [PATCH] moved english controlelrs methods to concern --- .../concerns/english_offers/offerable.rb | 85 +++++++++++ app/controllers/concerns/offerable.rb | 14 +- app/controllers/english_offers_controller.rb | 135 ++++-------------- app/controllers/offers_controller.rb | 16 +-- test/integration/english_offers_test.rb | 4 +- 5 files changed, 131 insertions(+), 123 deletions(-) create mode 100644 app/controllers/concerns/english_offers/offerable.rb diff --git a/app/controllers/concerns/english_offers/offerable.rb b/app/controllers/concerns/english_offers/offerable.rb new file mode 100644 index 000000000..d503dd96e --- /dev/null +++ b/app/controllers/concerns/english_offers/offerable.rb @@ -0,0 +1,85 @@ +module EnglishOffers + module Offerable + extend ActiveSupport::Concern + + included do + before_render :find_or_initialize_autobidder, only: %i[new create edit update] + before_action :prevent_check_for_invalid_bid, only: [:update] + end + + protected + + def broadcast_update_auction_offer(auction) + Offers::UpdateBroadcastService.call({ auction: }) + end + + def update_auction_values(auction, message_text) + AutobiderService.autobid(auction) + auction.update_ends_at(@offer) + + flash[:notice] = message_text + redirect_to root_path + end + + def inform_about_invalid_bid_amount + formatted_starting_price = format('%.2f', @auction.starting_price) + flash[:alert] = t('english_offers.create.bid_must_be', minimum: formatted_starting_price) + + if turbo_frame_request? + render turbo_stream: turbo_stream.action(:redirect, root_path) + else + redirect_to root_path, status: :see_other + end + end + + def find_or_initialize_autobidder + @autobider = current_user&.autobiders&.find_or_initialize_by(domain_name: @auction.domain_name) + end + + def prevent_check_for_invalid_bid + auction = Auction.with_user_offers(current_user.id).find_by(uuid: @offer.auction.uuid) + + return unless bid_is_bad?(auction:, update_params:) + + flash[:alert] = + "#{t('english_offers.show.bid_failed', price: format('%.2f', auction.highest_price.to_f).tr('.', ','))}" + + if turbo_frame_request? + render turbo_stream: turbo_stream.action(:redirect, root_path) + else + redirect_to root_path, status: :see_other + end + end + + def check_first_bid_for_english_auction(params, auction) + return true if auction.blind? + + starting_price = auction.starting_price + price = params[:price].to_f + + price.to_f >= starting_price.to_f + end + + private + + def bid_is_bad?(auction:, update_params:) + !additional_check_for_bids(auction, update_params[:price]) || + !check_bids_for_english_auction(update_params, auction) + end + + def additional_check_for_bids(auction, current_bid) + order = auction.offers.order(updated_at: :desc).first + + Money.new(order.cents).to_f < current_bid.to_f + end + + def check_bids_for_english_auction(params, auction) + return true if auction.blind? + + minimum = auction.min_bids_step.to_f + price = params[:price].to_f + + price >= minimum + end + end +end diff --git a/app/controllers/concerns/offerable.rb b/app/controllers/concerns/offerable.rb index 7473d24dd..6d393afac 100644 --- a/app/controllers/concerns/offerable.rb +++ b/app/controllers/concerns/offerable.rb @@ -11,9 +11,17 @@ module Offerable protected def check_for_ban - if Ban.valid.where(user_id: current_user).where(domain_name: @auction.domain_name).any? || current_user.completely_banned? - redirect_to root_path, flash: { alert: I18n.t("#{params[:controller]}.create.ban") } and return - end + is_ban = Ban.valid.where(user_id: current_user).where(domain_name: @auction.domain_name).any? + is_ban ||= current_user.completely_banned? + return unless is_ban + + redirect_to root_path, flash: { alert: I18n.t("#{params[:controller]}.create.ban") } and return + end + + def inform_invalid_captcha + @show_checkbox_recaptcha = true unless @success + flash[:alert] = t('offers.form.captcha_verification') + redirect_to root_path, status: :see_other end private diff --git a/app/controllers/english_offers_controller.rb b/app/controllers/english_offers_controller.rb index 9dbe77f66..a8e87137b 100644 --- a/app/controllers/english_offers_controller.rb +++ b/app/controllers/english_offers_controller.rb @@ -1,12 +1,13 @@ -# rubocop:disable Metrics +# frozen_string_literal: true + class EnglishOffersController < ApplicationController include BeforeRender include Offerable protect_from_forgery with: :null_session + # order is important before_action :set_offer, only: %i[show edit update] - before_render :find_or_initialize_autobidder, only: %i[new create edit update] - before_action :prevent_check_for_invalid_bid, only: [:update] + include EnglishOffers::Offerable include RecaptchaValidatable recaptcha_action 'english_offer' @@ -22,40 +23,25 @@ def new # POST /auctions/aa450f1a-45e2-4f22-b2c3-f5f46b5f906b/offers def create - unless check_first_bid_for_english_auction(create_params, @auction) - formatted_starting_price = format('%.2f', @auction.starting_price) - flash[:alert] = t('english_offers.create.bid_must_be', minimum: formatted_starting_price) - - if turbo_frame_request? - render turbo_stream: turbo_stream.action(:redirect, root_path) - else - redirect_to root_path, status: :see_other and return - end - end + inform_about_invalid_bid_amount and return unless check_first_bid_for_english_auction(create_params, @auction) + inform_invalid_captcha and return unless recaptcha_valid @offer = Offer.new(create_params) @offer.username = Username::GenerateUsernameService.new.call authorize! :manage, @offer - if recaptcha_valid - if create_predicate(@auction) - broadcast_update_auction_offer(@auction) - send_outbided_notification(auction: @auction, offer: @offer, flash:) - update_auction_values(@auction, t('english_offers.create.created')) - else - flash[:alert] = if @offer.errors.full_messages_for(:cents).present? - @offer.errors.full_messages_for(:cents).join - else - @offer.errors.full_messages.join('; ') - end - - redirect_to root_path and return - end + if create_predicate(@auction) + broadcast_update_auction_offer(@auction) + send_outbided_notification(auction: @auction, offer: @offer, flash:) + update_auction_values(@auction, t('english_offers.create.created')) else - @show_checkbox_recaptcha = true unless @success - flash.now[:alert] = t('english_offers.form.captcha_verification') + flash[:alert] = if @offer.errors.full_messages_for(:cents).present? + @offer.errors.full_messages_for(:cents).join + else + @offer.errors.full_messages.join('; ') + end - redirect_to root_path, status: :see_other and return + redirect_to root_path and return end end @@ -74,71 +60,24 @@ def edit def update @auction = Auction.english.with_user_offers(current_user.id).find_by(uuid: @offer.auction.uuid) redirect_to auction_path(@auction.uuid) and return if update_not_allowed(@auction) + inform_invalid_captcha and return unless recaptcha_valid - if recaptcha_valid - if update_predicate(@auction) - broadcast_update_auction_offer(@auction) - send_outbided_notification(auction: @auction, offer: @offer, flash:) - update_auction_values(@auction, t('english_offers.edit.bid_updated')) - else - flash[:alert] = if @offer.errors.full_messages_for(:cents).present? - @offer.errors.full_messages_for(:cents).join - else - @offer.errors.full_messages.join('; ') - end - - redirect_to root_path - end + if update_predicate(@auction) + broadcast_update_auction_offer(@auction) + send_outbided_notification(auction: @auction, offer: @offer, flash:) + update_auction_values(@auction, t('english_offers.edit.bid_updated')) else - @show_checkbox_recaptcha = true unless @success - flash.now[:alert] = t('english_offers.form.captcha_verification') - redirect_to root_path, status: :see_other - end - end - - private - - def find_or_initialize_autobidder - @autobider = current_user&.autobiders&.find_or_initialize_by(domain_name: @auction.domain_name) - end - - def broadcast_update_auction_offer(auction) - Offers::UpdateBroadcastService.call({ auction: }) - end - - def update_auction_values(auction, message_text) - AutobiderService.autobid(auction) - auction.update_ends_at(@offer) - - flash[:notice] = message_text - redirect_to root_path - end - - def prevent_check_for_invalid_bid - auction = Auction.with_user_offers(current_user.id).find_by(uuid: @offer.auction.uuid) - - return unless bid_is_bad?(auction:, update_params:) + flash[:alert] = if @offer.errors.full_messages_for(:cents).present? + @offer.errors.full_messages_for(:cents).join + else + @offer.errors.full_messages.join('; ') + end - flash[:alert] = - "#{t('english_offers.show.bid_failed', price: format('%.2f', auction.highest_price.to_f).tr('.', ','))}" - - if turbo_frame_request? - render turbo_stream: turbo_stream.action(:redirect, root_path) - else - redirect_to root_path, status: :see_other + redirect_to root_path end end - def bid_is_bad?(auction:, update_params:) - !additional_check_for_bids(auction, update_params[:price]) || - !check_bids_for_english_auction(update_params, auction) - end - - def additional_check_for_bids(auction, current_bid) - order = auction.offers.order(updated_at: :desc).first - - Money.new(order.cents).to_f < current_bid.to_f - end + private def create_predicate(auction) @offer.save && auction.update_minimum_bid_step(create_params[:price].to_f) && @offer.reload @@ -148,24 +87,6 @@ def create_params params.require(:offer).permit(:auction_id, :user_id, :price, :billing_profile_id, :username) end - def check_first_bid_for_english_auction(params, auction) - return true if auction.blind? - - starting_price = auction.starting_price - price = params[:price].to_f - - price.to_f >= starting_price.to_f - end - - def check_bids_for_english_auction(params, auction) - return true if auction.blind? - - minimum = auction.min_bids_step.to_f - price = params[:price].to_f - - price >= minimum - end - def update_predicate(auction) @offer.update(update_params) && auction.update_minimum_bid_step(create_params[:price].to_f) && diff --git a/app/controllers/offers_controller.rb b/app/controllers/offers_controller.rb index 6c46185a2..f6ed3ecda 100644 --- a/app/controllers/offers_controller.rb +++ b/app/controllers/offers_controller.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -# rubocop:disable Metrics class OffersController < ApplicationController include Offerable @@ -12,8 +11,6 @@ class OffersController < ApplicationController # GET /auctions/aa450f1a-45e2-4f22-b2c3-f5f46b5f906b/offers/new def new - prevent_check_for_existed_offer and return if @auction.offer_from_user(current_user.id) - BillingProfile.create_default_for_user(current_user.id) @offer = Offer.new(auction_id: @auction.id, user_id: current_user.id) end @@ -21,10 +18,11 @@ def new # POST /auctions/aa450f1a-45e2-4f22-b2c3-f5f46b5f906b/offers def create existing_offer = @auction.offer_from_user(current_user.id) - @offer = Offer.new(create_params) authorize! :manage, @offer + inform_invalid_captcha and return unless recaptcha_valid + respond_to do |format| if existing_offer format.html do @@ -34,9 +32,7 @@ def create format.html { redirect_to root_path, notice: t('.created') } format.json { render :show, status: :created, location: @offer } else - @show_checkbox_recaptcha = true unless @success - flash[:alert] = recaptcha_valid ? @offer.errors.full_messages.join('; ') : t('offers.form.captcha_verification') - + flash[:alert] = @offer.errors.full_messages.join('; ') format.html { redirect_to root_path, status: :see_other } format.json { render json: @offer.errors, status: :unprocessable_entity } end @@ -63,6 +59,8 @@ def edit # PUT /offers/aa450f1a-45e2-4f22-b2c3-f5f46b5f906b def update auction = @offer.auction + + inform_invalid_captcha and return unless recaptcha_valid redirect_to root_path and return if update_not_allowed(auction) respond_to do |format| @@ -70,9 +68,7 @@ def update format.html { redirect_to root_path, notice: t(:updated), status: :see_other } format.json { render :show, status: :ok, location: @offer } else - @show_checkbox_recaptcha = true unless @success - flash[:alert] = recaptcha_valid ? @offer.errors.full_messages.join('; ') : t('offers.form.captcha_verification') - + flash[:alert] = @offer.errors.full_messages.join('; ') format.html { redirect_to root_path, status: :see_other } format.json { render json: @offer.errors, status: :unprocessable_entity } end diff --git a/test/integration/english_offers_test.rb b/test/integration/english_offers_test.rb index fdb2e7793..b2010ccd5 100644 --- a/test/integration/english_offers_test.rb +++ b/test/integration/english_offers_test.rb @@ -152,9 +152,7 @@ def test_banned_user_cannot_create_an_offer } } - post auction_english_offers_path(auction_uuid: @auction.uuid), - params: params, - headers: { "HTTP_REFERER" => root_path } + post auction_english_offers_path(auction_uuid: @auction.uuid), params: params assert_equal flash[:alert], I18n.t('english_offers.create.ban') assert @auction.offers.empty?