Skip to content

Commit

Permalink
Merge pull request solidusio#18 from friendlycart/product-only-rule
Browse files Browse the repository at this point in the history
Add "only" match policy to product rule
  • Loading branch information
mamhoff committed Oct 10, 2023
2 parents b3a4ed8 + 2ebb69a commit 78d1449
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
7 changes: 6 additions & 1 deletion app/models/solidus_friendly_promotions/rules/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def preload_relations
[:products]
end

MATCH_POLICIES = %w[any all none].freeze
MATCH_POLICIES = %w[any all none only].freeze

validates :preferred_match_policy, inclusion: {in: MATCH_POLICIES}

Expand Down Expand Up @@ -50,6 +50,11 @@ def eligible?(order, _options = {})
eligibility_errors.add(:base, eligibility_error_message(:has_excluded_product),
error_code: :has_excluded_product)
end
when "only"
unless order_products(order).all? { |product| eligible_products.include?(product) }
eligibility_errors.add(:base, eligibility_error_message(:has_excluded_product),
error_code: :has_excluded_product)
end
else
raise "unexpected match policy: #{preferred_match_policy.inspect}"
end
Expand Down
9 changes: 5 additions & 4 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ en:
promotions: This is used to determine the promotional discount to be applied to an order, an item, or shipping charges.
product_rule:
choose_products: Choose products
label: Order must contain %{select} of these products
match_all: all
match_any: at least one
match_none: none
label: Order must contain %{select} these products
match_all: all of
match_any: at least one of
match_none: none of
match_only: only
product_source:
group: From product group
manual: Manually choose
Expand Down
37 changes: 37 additions & 0 deletions spec/models/solidus_friendly_promotions/rules/product_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,43 @@
end
end

context "with 'only' match policy" do
let(:rule_options) { super().merge(preferred_match_policy: "only") }

it "is not eligible if none of the order's products are in eligible products" do
allow(rule).to receive_messages(order_products: [product_one])
allow(rule).to receive_messages(eligible_products: [product_two, product_three])
expect(rule).not_to be_eligible(order)
end

it "is eligible if all of the order's products are in eligible products" do
allow(rule).to receive_messages(order_products: [product_one])
allow(rule).to receive_messages(eligible_products: [product_one])
expect(rule).to be_eligible(order)
end

context "when any of the order's products are in eligible products" do
before do
allow(rule).to receive_messages(order_products: [product_one, product_two])
allow(rule).to receive_messages(eligible_products: [product_two, product_three])
end

it { expect(rule).not_to be_eligible(order) }

it "sets an error message" do
rule.eligible?(order)
expect(rule.eligibility_errors.full_messages.first)
.to eq "Your cart contains a product that prevents this coupon code from being applied."
end

it "sets an error code" do
rule.eligible?(order)
expect(rule.eligibility_errors.details[:base].first[:error_code])
.to eq :has_excluded_product
end
end
end

context "with an invalid match policy" do
let(:rule) do
described_class.create!(
Expand Down

0 comments on commit 78d1449

Please sign in to comment.