super_good-solidus_taxjar 0.18.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +58 -0
  3. data/CHANGELOG.md +118 -5
  4. data/Gemfile +28 -10
  5. data/README.md +300 -45
  6. data/Rakefile +3 -0
  7. data/app/controllers/spree/admin/taxjar_settings_controller.rb +93 -0
  8. data/app/controllers/spree/admin/taxjar_transactions_controller.rb +37 -0
  9. data/app/controllers/spree/admin/transaction_sync_batches_controller.rb +18 -0
  10. data/app/jobs/super_good/solidus_taxjar/backfill_transaction_sync_batch_job.rb +23 -0
  11. data/app/jobs/super_good/solidus_taxjar/replace_transaction_job.rb +26 -0
  12. data/app/jobs/super_good/solidus_taxjar/report_transaction_job.rb +22 -0
  13. data/app/models/super_good/solidus_taxjar/configuration.rb +27 -0
  14. data/app/models/super_good/solidus_taxjar/order_transaction.rb +16 -0
  15. data/app/models/super_good/solidus_taxjar/refund_transaction.rb +13 -0
  16. data/app/models/super_good/solidus_taxjar/transaction_sync_batch.rb +11 -0
  17. data/app/models/super_good/solidus_taxjar/transaction_sync_log.rb +8 -0
  18. data/app/overrides/spree/admin/orders_controller_override.rb +12 -0
  19. data/app/overrides/spree/admin/shared/_order_submenu/add_taxjar_sync_history_tab.html.erb.deface +6 -0
  20. data/app/overrides/spree/admin/shared/_order_summary/add_taxjar_reported_at.html.erb.deface +30 -0
  21. data/app/overrides/spree/admin/shared/_taxes_tabs/add_configuration_menu_items.html.erb.deface +5 -0
  22. data/app/overrides/super_good/solidus_taxjar/spree/order_override.rb +21 -0
  23. data/app/views/spree/admin/orders/taxjar_transactions.html.erb +4 -0
  24. data/app/views/spree/admin/shared/_transaction_sync_log_table.html.erb +35 -0
  25. data/app/views/spree/admin/taxjar_settings/_nexus_regions.html.erb +23 -0
  26. data/app/views/spree/admin/taxjar_settings/_tax_categories.html.erb +41 -0
  27. data/app/views/spree/admin/taxjar_settings/edit.html.erb +17 -0
  28. data/app/views/spree/admin/taxjar_settings/edit_no_api_key.html.erb +21 -0
  29. data/app/views/spree/admin/transaction_sync_batches/index.html.erb +50 -0
  30. data/app/views/spree/admin/transaction_sync_batches/show.html.erb +7 -0
  31. data/bin/console +2 -0
  32. data/bin/rails-engine +1 -1
  33. data/bin/sandbox +43 -36
  34. data/bin/setup +3 -3
  35. data/config/routes.rb +19 -0
  36. data/db/migrate/20210908205201_create_taxjar_order_transactions.rb +16 -0
  37. data/db/migrate/20211008175113_create_taxjar_refund_transaction.rb +15 -0
  38. data/db/migrate/20211008183858_add_transaction_date_to_order_transaction.rb +5 -0
  39. data/db/migrate/20211119143354_create_configuration.rb +8 -0
  40. data/db/migrate/20220405213958_create_transaction_sync_batches.rb +7 -0
  41. data/db/migrate/20220405215225_create_transaction_sync_logs.rb +14 -0
  42. data/db/migrate/20220908181655_add_dates_to_transaction_sync_batch.rb +6 -0
  43. data/db/migrate/20220912182210_allow_null_transaction_sync_batches_on_logs.rb +5 -0
  44. data/db/migrate/20230320211309_add_refund_transaction_to_sync_logs.rb +5 -0
  45. data/lib/generators/super_good/solidus_taxjar/install/install_generator.rb +68 -0
  46. data/lib/super_good/engine.rb +2 -0
  47. data/lib/super_good/solidus_taxjar/addresses.rb +3 -3
  48. data/lib/super_good/solidus_taxjar/api.rb +45 -9
  49. data/lib/super_good/solidus_taxjar/api_params.rb +93 -26
  50. data/lib/super_good/solidus_taxjar/backfill_transactions.rb +11 -0
  51. data/lib/super_good/solidus_taxjar/cached_api.rb +23 -0
  52. data/lib/super_good/solidus_taxjar/calculator_helper.rb +34 -5
  53. data/lib/super_good/solidus_taxjar/discount_calculator.rb +1 -1
  54. data/lib/super_good/solidus_taxjar/overrides/request_override.rb +15 -0
  55. data/lib/super_good/solidus_taxjar/reportable.rb +91 -0
  56. data/lib/super_good/solidus_taxjar/reporting.rb +44 -0
  57. data/lib/super_good/solidus_taxjar/spree/legacy_reporting_subscriber.rb +41 -0
  58. data/lib/super_good/solidus_taxjar/spree/reporting_subscriber.rb +40 -0
  59. data/lib/super_good/solidus_taxjar/tax_calculator.rb +10 -4
  60. data/lib/super_good/solidus_taxjar/testing_support/factories/address_factory.rb +11 -0
  61. data/lib/super_good/solidus_taxjar/testing_support/factories/configuration_factory.rb +11 -0
  62. data/lib/super_good/solidus_taxjar/testing_support/factories/order_transaction_factory.rb +22 -0
  63. data/lib/super_good/solidus_taxjar/testing_support/factories/refund_transaction_factory.rb +7 -0
  64. data/lib/super_good/solidus_taxjar/testing_support/factories/transaction_sync_batch_factory.rb +9 -0
  65. data/lib/super_good/solidus_taxjar/testing_support/factories/transaction_sync_log_factory.rb +18 -0
  66. data/lib/super_good/solidus_taxjar/transaction_id_generator.rb +45 -0
  67. data/lib/super_good/solidus_taxjar/version.rb +1 -1
  68. data/lib/super_good/solidus_taxjar.rb +30 -3
  69. data/spec/features/spree/admin/backfill_transactions_spec.rb +138 -0
  70. data/spec/features/spree/admin/refund_spec.rb +167 -0
  71. data/spec/features/spree/admin/reporting_to_taxjar_spec.rb +156 -0
  72. data/spec/features/spree/admin/taxjar_settings_spec.rb +90 -0
  73. data/spec/features/spree/checkout_spec.rb +58 -0
  74. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/GET_sync_nexus_regions/Taxjar_API_token_is_not_set/doesn_t_make_a_request_for_the_nexus_regions.yml +57 -0
  75. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/GET_sync_tax_categories/Taxjar_API_token_is_not_set/doesn_t_make_a_request_for_the_tax_categories.yml +57 -0
  76. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_API_token_is_set/shows_the_settings_page.yml +2437 -0
  77. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_API_token_isn_t_set/doesn_t_show_any_other_TaxJar_features.yml +57 -0
  78. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_API_token_isn_t_set/shows_a_descriptive_error_message.yml +57 -0
  79. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_reporting_is_enabled/shows_that_reporting_is_enabled.yml +2382 -0
  80. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/order_is_shipped/the_user_backfills_their_transactions.yml +2511 -0
  81. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/the_user_navigates_to_the_TaxJar_Settings.yml +2382 -0
  82. data/spec/fixtures/cassettes/Admin_Transaction_Sync_Batches/user_has_a_shipped_order/starts_a_transaction_backfill.yml +370 -0
  83. data/spec/fixtures/cassettes/Reporting_orders_to_TaxJar/shipping_a_complete_and_paid_order.yml +310 -0
  84. data/spec/fixtures/cassettes/Reporting_orders_to_TaxJar/updating_an_order_which_was_not_reported_due_to_failure/it_reports_the_order_instead_of_trying_to_replace_it.yml +794 -0
  85. data/spec/fixtures/cassettes/Reporting_orders_to_TaxJar/with_an_order_with_invalid_zipcode/retry_of_a_previously_failed_transaction_sync.yml +418 -0
  86. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/creates_a_batch.yml +250 -0
  87. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/creates_a_log_in_the_batch_with_an_order.yml +250 -0
  88. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/user_supplies_a_start_date/creates_a_batch.yml +250 -0
  89. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/user_supplies_a_start_date/user_supplies_start_and_end_date/creates_a_batch.yml +250 -0
  90. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_CalculatorHelper/_taxable_address_/when_taxable_address_check_returns_true/with_US_address/when_the_address_is_not_within_a_nexus_region/1_3_2_2_2_1.yml +58 -0
  91. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_CalculatorHelper/_taxable_address_/when_taxable_address_check_returns_true/with_US_address/when_the_address_is_within_a_nexus_region/1_3_2_2_1_1.yml +58 -0
  92. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_Reporting/_refund_and_create_transaction/when_Taxjar_cannot_create_a_refund_transaction/doesn_t_create_a_new_transaction.yml +393 -0
  93. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_Reporting/_refund_and_create_transaction/when_Taxjar_cannot_create_a_refund_transaction/raises_an_error.yml +393 -0
  94. data/spec/fixtures/cassettes/Taxjar_API_Request/logging_is_disabled/doesn_t_call_the_logger.yml +158 -0
  95. data/spec/fixtures/cassettes/Taxjar_API_Request/logging_is_enabled/calls_the_logger.yml +158 -0
  96. data/spec/fixtures/cassettes/features/spree/admin/checkout.yml +238 -0
  97. data/spec/fixtures/cassettes/features/spree/admin/refund.yml +1162 -0
  98. data/spec/jobs/super_good/solidus_taxjar/backfill_transaction_sync_batch_job_spec.rb +117 -0
  99. data/spec/jobs/super_good/solidus_taxjar/replace_transaction_job_spec.rb +95 -0
  100. data/spec/jobs/super_good/solidus_taxjar/report_transaction_job_spec.rb +76 -0
  101. data/spec/models/super_good/solidus_taxjar/configuration_spec.rb +79 -0
  102. data/spec/models/super_good/solidus_taxjar/order_transaction_spec.rb +36 -0
  103. data/spec/models/super_good/solidus_taxjar/transaction_sync_batch_spec.rb +48 -0
  104. data/spec/requests/spree/admin/order_request_spec.rb +121 -0
  105. data/spec/requests/spree/admin/taxjar_settings_request_spec.rb +198 -0
  106. data/spec/requests/spree/admin/taxjar_transactions_request_spec.rb +62 -0
  107. data/spec/requests/spree/admin/transaction_sync_batches_request_spec.rb +82 -0
  108. data/spec/spec_helper.rb +47 -4
  109. data/spec/subscribers/super_good/solidus_taxjar/spree/reporting_subscriber_spec.rb +278 -0
  110. data/spec/super_good/solidus_taxjar/addresses_spec.rb +0 -14
  111. data/spec/super_good/solidus_taxjar/api_params_spec.rb +284 -80
  112. data/spec/super_good/solidus_taxjar/api_spec.rb +168 -28
  113. data/spec/super_good/solidus_taxjar/backfill_transactions_spec.rb +24 -0
  114. data/spec/super_good/solidus_taxjar/cached_api_spec.rb +58 -0
  115. data/spec/super_good/solidus_taxjar/calculator_helper_spec.rb +131 -0
  116. data/spec/super_good/solidus_taxjar/discount_calculator_spec.rb +19 -2
  117. data/spec/super_good/solidus_taxjar/reportable_spec.rb +194 -0
  118. data/spec/super_good/solidus_taxjar/reporting_spec.rb +243 -0
  119. data/spec/super_good/solidus_taxjar/tax_calculator_spec.rb +19 -19
  120. data/spec/super_good/solidus_taxjar/tax_rate_calculator_spec.rb +8 -3
  121. data/spec/super_good/solidus_taxjar/transaction_id_generator_spec.rb +77 -0
  122. data/spec/super_good/solidus_taxjar_spec.rb +99 -0
  123. data/spec/support/checkoutable_store_shared_context.rb +19 -0
  124. data/spec/support/solidus_events_helper.rb +26 -0
  125. data/spec/taxjar/api/request_spec.rb +52 -0
  126. data/super_good-solidus_taxjar.gemspec +4 -3
  127. metadata +176 -14
@@ -1,11 +1,15 @@
1
1
  require "spec_helper"
2
2
 
3
3
  RSpec.describe SuperGood::SolidusTaxjar::Api do
4
+ let(:api) { described_class.new(taxjar_client: dummy_client) }
5
+ let(:dummy_client) { instance_double ::Taxjar::Client }
6
+
4
7
  describe ".new" do
5
8
  subject { described_class.new }
6
9
 
7
10
  before do
8
- ENV["TAXJAR_API_KEY"] = 'taxjar_api_token'
11
+ allow(ENV).to receive(:fetch).and_call_original
12
+ allow(ENV).to receive(:fetch).with("TAXJAR_API_KEY").and_return("taxjar_api_token")
9
13
  end
10
14
 
11
15
  it "sets the correct headers" do
@@ -21,7 +25,8 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
21
25
  subject { described_class.default_taxjar_client }
22
26
 
23
27
  before do
24
- ENV["TAXJAR_API_KEY"] = 'taxjar_api_token'
28
+ allow(ENV).to receive(:fetch).and_call_original
29
+ allow(ENV).to receive(:fetch).with("TAXJAR_API_KEY").and_return("taxjar_api_token")
25
30
  end
26
31
 
27
32
  it "returns an instance of the TaxJar client" do
@@ -29,12 +34,26 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
29
34
  end
30
35
  end
31
36
 
37
+ describe "#tax_categories" do
38
+ subject { api.tax_categories }
39
+
40
+ let(:tax_categories) {
41
+ [
42
+ instance_double(Taxjar::Category, name: "Clothing"),
43
+ instance_double(Taxjar::Category, name: "Digital Goods")
44
+ ]
45
+ }
46
+
47
+ it "responds with a list of tax categories" do
48
+ allow(dummy_client).to receive(:categories).and_return(tax_categories)
49
+
50
+ expect(subject).to eq(tax_categories)
51
+ end
52
+ end
32
53
 
33
54
  describe "#tax_for" do
34
55
  subject { api.tax_for order }
35
56
 
36
- let(:api) { described_class.new(taxjar_client: dummy_client) }
37
- let(:dummy_client) { instance_double ::Taxjar::Client }
38
57
  let(:order) { Spree::Order.new }
39
58
 
40
59
  before do
@@ -55,8 +74,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
55
74
  describe "tax_rate_for" do
56
75
  subject { api.tax_rate_for address }
57
76
 
58
- let(:api) { described_class.new(taxjar_client: dummy_client) }
59
- let(:dummy_client) { instance_double ::Taxjar::Client }
60
77
  let(:address) { Spree::Address.new }
61
78
  let(:tax_rate) { 0.04 }
62
79
  let(:response) { double(rate: tax_rate) }
@@ -79,8 +96,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
79
96
  describe "#tax_rates_for" do
80
97
  subject { api.tax_rates_for address }
81
98
 
82
- let(:api) { described_class.new(taxjar_client: dummy_client) }
83
- let(:dummy_client) { instance_double ::Taxjar::Client }
84
99
  let(:address) { Spree::Address.new }
85
100
 
86
101
  before do
@@ -103,28 +118,47 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
103
118
 
104
119
  let(:api) { described_class.new(taxjar_client: dummy_client) }
105
120
  let(:dummy_client) { instance_double ::Taxjar::Client }
106
- let(:order) { Spree::Order.new }
121
+ let(:order) { create(:order_ready_to_ship, number: "R123") }
122
+
123
+ let(:dummy_response) do
124
+ instance_double(
125
+ ::Taxjar::Order,
126
+ transaction_id: "R123",
127
+ transaction_date: "2015-05-15T00:00:00Z"
128
+ )
129
+ end
107
130
 
108
- before do
109
- allow(SuperGood::SolidusTaxjar::ApiParams)
110
- .to receive(:transaction_params)
111
- .with(order)
112
- .and_return({transaction: "params"})
131
+ context "when the latest transaction ID is nil" do
132
+ before do
133
+ allow(SuperGood::SolidusTaxjar::ApiParams)
134
+ .to receive(:transaction_params)
135
+ .with(order, "R123")
136
+ .and_return({transaction: "params"})
113
137
 
114
- allow(dummy_client)
115
- .to receive(:create_order)
116
- .with({transaction: "params"})
117
- .and_return({some_kind_of: "response"})
138
+ allow(dummy_client)
139
+ .to receive(:create_order)
140
+ .with({transaction: "params"})
141
+ .and_return(dummy_response)
142
+ end
143
+
144
+ it { is_expected.to eq(dummy_response) }
118
145
  end
119
146
 
120
- it { is_expected.to eq({some_kind_of: "response"}) }
147
+ context "when the API call to create the transaction fails" do
148
+ before do
149
+ allow(dummy_client).to receive(:create_order).and_raise(Taxjar::Error)
150
+ end
151
+
152
+ it "does not create an `OrderTransaction` for the order" do
153
+ expect { subject }.to raise_error(Taxjar::Error)
154
+ expect(order.taxjar_order_transactions.count).to be_zero
155
+ end
156
+ end
121
157
  end
122
158
 
123
159
  describe "#update_transaction_for" do
124
160
  subject { api.update_transaction_for order }
125
161
 
126
- let(:api) { described_class.new(taxjar_client: dummy_client) }
127
- let(:dummy_client) { instance_double ::Taxjar::Client }
128
162
  let(:order) { Spree::Order.new }
129
163
 
130
164
  before do
@@ -142,11 +176,9 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
142
176
  it { is_expected.to eq({some_kind_of: "response"}) }
143
177
  end
144
178
 
145
- describe "#update_transaction_for" do
179
+ describe "#delete_transaction_for" do
146
180
  subject { api.delete_transaction_for order }
147
181
 
148
- let(:api) { described_class.new(taxjar_client: dummy_client) }
149
- let(:dummy_client) { instance_double ::Taxjar::Client }
150
182
  let(:order) { Spree::Order.new(number: "R111222333") }
151
183
 
152
184
  before do
@@ -159,11 +191,49 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
159
191
  it { is_expected.to eq({some_kind_of: "response"}) }
160
192
  end
161
193
 
194
+ describe "#show_latest_transaction_for" do
195
+ subject { api.show_latest_transaction_for order }
196
+
197
+ let(:order) { Spree::Order.new(number: "R111222333") }
198
+
199
+ context "with a persisted order transaction" do
200
+ before do
201
+ create(
202
+ :taxjar_order_transaction,
203
+ order: order,
204
+ transaction_id: "R111222333-42"
205
+ )
206
+ end
207
+
208
+ let(:order) { create(:order, number: "R111222333") }
209
+
210
+ it "uses the persisted transaction_id to fetch the TaxJar transaction" do
211
+ expect(dummy_client)
212
+ .to receive(:show_order)
213
+ .with("R111222333-42")
214
+ .and_return({some_kind_of: "response"})
215
+ expect(subject).to eq({some_kind_of: "response"})
216
+ end
217
+
218
+ context "TaxJar does not have an order transaction persisted" do
219
+ before do
220
+ allow(dummy_client)
221
+ .to receive(:show_order)
222
+ .and_raise(Taxjar::Error::NotFound)
223
+ end
224
+
225
+ it { is_expected.to eq nil }
226
+ end
227
+ end
228
+
229
+ context "without a persisted order transaction" do
230
+ it { is_expected.to eq nil }
231
+ end
232
+ end
233
+
162
234
  describe "#create_refund_for" do
163
235
  subject { api.create_refund_for reimbursement }
164
236
 
165
- let(:api) { described_class.new(taxjar_client: dummy_client) }
166
- let(:dummy_client) { instance_double ::Taxjar::Client }
167
237
  let(:reimbursement) { Spree::Reimbursement.new }
168
238
 
169
239
  before do
@@ -181,11 +251,69 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
181
251
  it { is_expected.to eq({some_kind_of: "response"}) }
182
252
  end
183
253
 
254
+ describe "#create_refund_transaction_for" do
255
+ subject { api.create_refund_transaction_for order }
256
+
257
+ let(:order) { create(:order_ready_to_ship, number: "R111222333") }
258
+
259
+ let(:taxjar_order) {
260
+ Taxjar::Order.new(
261
+ amount: 20,
262
+ sales_tax: 2,
263
+ shipping: 5
264
+ )
265
+ }
266
+
267
+ before do
268
+ allow(dummy_client)
269
+ .to receive(:show_order)
270
+ .with("R111222333-10")
271
+ .and_return(taxjar_order)
272
+
273
+ allow(SuperGood::SolidusTaxjar::ApiParams)
274
+ .to receive(:refund_transaction_params)
275
+ .with(order, taxjar_order)
276
+ .and_return({refund_transaction: "params"})
277
+
278
+ allow(dummy_client)
279
+ .to receive(:create_refund)
280
+ .with({refund_transaction: "params"})
281
+ .and_return({some_kind_of: "response"})
282
+ end
283
+
284
+ context "when no order transaction has been persisted" do
285
+ it "raises an exception" do
286
+ expect { subject }.to raise_error(
287
+ NotImplementedError,
288
+ "No latest TaxJar order transaction for #{order.number}. " \
289
+ "Backfilling TaxJar transaction orders from Solidus is not yet " \
290
+ "implemented."
291
+ )
292
+ end
293
+ end
294
+
295
+ context "when an order transaction has been persisted" do
296
+ before do
297
+ create(
298
+ :taxjar_order_transaction,
299
+ order: order,
300
+ transaction_id: "R111222333-10"
301
+ )
302
+ end
303
+
304
+ it "requests the latest transaction from TaxJar" do
305
+ expect(dummy_client).to receive(:show_order).with("R111222333-10")
306
+
307
+ subject
308
+ end
309
+
310
+ it { is_expected.to eq({some_kind_of: "response"}) }
311
+ end
312
+ end
313
+
184
314
  describe "#validate_spree_address" do
185
315
  subject { api.validate_spree_address spree_address }
186
316
 
187
- let(:api) { described_class.new(taxjar_client: dummy_client) }
188
- let(:dummy_client) { instance_double ::Taxjar::Client }
189
317
  let(:spree_address) { build :address }
190
318
 
191
319
  before do
@@ -202,4 +330,16 @@ RSpec.describe SuperGood::SolidusTaxjar::Api do
202
330
 
203
331
  it { is_expected.to eq({some_kind_of: "response"}) }
204
332
  end
333
+
334
+ describe "#nexus_regions" do
335
+ subject { api.nexus_regions }
336
+
337
+ before do
338
+ allow(dummy_client)
339
+ .to receive(:nexus_regions)
340
+ .and_return({some_kind_of: "response"})
341
+ end
342
+
343
+ it { is_expected.to eq({some_kind_of: "response"}) }
344
+ end
205
345
  end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe SuperGood::SolidusTaxjar::BackfillTransactions do
4
+ describe "#call" do
5
+ subject { described_class.new.call(start_date: start_date.to_s, end_date: end_date.to_s) }
6
+
7
+ let(:start_date) { 1.day.ago.to_date }
8
+ let(:end_date) { Date.today }
9
+
10
+ it "returns a new transaction sync batch" do
11
+ expect(subject).to be_a(SuperGood::SolidusTaxjar::TransactionSyncBatch)
12
+ end
13
+
14
+ it "has the start and end date" do
15
+ expect(subject).to have_attributes({start_date: start_date, end_date: end_date})
16
+ end
17
+
18
+ it "queues a job to backfill the transactions in the batch" do
19
+ expect { subject }
20
+ .to have_enqueued_job(SuperGood::SolidusTaxjar::BackfillTransactionSyncBatchJob)
21
+ .with(kind_of(SuperGood::SolidusTaxjar::TransactionSyncBatch))
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe SuperGood::SolidusTaxjar::CachedApi do
4
+ describe ".nexus_regions" do
5
+ subject { instance.nexus_regions }
6
+
7
+ let(:instance) { described_class.new(api: dummy_api) }
8
+
9
+ let(:dummy_api) do
10
+ instance_double(SuperGood::SolidusTaxjar::Api)
11
+ end
12
+
13
+ let(:nexus_region) { ::Taxjar::NexusRegion.new(region: "California") }
14
+
15
+ before do
16
+ allow(dummy_api).to receive(:nexus_regions).and_return(
17
+ [nexus_region]
18
+ )
19
+ end
20
+
21
+ it "makes a request to the TaxJar API" do
22
+ subject
23
+ expect(dummy_api).to have_received(:nexus_regions)
24
+ end
25
+
26
+ it "returns a list of nexus regions" do
27
+ expect(subject).to contain_exactly(nexus_region)
28
+ end
29
+
30
+ context "when nexus regions cached" do
31
+ before do
32
+ Rails.cache.write(:nexus_regions, [nexus_region])
33
+ end
34
+
35
+ it "doesn't make a request to the TaxJar API" do
36
+ subject
37
+ expect(dummy_api).to_not have_received(:nexus_regions)
38
+ end
39
+
40
+ it "returns a list of nexus regions" do
41
+ expect(subject).to contain_exactly(nexus_region)
42
+ end
43
+
44
+ context "with refresh true" do
45
+ subject { instance.nexus_regions(refresh: true) }
46
+
47
+ it "makes a request to the TaxJar API" do
48
+ subject
49
+ expect(dummy_api).to have_received(:nexus_regions)
50
+ end
51
+
52
+ it "returns a list of nexus regions" do
53
+ expect(subject).to contain_exactly(nexus_region)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,131 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe SuperGood::SolidusTaxjar::CalculatorHelper do
4
+ class TestProxy
5
+ extend SuperGood::SolidusTaxjar::CalculatorHelper
6
+ end
7
+
8
+ describe "#incomplete_address?" do
9
+ subject { TestProxy.incomplete_address?(address) }
10
+
11
+ context "with a missing city" do
12
+ let(:address) { build :address, city: nil }
13
+ it { is_expected.to eq(true) }
14
+ end
15
+
16
+ context "with a missing address1" do
17
+ let(:address) { build :address, address1: nil }
18
+ it { is_expected.to eq(true) }
19
+ end
20
+
21
+ context "with a missing zipcode" do
22
+ let(:address) { build :address, zipcode: nil }
23
+ it { is_expected.to eq(true) }
24
+ end
25
+
26
+ context "with a missing state in CA" do
27
+ let(:address) { build :address, country_iso_code: "CA" }
28
+
29
+ before { address.state = nil }
30
+
31
+ it { is_expected.to eq(true) }
32
+ end
33
+
34
+ context "with a missing state in US" do
35
+ let(:address) { build :address, country_iso_code: "US" }
36
+
37
+ before { address.state = nil }
38
+
39
+ it { is_expected.to eq(true) }
40
+ end
41
+
42
+ context "with a missing state in DE" do
43
+ let(:address) { build :address, country_iso_code: "DE", state: nil }
44
+ it { is_expected.to eq(false) }
45
+ end
46
+ end
47
+
48
+ describe "#state_required?" do
49
+ subject { TestProxy.state_required?(country) }
50
+
51
+ context "when the address' country is Canada" do
52
+ let(:country) { Spree::Country.new(iso: "CA") }
53
+ it { is_expected.to eq(true) }
54
+ end
55
+
56
+ context "when the address' country is the USA" do
57
+ let(:country) { Spree::Country.new(iso: "US") }
58
+ it { is_expected.to eq(true) }
59
+ end
60
+
61
+ context "when the address' country is neither Canada nor the USA" do
62
+ let(:country) { Spree::Country.new(iso: "FR") }
63
+ it { is_expected.to eq(false) }
64
+ end
65
+ end
66
+
67
+ describe "#taxable_address?" do
68
+ subject { TestProxy.taxable_address?(address) }
69
+
70
+ let(:configuration_class) { double }
71
+
72
+ before do
73
+ allow(SuperGood::SolidusTaxjar)
74
+ .to receive(:taxable_address_check)
75
+ .and_return(configuration_class)
76
+ allow(configuration_class).to receive(:call)
77
+ .and_return(taxable_address)
78
+ end
79
+
80
+ context "when taxable address check returns false" do
81
+ let(:taxable_address) { false }
82
+ let(:address) do
83
+ create :address, name: "Canada", country_iso_code: "CA"
84
+ end
85
+
86
+ it { is_expected.to be_falsey }
87
+ end
88
+
89
+ context "when taxable address check returns true" do
90
+ let(:taxable_address) { true }
91
+
92
+ context "with non-US address" do
93
+ let(:address) do
94
+ create :address, name: "Canada", country_iso_code: "CA"
95
+ end
96
+
97
+ it { is_expected.to be_truthy }
98
+ end
99
+
100
+ context "with US address", :vcr do
101
+ let(:usa) { create :country, iso: "US", name: "United States" }
102
+
103
+ # This test expects a TaxJar account to have nexus in California.
104
+ #
105
+ context "when the address is within a nexus region" do
106
+ let(:address) {
107
+ create :address,
108
+ state: create(:state, abbr: "CA", country: usa, name: "Cali!"),
109
+ country: usa,
110
+ zipcode: "94704"
111
+ }
112
+
113
+ it { is_expected.to eq true }
114
+ end
115
+
116
+ # This test expects a TaxJar account to *not* have nexus in Alabama.
117
+ #
118
+ context "when the address is not within a nexus region" do
119
+ let(:address) {
120
+ create :address,
121
+ state: create(:state, abbr: "AL", country: usa, name: "Alabama"),
122
+ country: usa,
123
+ zipcode: "35006"
124
+ }
125
+
126
+ it { is_expected.to eq false }
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -5,9 +5,26 @@ RSpec.describe SuperGood::SolidusTaxjar::DiscountCalculator do
5
5
  subject { calculator.discount }
6
6
 
7
7
  let(:calculator) { described_class.new line_item }
8
+ let(:line_item) { create :line_item }
9
+ let!(:order) { create :completed_order_with_promotion, promotion: promotion_with_adjustment, line_items: [line_item] }
8
10
 
9
- let(:line_item) { ::Spree::LineItem.new(promo_total: 12.34) }
11
+ let(:cancelation_adjustment_amount) { -8 }
12
+ let(:promotion_adjustment_amount) { -2 }
13
+ let(:promotion_with_adjustment) { create :promotion_with_item_adjustment, adjustment_rate: promotion_adjustment_amount }
14
+ let!(:unit_cancellation_adjustment) { create :adjustment, order: order, adjustable: line_item, amount: cancelation_adjustment_amount, source_type: "Spree::UnitCancel" }
10
15
 
11
- it { is_expected.to eq(-12.34) }
16
+ let!(:tax_adjustment) { create :tax_adjustment, order: order, adjustable: line_item, amount: 2.50 }
17
+
18
+ it "sums the total of all non-tax adjustments" do
19
+ expect(subject).to eq(-1 * (cancelation_adjustment_amount + promotion_adjustment_amount))
20
+ end
21
+
22
+ context "a non-eligible adjustment exists" do
23
+ let!(:unit_cancellation_adjustment) { create :adjustment, order: order, adjustable: line_item, eligible: false, amount: cancelation_adjustment_amount, source_type: "Spree::UnitCancel" }
24
+
25
+ it "only sums eligible adjustments" do
26
+ expect(subject).to eq(-1 * promotion_adjustment_amount)
27
+ end
28
+ end
12
29
  end
13
30
  end