diff --git a/app/controllers/classified_listings_controller.rb b/app/controllers/classified_listings_controller.rb index e74d6b3af..0e59ad870 100644 --- a/app/controllers/classified_listings_controller.rb +++ b/app/controllers/classified_listings_controller.rb @@ -65,16 +65,18 @@ class ClassifiedListingsController < ApplicationController # NOTE: this should probably be split in three different actions: bump, unpublish, publish if listing_params[:action] == "bump" cost = ClassifiedListing.cost_by_category(@classified_listing.category) - if current_user.credits.unspent.size >= cost - ActiveRecord::Base.transaction do - Credits::Buyer.call( - purchaser: current_user, - purchase: @classified_listing, - cost: cost, - ) - raise ActiveRecord::Rollback unless bump_listing - end + org = Organization.find_by(id: @classified_listing.organization_id) + + available_org_credits = org.credits.unspent if org + available_user_credits = current_user.credits.unspent + + if org && available_org_credits.size >= cost + charge_credits_before_bump(org, cost) + elsif available_user_credits.size >= cost + charge_credits_before_bump(current_user, cost) + else + redirect_to(credits_path, notice: "Not enough available credits") && return end elsif listing_params[:action] == "unpublish" unpublish_listing @@ -136,6 +138,18 @@ class ClassifiedListingsController < ApplicationController end end + def charge_credits_before_bump(purchaser, cost) + ActiveRecord::Base.transaction do + Credits::Buyer.call( + purchaser: purchaser, + purchase: @classified_listing, + cost: cost, + ) + + raise ActiveRecord::Rollback unless bump_listing + end + end + def set_classified_listing @classified_listing = ClassifiedListing.find(params[:id]) end diff --git a/spec/requests/classified_listings_spec.rb b/spec/requests/classified_listings_spec.rb index bb1ec1ae3..aae967c9b 100644 --- a/spec/requests/classified_listings_spec.rb +++ b/spec/requests/classified_listings_spec.rb @@ -8,7 +8,8 @@ RSpec.describe "ClassifiedListings", type: :request do title: "something", body_markdown: "something else", category: "cfp", - tag_list: "" + tag_list: "", + contact_via_connect: true } } end @@ -160,6 +161,8 @@ RSpec.describe "ClassifiedListings", type: :request do describe "PUT /listings/:id" do let(:listing) { create(:classified_listing, user: user) } + let(:organization) { create(:organization) } + let(:org_listing) { create(:classified_listing, user: user, organization: organization) } before do sign_in user @@ -168,10 +171,11 @@ RSpec.describe "ClassifiedListings", type: :request do context "when the bump action is called" do let(:params) { { classified_listing: { action: "bump" } } } - it "does not bump the listing if the use has not enough credits" do + it "does not bump the user listing and redirects to credits if the user has not enough credits" do previous_bumped_at = listing.bumped_at put "/listings/#{listing.id}", params: params expect(listing.reload.bumped_at.to_i).to eq(previous_bumped_at.to_i) + expect(response.body).to redirect_to("/credits") end it "does not subtract spent credits if the user has not enough credits" do @@ -198,6 +202,27 @@ RSpec.describe "ClassifiedListings", type: :request do end.to change(user.credits.spent, :size).by(cost) expect(listing.reload.bumped_at >= previous_bumped_at).to eq(true) end + + it "bumps the org listing using org credits before user credits" do + cost = ClassifiedListing.cost_by_category(org_listing.category) + create_list(:credit, cost, organization: organization) + create_list(:credit, cost, user: user) + previous_bumped_at = org_listing.bumped_at + expect do + put "/listings/#{org_listing.id}", params: params + end.to change(organization.credits.spent, :size).by(cost) + expect(org_listing.reload.bumped_at >= previous_bumped_at).to eq(true) + end + + it "bumps the org listing using user credits if org credits insufficient and user credits are" do + cost = ClassifiedListing.cost_by_category(org_listing.category) + create_list(:credit, cost, user: user) + previous_bumped_at = org_listing.bumped_at + expect do + put "/listings/#{org_listing.id}", params: params + end.to change(user.credits.spent, :size).by(cost) + expect(org_listing.reload.bumped_at >= previous_bumped_at).to eq(true) + end end end end