summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandrea longhi <andrea@spaghetticode.it>2020-01-13 20:31:47 +0100
committerandrea longhi <andrea@spaghetticode.it>2020-01-14 11:10:04 +0100
commitc7bcc30f9aa142694e84195063a6093f428950b4 (patch)
treef887729c05e9868b32b9a2c1915d40d13412fdfe
parent044bb66e25a440388431de27c67d437fe6cebfb6 (diff)
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.
-rw-r--r--lib/super_good/solidus_taxjar.rb1
-rw-r--r--lib/super_good/solidus_taxjar/tax_rate_calculator.rb36
-rw-r--r--spec/super_good/solidus_taxjar/tax_rate_calculator_spec.rb97
3 files changed, 134 insertions, 0 deletions
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