@@ -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
324449end
0 commit comments