diff --git a/app/models/tag_rule/filter_payment_methods.rb b/app/models/tag_rule/filter_payment_methods.rb new file mode 100644 index 0000000000..da29426298 --- /dev/null +++ b/app/models/tag_rule/filter_payment_methods.rb @@ -0,0 +1,32 @@ +class TagRule::FilterPaymentMethods < TagRule + preference :matched_payment_methods_visibility, :string, default: "visible" + preference :payment_method_tags, :string, default: "" + + attr_accessible :preferred_matched_payment_methods_visibility, :preferred_payment_method_tags + + private + + # Warning: this should only EVER be called via TagRule#apply + def apply! + unless preferred_matched_payment_methods_visibility == "visible" + subject.reject!{ |pm| tags_match?(pm) } + end + end + + def apply_default! + if preferred_matched_payment_methods_visibility == "visible" + subject.reject!{ |pm| tags_match?(pm) } + end + end + + def tags_match?(payment_method) + payment_method_tags = payment_method.andand.tag_list || [] + preferred_tags = preferred_payment_method_tags.split(",") + ( payment_method_tags & preferred_tags ).any? + end + + def subject_class_matches? + subject.class == Array && + subject.all? { |i| i.class < Spree::PaymentMethod } + end +end diff --git a/spec/factories.rb b/spec/factories.rb index 2e29e74316..d0d7755cc0 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -294,6 +294,10 @@ FactoryGirl.define do enterprise { FactoryGirl.create :distributor_enterprise } end + factory :filter_payment_methods_tag_rule, class: TagRule::FilterPaymentMethods do + enterprise { FactoryGirl.create :distributor_enterprise } + end + factory :tag_rule, class: TagRule::DiscountOrder do enterprise { FactoryGirl.create :distributor_enterprise } before(:create) do |tr| diff --git a/spec/models/tag_rule/filter_payment_methods_spec.rb b/spec/models/tag_rule/filter_payment_methods_spec.rb new file mode 100644 index 0000000000..8eec06f773 --- /dev/null +++ b/spec/models/tag_rule/filter_payment_methods_spec.rb @@ -0,0 +1,83 @@ +require 'spec_helper' + +describe TagRule::FilterPaymentMethods, type: :model do + let!(:tag_rule) { create(:filter_payment_methods_tag_rule) } + + describe "determining whether tags match for a given payment method" do + context "when the payment method is nil" do + + it "returns false" do + expect(tag_rule.send(:tags_match?, nil)).to be false + end + end + + context "when the payment method is not nil" do + let(:payment_method) { create(:payment_method, tag_list: ["member","local","volunteer"]) } + + context "when the rule has no preferred payment method tags specified" do + before { allow(tag_rule).to receive(:preferred_payment_method_tags) { "" } } + it { expect(tag_rule.send(:tags_match?, payment_method)).to be false } + end + + context "when the rule has preferred customer tags specified that match ANY of the customer tags" do + before { allow(tag_rule).to receive(:preferred_payment_method_tags) { "wholesale,some_tag,member" } } + it { expect(tag_rule.send(:tags_match?, payment_method)).to be true } + end + + context "when the rule has preferred customer tags specified that match NONE of the customer tags" do + before { allow(tag_rule).to receive(:preferred_payment_method_tags) { "wholesale,some_tag,some_other_tag" } } + it { expect(tag_rule.send(:tags_match?, payment_method)).to be false } + end + end + end + + describe "applying the rule" do + # Assume that all validation is done by the TagRule base class + + let(:sm1) { create(:payment_method, tag_list: ["tag1", "something", "somethingelse"]) } + let(:sm2) { create(:payment_method, tag_list: ["tag2"]) } + let(:sm3) { create(:payment_method, tag_list: ["tag3"]) } + let!(:payment_methods) { [sm1, sm2, sm3] } + + before do + tag_rule.update_attribute(:preferred_payment_method_tags, "tag2") + tag_rule.context = {subject: payment_methods} + end + + context "apply!" do + context "when showing matching payment methods" do + before { tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, "visible") } + it "does nothing" do + tag_rule.send(:apply!) + expect(payment_methods).to eq [sm1, sm2, sm3] + end + end + + context "when hiding matching payment methods" do + before { tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, "hidden") } + it "removes matching payment methods from the list" do + tag_rule.send(:apply!) + expect(payment_methods).to eq [sm1, sm3] + end + end + end + + context "apply_default!" do + context "when showing matching payment methods" do + before { tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, "visible") } + it "remove matching payment methods from the list" do + tag_rule.send(:apply_default!) + expect(payment_methods).to eq [sm1, sm3] + end + end + + context "when hiding matching payment methods" do + before { tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, "hidden") } + it "does nothing" do + tag_rule.send(:apply_default!) + expect(payment_methods).to eq [sm1, sm2, sm3] + end + end + end + end +end