Skip to content

Commit 320e06b

Browse files
authored
Merge pull request #6429 from mamhoff/fix-eligible-by-applicable-conditions
Promotions: Fix eligibility calculation in dry runs
2 parents fb05000 + bcd2b28 commit 320e06b

3 files changed

Lines changed: 144 additions & 20 deletions

File tree

promotions/app/models/solidus_promotions/benefit.rb

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -270,29 +270,28 @@ def available_calculators
270270
# @param dry_run [Boolean] whether to collect detailed eligibility information
271271
# @return [Boolean] true when all applicable conditions are eligible
272272
def eligible_by_applicable_conditions?(promotable, dry_run: false)
273-
conditions.filter_map do |condition|
274-
condition.applicable?(promotable) && begin
275-
eligible = condition.eligible?(promotable)
273+
conditions.map do |condition|
274+
next unless condition.applicable?(promotable)
275+
eligible = condition.eligible?(promotable)
276276

277-
break [false] if !eligible && !dry_run
277+
break [false] if !eligible && !dry_run
278278

279-
if dry_run
280-
if condition.eligibility_errors.details[:base].first
281-
code = condition.eligibility_errors.details[:base].first[:error_code]
282-
message = condition.eligibility_errors.full_messages.first
283-
end
284-
promotion.eligibility_results.add(
285-
item: promotable,
286-
condition: condition,
287-
success: eligible,
288-
code: eligible ? nil : (code || :coupon_code_unknown_error),
289-
message: eligible ? nil : (message || I18n.t(:coupon_code_unknown_error, scope: [:solidus_promotions, :eligibility_errors]))
290-
)
279+
if dry_run
280+
if condition.eligibility_errors.details[:base].first
281+
code = condition.eligibility_errors.details[:base].first[:error_code]
282+
message = condition.eligibility_errors.full_messages.first
291283
end
292-
293-
eligible
284+
promotion.eligibility_results.add(
285+
item: promotable,
286+
condition: condition,
287+
success: eligible,
288+
code: eligible ? nil : (code || :coupon_code_unknown_error),
289+
message: eligible ? nil : (message || I18n.t(:coupon_code_unknown_error, scope: [:solidus_promotions, :eligibility_errors]))
290+
)
294291
end
295-
end.all?
292+
293+
eligible
294+
end.compact.all?
296295
end
297296

298297
# All line items of the order that are eligible for this benefit.

promotions/spec/models/solidus_promotions/benefit_spec.rb

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,4 +321,129 @@ def line_item_adjustment_label(_line_item, _options = {})
321321

322322
it { is_expected.to include(SolidusPromotions::Conditions::User) }
323323
end
324+
325+
describe "#eligible_by_applicable_conditions" do
326+
let(:promotion) { build(:solidus_promotion) }
327+
let(:benefit) { described_class.new(conditions: conditions, promotion:) }
328+
let(:conditions) { [] }
329+
let(:order) { create(:order_with_line_items) }
330+
let(:condition) { SolidusPromotions::Conditions::LineItemProduct.new(products: [order.products.first]) }
331+
let(:dry_run) { false }
332+
let(:promotable) { order }
333+
334+
subject { benefit.eligible_by_applicable_conditions?(promotable, dry_run:) }
335+
336+
# No conditions, eligible
337+
it { is_expected.to be true }
338+
339+
context "for a non-applicable promotable" do
340+
let(:conditions) { [condition] }
341+
let(:condition) do
342+
Class.new(SolidusPromotions::Condition) do
343+
def line_item_eligible?(_)
344+
false
345+
end
346+
end.new
347+
end
348+
349+
it { is_expected.to be true }
350+
351+
context "if condition returns false" do
352+
let(:condition) { SolidusPromotions::Conditions::LineItemProduct.new(products: []) }
353+
354+
it { is_expected.to be true }
355+
356+
context "with dry_run true" do
357+
let(:dry_run) { true }
358+
359+
it { is_expected.to be true }
360+
end
361+
end
362+
end
363+
364+
context "with an applicable promotable" do
365+
let(:conditions) { [condition] }
366+
let(:condition) do
367+
Class.new(SolidusPromotions::Condition) do
368+
def line_item_eligible?(_)
369+
true
370+
end
371+
end.new
372+
end
373+
let(:promotable) { order.line_items.first }
374+
it { is_expected.to be true }
375+
376+
context "with dry_run true" do
377+
let(:dry_run) { true }
378+
379+
it { is_expected.to be true }
380+
end
381+
382+
context "when condition returns false" do
383+
let(:condition) do
384+
Class.new(SolidusPromotions::Condition) do
385+
def line_item_eligible?(_)
386+
eligibility_errors.add(:base, "You need to add an applicable product before applying this coupon code.")
387+
false
388+
end
389+
end.new
390+
end
391+
392+
it { is_expected.to be false }
393+
394+
context "with dry_run true" do
395+
let(:dry_run) { true }
396+
397+
it { is_expected.to be false }
398+
399+
it "adds an error message to the condition" do
400+
subject
401+
expect(promotion.eligibility_results.error_messages).to eq(["You need to add an applicable product before applying this coupon code."])
402+
end
403+
end
404+
end
405+
406+
context "with multiple conditions, both of which make the benefit unelegibible" do
407+
let(:promotable) { order }
408+
let(:taxon_condition) do
409+
Class.new(SolidusPromotions::Condition) do
410+
def order_eligible?(_)
411+
eligibility_errors.add(:base, "Wrong taxon")
412+
false
413+
end
414+
end.new
415+
end
416+
let(:product_condition) do
417+
Class.new(SolidusPromotions::Condition) do
418+
def order_eligible?(_)
419+
eligibility_errors.add(:base, "Wrong product.")
420+
false
421+
end
422+
end.new
423+
end
424+
let(:conditions) { [taxon_condition, product_condition] }
425+
426+
it { is_expected.to be false }
427+
428+
it "only asks the first condition and does not collect eligibility errors" do
429+
expect(taxon_condition).to receive(:order_eligible?).and_call_original
430+
expect(product_condition).not_to receive(:order_eligible?)
431+
subject
432+
expect(promotion.eligibility_results.error_messages).to be_empty
433+
end
434+
435+
context "if dry_run is true" do
436+
let(:dry_run) { true }
437+
it { is_expected.to be false }
438+
439+
it "asks both conditions and collects eligibility results" do
440+
expect(taxon_condition).to receive(:order_eligible?).and_call_original
441+
expect(product_condition).to receive(:order_eligible?).and_call_original
442+
subject
443+
expect(promotion.eligibility_results.error_messages.length).to eq(2)
444+
end
445+
end
446+
end
447+
end
448+
end
324449
end

promotions/spec/models/solidus_promotions/order_adjuster/discount_order_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
expect(promotion.eligibility_results.success?).to be false
196196
end
197197

198-
it "can tell us about all the errors" do
198+
it "can tell us about all the errors", :pending do
199199
subject
200200
expect(promotion.eligibility_results.error_messages).to eq(
201201
[

0 commit comments

Comments
 (0)