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

Make cart taxes configurable via Spree::Store object #933

Merged
merged 8 commits into from Mar 16, 2016
Next Next commit
Introduce Spree::Tax::TaxLocation class
This class is intended to behave like an address when passed
into Spree::Zone.for_address, but not have any of the complex behaviour
of Spree::Address.
mamhoff committed Mar 14, 2016
commit 3b6b7c69402e8bea7647e0a9c352c19f99f0aec0
33 changes: 33 additions & 0 deletions core/app/models/spree/tax/tax_location.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Spree
module Tax
# A class exclusively used as a drop-in replacement for a default tax address.
# It responds to `:country_id` and `:state_id`.
#
# @attr_reader [Integer] country_id the ID of a Spree::Country object
# @attr_reader [Integer] state_id the ID of a Spree::State object
class TaxLocation
attr_reader :country_id, :state_id

# Create a new TaxLocation object
#
# @see Spree::Zone.for_address
#
# @param [Spree::Country] country a Spree::Country object, default: nil
# @param [Spree::State] state a Spree::State object, default: nil
#
# @return [Spree::Tax::TaxLocation] a Spree::Tax::TaxLocation object
def initialize(country: nil, state: nil)
@country_id = country && country.id
@state_id = state && state.id
end

def ==(other)
state_id == other.state_id && country_id == other.country_id
end

def empty?
country_id.nil? && state_id.nil?
end
end
end
end
68 changes: 68 additions & 0 deletions core/spec/models/spree/tax/tax_location_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require 'spec_helper'

RSpec.describe Spree::Tax::TaxLocation do
let(:country) { build_stubbed(:country) }
let(:state) { build_stubbed(:state) }

subject { described_class.new }

it { is_expected.to respond_to(:state_id) }
it { is_expected.to respond_to(:country_id) }

describe "default values" do
it "has a nil state and country id" do
expect(subject.state_id).to eq(nil)
expect(subject.country_id).to eq(nil)
end
end

describe '#==' do
let(:other) { described_class.new(state: nil, country: nil) }

it 'compares the values of state id and country id and does not care about object identity' do
expect(subject).to eq(other)
end
end

describe "initialization" do
subject { described_class.new(args) }

context 'with a country object' do
let(:args) { { country: country } }

it "will yield a location with that country's id" do
expect(subject.country_id).to eq(country.id)
end
end

context 'with a state object' do
let(:args) { { state: state } }

it "will yield a location with that state's id" do
expect(subject.state_id).to eq(state.id)
end
end
end

describe "#empty?" do
subject { described_class.new(args).empty? }

context 'with a country present' do
let(:args) { { country: country } }

it { is_expected.to be false }
end

context 'with a state present' do
let(:args) { { state: state } }

it { is_expected.to be false }
end

context 'with no region data present' do
let(:args) { {} }

it { is_expected.to be true }
end
end
end