diff --git a/core/app/models/spree/zone.rb b/core/app/models/spree/zone.rb index 4df41080e0c..cb251ab1185 100644 --- a/core/app/models/spree/zone.rb +++ b/core/app/models/spree/zone.rb @@ -26,6 +26,7 @@ class Zone < Spree::Base country_ids ).uniq end + scope :for_address, ->(address) { with_member_ids(address.try(:state_id), address.try(:country_id)) } alias :members :zone_members accepts_nested_attributes_for :zone_members, allow_destroy: true, reject_if: proc { |a| a['zoneable_id'].blank? } diff --git a/core/spec/models/spree/zone_spec.rb b/core/spec/models/spree/zone_spec.rb index 36b13c718f6..4b37ac71b78 100644 --- a/core/spec/models/spree/zone_spec.rb +++ b/core/spec/models/spree/zone_spec.rb @@ -1,6 +1,50 @@ require 'spec_helper' describe Spree::Zone, type: :model do + describe 'for_address' do + let(:new_york_address) { create(:address, state_code: "NY") } + let(:alabama_address) { create(:address) } + let(:canada_address) { create(:address, country_iso_code: "CA") } + + let!(:new_york_zone) { create(:zone, states: [new_york_address.state]) } + let!(:alabama_zone) { create(:zone, states: [alabama_address.state]) } + let!(:united_states_zone) { create(:zone, countries: [new_york_address.country]) } + let!(:canada_zone) { create(:zone, countries: [canada_address.country]) } + let!(:north_america_zone) { create(:zone, countries: [canada_address.country, new_york_address.country]) } + subject { Spree::Zone.for_address(address) } + + context 'when there is no address' do + let(:address) { nil } + it 'returns an empty relation' do + expect(subject).to eq([]) + end + end + + context 'for an address in New York' do + let(:address) { new_york_address } + + it 'matches the New York zone' do + expect(subject).to include(new_york_zone) + end + + it 'matches the United States zone' do + expect(subject).to include(united_states_zone) + end + + it 'does not match the Alabama zone' do + expect(subject).not_to include(alabama_zone) + end + + it 'does not match the Canadian zone' do + expect(subject).not_to include(canada_zone) + end + + it 'matches the North America zone' do + expect(subject).to include(north_america_zone) + end + end + end + context "#match" do let(:country_zone) { create(:zone, name: 'CountryZone') } let(:country) do