Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "only" match policy to product rule #18

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -45,10 +45,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