From c7bcc30f9aa142694e84195063a6093f428950b4 Mon Sep 17 00:00:00 2001 From: andrea longhi Date: Mon, 13 Jan 2020 20:31:47 +0100 Subject: Add tax rate calculator class This new calculator allows to retrieve tax rate information starting from a `Spree::Address` model. It shares some logic with the tax calculator, for example the ability to handle exceptions using `SolidusTaxJar.exception_handler` lambda. --- lib/super_good/solidus_taxjar.rb | 1 + .../solidus_taxjar/tax_rate_calculator.rb | 36 ++++++++ .../solidus_taxjar/tax_rate_calculator_spec.rb | 97 ++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 lib/super_good/solidus_taxjar/tax_rate_calculator.rb create mode 100644 spec/super_good/solidus_taxjar/tax_rate_calculator_spec.rb diff --git a/lib/super_good/solidus_taxjar.rb b/lib/super_good/solidus_taxjar.rb index 35d9155..1b1a4ac 100644 --- a/lib/super_good/solidus_taxjar.rb +++ b/lib/super_good/solidus_taxjar.rb @@ -7,6 +7,7 @@ require "super_good/solidus_taxjar/api_params" require "super_good/solidus_taxjar/api" require "super_good/solidus_taxjar/calculator_helper" require "super_good/solidus_taxjar/tax_calculator" +require "super_good/solidus_taxjar/tax_rate_calculator" require "super_good/solidus_taxjar/discount_calculator" module SuperGood diff --git a/lib/super_good/solidus_taxjar/tax_rate_calculator.rb b/lib/super_good/solidus_taxjar/tax_rate_calculator.rb new file mode 100644 index 0000000..dc3d771 --- /dev/null +++ b/lib/super_good/solidus_taxjar/tax_rate_calculator.rb @@ -0,0 +1,36 @@ +module SuperGood + module SolidusTaxJar + class TaxRateCalculator + include CalculatorHelper + def initialize(address, api: self.class.default_api) + @address = address + @api = api + end + + def calculate + return no_rate if SuperGood::SolidusTaxJar.test_mode + return no_rate if incomplete_address?(address) + return no_rate unless taxable_address?(address) + cache do + api.tax_rate_for(address).to_d + end + + rescue StandardError => e + exception_handler.(e) + no_rate + end + + private + + attr_reader :address, :api + + def no_rate + BigDecimal(0) + end + + def cache_key + SuperGood::SolidusTaxJar.cache_key.(address) + end + end + end +end diff --git a/spec/super_good/solidus_taxjar/tax_rate_calculator_spec.rb b/spec/super_good/solidus_taxjar/tax_rate_calculator_spec.rb new file mode 100644 index 0000000..9a4e2b8 --- /dev/null +++ b/spec/super_good/solidus_taxjar/tax_rate_calculator_spec.rb @@ -0,0 +1,97 @@ +require 'spec_helper' + +RSpec.describe ::SuperGood::SolidusTaxJar::TaxRateCalculator do + describe "#calculate" do + subject { calculator.calculate } + + let(:calculator) { described_class.new(address, api: dummy_api) } + + let(:dummy_api) do + instance_double ::SuperGood::SolidusTaxJar::API + end + + let(:dummy_tax_rate) { BigDecimal(0) } + + let(:incomplete_address) do + ::Spree::Address.new( + first_name: "Ronnie James", + zipcode: nil, + address1: nil, + city: "Beverly Hills", + state_name: "California", + country: ::Spree::Country.new(iso: "US") + ) + end + + let(:complete_address) do + incomplete_address.tap do |address| + address.zipcode = "90210" + address.address1 = "9900 Wilshire Blvd" + end + end + + shared_examples "returns the dummy tax rate" do + it { expect(subject).to eq dummy_tax_rate } + end + + context "when the address is not complete" do + let(:address) { incomplete_address } + + it_behaves_like "returns the dummy tax rate" + end + + context "when the address is complete" do + let(:address) { complete_address } + + context "when the address is not taxable" do + before do + allow(SuperGood::SolidusTaxJar.taxable_address_check) + .to receive(:call).with(address) + .and_return(false) + end + + it_behaves_like "returns the dummy tax rate" + end + + context "when the address is taxable" do + let(:tax_rate) { 0.03 } + + before do + allow(dummy_api).to receive(:tax_rate_for) { tax_rate } + end + + it "returns the expected tax rate" do + expect(subject).to eq tax_rate + end + end + end + + context "when the API encounters an error" do + let(:address) { complete_address } + + before do + allow(dummy_api).to receive(:tax_rate_for).and_raise("A bad thing happened.") + end + + it "calls the configured error handler" do + expect(SuperGood::SolidusTaxJar.exception_handler).to receive(:call) do |e| + expect(e).to be_a StandardError + expect(e.message).to eq "A bad thing happened." + end + + subject + end + + it_behaves_like "returns the dummy tax rate" + end + + context "when test_mode is set" do + let(:address) { complete_address } + + before { SuperGood::SolidusTaxJar.test_mode = true } + after { SuperGood::SolidusTaxJar.test_mode = false } + + it_behaves_like "returns the dummy tax rate" + end + end +end -- cgit v1.2.3