solidus_avatax_certified 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.env_example +4 -0
  3. data/.gitignore +16 -0
  4. data/.rspec +3 -0
  5. data/.ruby-version +1 -0
  6. data/GEM_VERSION +1 -0
  7. data/Gemfile +18 -0
  8. data/LICENSE +26 -0
  9. data/README.md +27 -0
  10. data/Rakefile +21 -0
  11. data/app/assets/javascripts/spree/backend/address_validator.js +84 -0
  12. data/app/assets/javascripts/spree/backend/solidus_avatax_certified.js +5 -0
  13. data/app/assets/javascripts/spree/backend/use_code_picker.js +51 -0
  14. data/app/assets/javascripts/spree/frontend/address_validator.js +87 -0
  15. data/app/assets/javascripts/spree/frontend/flash.js.coffee +26 -0
  16. data/app/assets/javascripts/spree/frontend/solidus_avatax_certified.js +4 -0
  17. data/app/assets/stylesheets/spree/backend/solidus_avatax_certified.css +4 -0
  18. data/app/assets/stylesheets/spree/frontend/solidus_avatax_certified.css +4 -0
  19. data/app/controllers/spree/admin/avalara_entity_use_codes_controller.rb +15 -0
  20. data/app/controllers/spree/admin/avatax_settings_controller.rb +82 -0
  21. data/app/controllers/spree/admin/users_controller_decorator.rb +11 -0
  22. data/app/controllers/spree/checkout_controller_decorator.rb +22 -0
  23. data/app/models/solidus_avatax_certified/address.rb +95 -0
  24. data/app/models/solidus_avatax_certified/avatax_log.rb +69 -0
  25. data/app/models/solidus_avatax_certified/line.rb +146 -0
  26. data/app/models/solidus_avatax_certified/preference_updater.rb +74 -0
  27. data/app/models/spree/address_decorator.rb +13 -0
  28. data/app/models/spree/adjustment_decorator.rb +10 -0
  29. data/app/models/spree/avalara_entity_use_code.rb +5 -0
  30. data/app/models/spree/avalara_preference.rb +72 -0
  31. data/app/models/spree/avalara_transaction.rb +181 -0
  32. data/app/models/spree/calculator/avalara_transaction.rb +86 -0
  33. data/app/models/spree/line_item_decorator.rb +25 -0
  34. data/app/models/spree/order_decorator.rb +85 -0
  35. data/app/models/spree/payment_decorator.rb +23 -0
  36. data/app/models/spree/refund_decorator.rb +30 -0
  37. data/app/models/spree/shipment_decorator.rb +28 -0
  38. data/app/models/spree/shipping_rate_decorator.rb +25 -0
  39. data/app/models/spree/user_decorator.rb +3 -0
  40. data/app/models/tax_svc.rb +143 -0
  41. data/app/overrides/spree/admin/shared/_configuration_menu.rb +10 -0
  42. data/app/overrides/spree/admin/users/sidebar.rb +8 -0
  43. data/app/overrides/spree/admin/users/validation_button.rb +6 -0
  44. data/app/views/spree/admin/avalara_entity_use_codes/_form.html.erb +27 -0
  45. data/app/views/spree/admin/avalara_entity_use_codes/edit.html.erb +16 -0
  46. data/app/views/spree/admin/avalara_entity_use_codes/index.html.erb +33 -0
  47. data/app/views/spree/admin/avalara_entity_use_codes/new.html.erb +17 -0
  48. data/app/views/spree/admin/avalara_entity_use_codes/show.html.erb +24 -0
  49. data/app/views/spree/admin/avatax_settings/edit.html.erb +183 -0
  50. data/app/views/spree/admin/avatax_settings/ping_my_service.js.erb +8 -0
  51. data/app/views/spree/admin/avatax_settings/show.html.erb +124 -0
  52. data/app/views/spree/admin/avatax_settings/validate_address.js.erb +8 -0
  53. data/app/views/spree/admin/users/avalara_information.html.erb +53 -0
  54. data/app/views/spree/checkout/_address.html.erb +35 -0
  55. data/app/views/spree/checkout/_address_validator_button.html.erb +3 -0
  56. data/bin/rails +7 -0
  57. data/circle.yml +17 -0
  58. data/config/initializers/avatax.rb +5 -0
  59. data/config/initializers/spree.rb +3 -0
  60. data/config/locales/en.yml +35 -0
  61. data/config/routes.rb +18 -0
  62. data/db/migrate/20160624154205_create_spree_avalara_transactions.rb +9 -0
  63. data/db/migrate/20160624154423_create_spree_avalara_entity_use_codes.rb +9 -0
  64. data/db/migrate/20160624155217_add_columns_to_spree_users.rb +6 -0
  65. data/db/migrate/20160628200504_create_spree_avalara_preferences.rb +10 -0
  66. data/db/migrate/20160805193512_add_vat_id_to_spree_users.rb +5 -0
  67. data/db/seeds.rb +1 -0
  68. data/lib/generators/solidus_avatax_certified/install/install_generator.rb +45 -0
  69. data/lib/solidus_avatax_certified/engine.rb +22 -0
  70. data/lib/solidus_avatax_certified/preference_seeder.rb +69 -0
  71. data/lib/solidus_avatax_certified/seeder.rb +117 -0
  72. data/lib/solidus_avatax_certified.rb +2 -0
  73. data/lib/tasks/load_seeds.rake +15 -0
  74. data/setup.md +12 -0
  75. data/solidus_avatax_certified.gemspec +42 -0
  76. data/spec/controllers/spree/admin/avalara_entity_use_codes_controller_spec.rb +53 -0
  77. data/spec/controllers/spree/admin/avatax_settings_controller_spec.rb +67 -0
  78. data/spec/factories/avalara_entity_use_code_factory.rb +6 -0
  79. data/spec/factories/avalara_factories.rb +76 -0
  80. data/spec/factories/avalara_order_factory.rb +62 -0
  81. data/spec/factories/avalara_preference_factory.rb +7 -0
  82. data/spec/factories/avalara_shipment_factory.rb +27 -0
  83. data/spec/factories/avalara_shipping_method_factory.rb +23 -0
  84. data/spec/factories/tax_rate_factory.rb +19 -0
  85. data/spec/features/certification_spec.rb +77 -0
  86. data/spec/features/checkout_spec.rb +156 -0
  87. data/spec/features/vat_spec.rb +153 -0
  88. data/spec/models/solidus_avatax_certified/address_spec.rb +80 -0
  89. data/spec/models/solidus_avatax_certified/avatax_log_spec.rb +97 -0
  90. data/spec/models/solidus_avatax_certified/line_spec.rb +100 -0
  91. data/spec/models/spree/address_decorator_spec.rb +44 -0
  92. data/spec/models/spree/adjustment_decorator_spec.rb +25 -0
  93. data/spec/models/spree/avalara_entity_use_code_spec.rb +5 -0
  94. data/spec/models/spree/avalara_preference_spec.rb +173 -0
  95. data/spec/models/spree/avalara_transaction_spec.rb +203 -0
  96. data/spec/models/spree/calculator/avalara_transaction_spec.rb +129 -0
  97. data/spec/models/spree/line_item_decorator_spec.rb +33 -0
  98. data/spec/models/spree/order_decorator_spec.rb +164 -0
  99. data/spec/models/spree/payment_decorator_spec.rb +117 -0
  100. data/spec/models/spree/refund_decorator_spec.rb +81 -0
  101. data/spec/models/spree/shipment_decorator_spec.rb +36 -0
  102. data/spec/models/spree/shipping_rate_decorator_spec.rb +17 -0
  103. data/spec/models/spree/user_decorator_spec.rb +5 -0
  104. data/spec/spec_helper.rb +81 -0
  105. data/spec/support/avatax_config_preferences.rb +8 -0
  106. data/spec/support/vcr.rb +9 -0
  107. data/spec/vcr/Certification/Exempt_sales_should_be_reflected_in_the_test_data_through_use_of_ExemptionNo_or_CustomerUsageType_/does_not_add_additional_tax.yml +276 -0
  108. data/spec/vcr/Certification/Transactions_have_been_committed_/commits_an_order.yml +336 -0
  109. data/spec/vcr/Certification/Transactions_have_been_voided/cancelled_/should_be_successful/returns_ResultCode_with_value_Success.yml +522 -0
  110. data/spec/vcr/Certification/return_orders/_commit_avatax_final/should_commit_avatax_final.yml +404 -0
  111. data/spec/vcr/Checkout/complete_order/has_tax_and_shipping_tax_adjustments_on_page.yml +72 -0
  112. data/spec/vcr/Checkout/complete_order/order_line_items_and_shipments_have_an_additional_tax_total_sum_of_0_40.yml +72 -0
  113. data/spec/vcr/Checkout/payment/tax_included/has_tax_and_shipping_tax_adjustments_on_page.yml +72 -0
  114. data/spec/vcr/Checkout/payment/tax_included/order_line_items_and_shipments_have_an_included_tax_total_sum_of_0_38.yml +72 -0
  115. data/spec/vcr/Checkout/payment/tax_not_included/on_payment_page/has_tax_and_shipping_tax_adjustments_on_page.yml +72 -0
  116. data/spec/vcr/Checkout/payment/tax_not_included/on_payment_page/order_line_items_and_shipments_and_shipments_have_an_additional_tax_total_sum_of_0_40.yml +72 -0
  117. data/spec/vcr/Checkout/payment/with_promotion/tax_not_included/has_adjusted_tax_amount_after_promotion_applied.yml +73 -0
  118. data/spec/vcr/SolidusAvataxCertified_Address/_validate/fails_when_information_is_incorrect.yml +54 -0
  119. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_included_in_price/should_be_equal_to_the_item_pre-tax_total_rate.yml +137 -0
  120. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_included_in_price/should_be_equal_to_the_previous_included_tax_total_is_order_is_at_address.yml +138 -0
  121. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_included_in_price/should_be_equal_to_the_previous_included_tax_total_is_order_is_at_cart.yml +137 -0
  122. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_item_pre-tax_total_rate.yml +136 -0
  123. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_previous_additional_tax_total_if_order_is_at_address.yml +137 -0
  124. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_previous_additional_tax_total_if_order_is_at_cart.yml +136 -0
  125. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/should_be_equal_to_the_previous_tax_total_if_preference_tax_calculation_is_false.yml +136 -0
  126. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/when_the_line_item_is_discounted/should_be_equal_to_the_items_pre-tax_total_rate.yml +276 -0
  127. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_computing_a_line_item/when_tax_is_not_included_in_price/when_the_order_is_discounted/should_be_equal_to_the_items_pre-tax_total_rate.yml +206 -0
  128. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_a_shipment/computing_normal_shipment/should_be_equal_4_0.yml +141 -0
  129. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_a_shipment/when_tax_is_included_in_price/should_be_equal_to_3_85.yml +143 -0
  130. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_a_shipment/with_promotion/should_equal_3_96.yml +210 -0
  131. data/spec/vcr/Spree_Calculator_AvalaraTransaction/_compute/when_given_an_order/when_computing_an_order/should_raise_error.yml +136 -0
  132. data/spec/vcr/Spree_Order/_cancel_avalara/should_receive_cancel_order_when_cancel_avalara_is_called.yml +136 -0
  133. data/spec/vcr/Spree_Order/_cancel_avalara/state_machine_event_cancel/should_recieve_cancel_avalara_when_event_cancel_is_called.yml +259 -0
  134. data/spec/vcr/Spree_Order/_validate_ship_address/should_return_false_if_validation_failed.yml +54 -0
  135. data/spec/vcr/Spree_Order/_validate_ship_address/should_return_the_response_if_refuse_checkout_on_address_validation_is_disabled.yml +59 -0
  136. data/spec/vcr/Spree_Order/_validate_ship_address/should_return_the_response_if_validation_is_success.yml +59 -0
  137. data/spec/vcr/Spree_Payment/_avalara_finalize/should_update_the_amount_to_be_the_order_total.yml +136 -0
  138. data/spec/vcr/Spree_Payment/_cancel_avalara/committed_order/should_be_successful/ResultCode_returns_Success.yml +205 -0
  139. data/spec/vcr/Spree_Payment/_cancel_avalara/uncommitted_order/should_fail/ResultCode_returns_Error.yml +191 -0
  140. data/spec/vcr/Spree_Payment/_purchase_/receive_avalara_finalize.yml +136 -0
  141. data/spec/vcr/Spree_Payment/_void_transaction_/receive_cancel_avalara.yml +136 -0
  142. data/spec/vcr/Spree_Refund/full_refund/returns_correct_tax_calculations.yml +270 -0
  143. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_does_not_have_Nexus_Jurisdition_Registered/TotalTax_is_equal_to_order_included_tax_total.yml +137 -0
  144. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_does_not_have_Nexus_Jurisdition_Registered/origin_country_tax_is_returned.yml +138 -0
  145. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_does_not_have_Nexus_Jurisdition_Registered/with_BusinessIdentificationNo/origin_country_zero_rate_is_returned.yml +143 -0
  146. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_has_Nexus_Jurisdition_Registered/TotalTax_is_equal_to_order_included_tax_total.yml +139 -0
  147. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_has_Nexus_Jurisdition_Registered/destination_country_tax_is_returned.yml +139 -0
  148. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_another_EU_country/Seller_has_Nexus_Jurisdition_Registered/with_BusinessIdentificationNo/origin_country_zero_rate_is_returned.yml +144 -0
  149. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_same_EU_country/TotalTax_is_equal_to_order_included_tax_total.yml +137 -0
  150. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_in_same_EU_country/tax_detail_country_equals_to_IT.yml +138 -0
  151. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/TotalTax_is_equal_to_order_included_tax_total.yml +137 -0
  152. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/tax_detail_country_equals_to_IT.yml +137 -0
  153. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/total_tax_is_0_since_utah_is_not_in_jurisdiction.yml +137 -0
  154. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_does_not_have_Nexus_Jurisdition_registered/with_BusinessIdentificationNo/origin_country_zero_rate_is_returned.yml +138 -0
  155. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_has_Nexus_Jurisdiction_Registered/TotalTax_is_equal_to_order_included_tax_total.yml +195 -0
  156. data/spec/vcr/VAT/Seller_in_EU_country_Buyer_is_outside_EU/Seller_has_Nexus_Jurisdiction_Registered/tax_detail_region_equals_to_AL.yml +195 -0
  157. data/spec/vcr/address_validation_success.yml +59 -0
  158. data/spec/vcr/capture_with_customer_usage_type.yml +72 -0
  159. data/spec/vcr/order_cancel.yml +258 -0
  160. data/spec/vcr/order_capture.yml +72 -0
  161. data/spec/vcr/order_capture_finalize.yml +141 -0
  162. data/spec/vcr/order_capture_with_promo.yml +73 -0
  163. data/spec/vcr/order_return_capture.yml +68 -0
  164. data/spec/vcr/tax_included_order.yml +73 -0
  165. metadata +581 -0
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order, :vcr do
4
+
5
+ it { should have_one :avalara_transaction }
6
+ let(:order) { build(:avalara_order, ship_address: build(:address)) }
7
+ let(:avalara_order) { create(:avalara_order) }
8
+ let(:completed_order) { create(:completed_avalara_order) }
9
+
10
+ describe "#avalara_tax_enabled?" do
11
+ it "should return true" do
12
+ expect(Spree::Order.new.avalara_tax_enabled?).to eq(true)
13
+ end
14
+ end
15
+
16
+ describe '#cancel_avalara' do
17
+ subject do
18
+ VCR.use_cassette("order_cancel") do
19
+ avalara_order.avalara_capture_finalize
20
+ avalara_order.cancel_avalara
21
+ end
22
+ end
23
+
24
+ it 'return a hash with a ResultCode of Success' do
25
+ expect(subject["ResultCode"]).to eq("Success")
26
+ expect(subject).to be_kind_of(Hash)
27
+ end
28
+
29
+ it 'should receive cancel_order when cancel_avalara is called' do
30
+ expect(avalara_order.avalara_transaction).to receive(:cancel_order)
31
+ subject
32
+ end
33
+
34
+ context 'state machine event cancel' do
35
+ it 'should recieve cancel_avalara when event cancel is called' do
36
+ expect(completed_order).to receive(:cancel_avalara)
37
+ completed_order.cancel!
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#avalara_capture" do
43
+ subject do
44
+ VCR.use_cassette("order_capture", allow_playback_repeats: true) do
45
+ avalara_order.avalara_capture
46
+ end
47
+ end
48
+
49
+ it "should response with Hash object" do
50
+ expect(subject).to be_kind_of(Hash)
51
+ end
52
+ it "creates new avalara_transaction" do
53
+ expect{subject}.to change{Spree::AvalaraTransaction.count}.by(1)
54
+ end
55
+ it 'should have a ResultCode of success' do
56
+ expect(subject['ResultCode']).to eq('Success')
57
+ end
58
+ end
59
+
60
+ describe "#avalara_capture_finalize" do
61
+
62
+ subject do
63
+ VCR.use_cassette("order_capture_finalize", allow_playback_repeats: true) do
64
+ avalara_order.avalara_capture_finalize
65
+ end
66
+ end
67
+
68
+ it "should response with Hash object" do
69
+ expect(subject).to be_kind_of(Hash)
70
+ end
71
+
72
+ it 'should have a ResultCode of success' do
73
+ expect(subject['ResultCode']).to eq('Success')
74
+ end
75
+
76
+ # Spec fails when using VCR since dates are involved.
77
+
78
+ # context 'commit on completed at date' do
79
+ # before do
80
+ # completed_order.update_attributes(completed_at: 5.days.ago)
81
+ # end
82
+
83
+ # it 'has a docdate of completed at date' do
84
+ # response = completed_order.avalara_capture_finalize
85
+ # expect(response['DocDate']).to eq(5.days.ago.strftime('%F'))
86
+ # end
87
+ # end
88
+ end
89
+
90
+ describe '#avatax_cache_key' do
91
+ it 'should respond with a cache key' do
92
+ expected_response = "Spree::Order-#{order.number}-#{order.promo_total}"
93
+
94
+ expect(order.avatax_cache_key).to eq(expected_response)
95
+ end
96
+ end
97
+
98
+ describe '#customer_usage_type' do
99
+ let(:use_code) { build(:avalara_entity_use_code) }
100
+
101
+ before do
102
+ order.user.update_attributes(avalara_entity_use_code: use_code)
103
+ end
104
+
105
+ it 'should respond with user usage type' do
106
+ expect(order.customer_usage_type).to eq('A')
107
+ end
108
+ it 'should respond with blank string if no user' do
109
+ order.update_attributes(user: nil)
110
+ expect(order.customer_usage_type).to eq('')
111
+ end
112
+ end
113
+
114
+ describe '#validate_ship_address' do
115
+ it 'should return the response if validation is success' do
116
+ Spree::AvalaraPreference.address_validation.update_attributes(value: 'true')
117
+ response = order.validate_ship_address
118
+
119
+ expect(response['ResultCode']).to eq('Success')
120
+ end
121
+
122
+ it 'should return the response if refuse checkout on address validation is disabled' do
123
+ Spree::AvalaraPreference.refuse_checkout_address_validation_error.update_attributes(value: 'false')
124
+ response = order.validate_ship_address
125
+
126
+ expect(response['ResultCode']).to eq('Success')
127
+ end
128
+
129
+ it 'should return false if validation failed' do
130
+ Spree::AvalaraPreference.refuse_checkout_address_validation_error.update_attributes(value: 'true')
131
+ order.ship_address.update_attributes(zipcode: nil, city: nil, address1: nil)
132
+ response = order.validate_ship_address
133
+
134
+ expect(response).to eq(false)
135
+ end
136
+ end
137
+
138
+ describe '#address_validation_enabled?' do
139
+ it 'should return false if ship address is nil' do
140
+ order.ship_address = nil
141
+
142
+ expect(order.address_validation_enabled?).to be_falsey
143
+ end
144
+
145
+ it 'returns true if preference is true and country validation is enabled' do
146
+ Spree::AvalaraPreference.address_validation.update_attributes(value: 'true')
147
+ Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'United States,Canada')
148
+
149
+ expect(order.address_validation_enabled?).to be_truthy
150
+ end
151
+
152
+ it 'returns false if address validation preference is false' do
153
+ Spree::AvalaraPreference.address_validation.update_attributes(value: 'false')
154
+
155
+ expect(order.address_validation_enabled?).to be_falsey
156
+ end
157
+
158
+ it 'returns false if enabled country is not present' do
159
+ Spree::AvalaraPreference.validation_enabled_countries.update_attributes(value: 'Canada')
160
+
161
+ expect(order.address_validation_enabled?).to be_falsey
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Payment, :vcr do
4
+ let(:order) { create(:avalara_order) }
5
+
6
+ let(:gateway) do
7
+ gateway = Spree::Gateway::Bogus.new( :active => true, :name => 'Bogus gateway')
8
+ allow(gateway).to receive_messages :environment => 'test'
9
+ allow(gateway).to receive_messages :source_required => true
10
+ gateway
11
+ end
12
+
13
+ let(:card) do
14
+ Spree::CreditCard.create!(
15
+ number: '4111111111111111',
16
+ month: '12',
17
+ year: Time.now.year + 1,
18
+ verification_value: '123',
19
+ name: 'Name',
20
+ imported: false
21
+ )
22
+ end
23
+
24
+ let(:payment) do
25
+ payment = Spree::Payment.new
26
+ payment.source = card
27
+ payment.order = order
28
+ payment.payment_method = gateway
29
+ payment.amount = order.total
30
+ payment
31
+ end
32
+
33
+ let(:amount_in_cents) { (payment.amount * 100).round }
34
+
35
+ let!(:success_response) do
36
+ double('success_response', :success? => true,
37
+ :authorization => '123',
38
+ :avs_result => { 'code' => 'avs-code' },
39
+ :cvv_result => { 'code' => 'cvv-code', 'message' => 'CVV Result'})
40
+ end
41
+
42
+ let(:failed_response) { double('gateway_response', :success? => false) }
43
+
44
+ before(:each) do
45
+ allow(payment.log_entries).to receive(:create!)
46
+ end
47
+
48
+
49
+ describe '#purchase!' do
50
+ subject do
51
+ VCR.use_cassette("order_capture_finalize") do
52
+ order.avalara_capture_finalize
53
+ payment.purchase!
54
+ end
55
+ end
56
+
57
+ it 'receive avalara_finalize' do
58
+ expect(payment).to receive(:avalara_finalize)
59
+ subject
60
+ end
61
+ end
62
+
63
+ describe '#avalara_finalize' do
64
+ subject do
65
+ VCR.use_cassette("order_capture_finalize") do
66
+ order.avalara_capture_finalize
67
+ payment.avalara_finalize
68
+ end
69
+ end
70
+
71
+ it 'should update the amount to be the order total' do
72
+ payment.update_attributes(amount: 5)
73
+ initial_amount = payment.amount
74
+
75
+ subject
76
+
77
+ expect(payment.amount).not_to eq(initial_amount)
78
+ end
79
+ end
80
+
81
+ describe '#void_transaction!' do
82
+ it 'receive cancel_avalara' do
83
+ expect(payment).to receive(:cancel_avalara)
84
+ payment.void_transaction!
85
+ end
86
+ end
87
+
88
+ describe '#cancel_avalara' do
89
+ context 'uncommitted order' do
90
+ let!(:order) { create(:avalara_order) }
91
+
92
+ describe 'should fail' do
93
+ it 'ResultCode returns Error' do
94
+ response = payment.cancel_avalara
95
+ expect(response['ResultCode']).to eq('Error')
96
+ end
97
+ end
98
+ end
99
+
100
+ context 'committed order' do
101
+ let(:order) { create(:completed_avalara_order) }
102
+
103
+ subject do
104
+ VCR.use_cassette("order_cancel") do
105
+ order.avalara_capture_finalize
106
+ payment.cancel_avalara
107
+ end
108
+ end
109
+
110
+ describe 'should be successful' do
111
+ it 'ResultCode returns Success' do
112
+ expect(subject['ResultCode']).to eq('Success')
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Refund, :vcr do
4
+
5
+ it { should have_one :avalara_transaction }
6
+
7
+ subject(:order) do
8
+ order = create(:shipped_order)
9
+ Spree::AvalaraTransaction.create(order: order)
10
+ order.reload
11
+ end
12
+
13
+ let(:amount) { 10.0 }
14
+ let(:amount_in_cents) { amount * 100 }
15
+
16
+ let(:authorization) { generate(:refund_transaction_id) }
17
+
18
+ let(:payment_amount) { amount*2 }
19
+ let(:payment_method) { create(:credit_card_payment_method) }
20
+ let(:payment) { create(:payment, amount: payment_amount, payment_method: payment_method, order: order) }
21
+
22
+ let(:refund_reason) { create(:refund_reason) }
23
+
24
+ let(:gateway_response) {
25
+ ActiveMerchant::Billing::Response.new(
26
+ gateway_response_success,
27
+ gateway_response_message,
28
+ gateway_response_params,
29
+ gateway_response_options
30
+ )
31
+ }
32
+ let(:gateway_response_success) { true }
33
+ let(:gateway_response_message) { '' }
34
+ let(:gateway_response_params) { {} }
35
+ let(:gateway_response_options) { {} }
36
+
37
+ let(:reimbursement) { create(:reimbursement) }
38
+
39
+ let(:refund) {Spree::Refund.new(payment: payment, amount: BigDecimal.new(10), reason: refund_reason, transaction_id: nil, reimbursement: reimbursement)}
40
+
41
+ before do
42
+ allow(payment.payment_method)
43
+ .to receive(:credit)
44
+ .with(amount_in_cents, payment.source, payment.transaction_id, {originator: an_instance_of(Spree::Refund)})
45
+ .and_return(gateway_response)
46
+ order.reload
47
+ end
48
+
49
+ describe '#avalara_tax_enabled?' do
50
+ it 'should return true' do
51
+ expect(Spree::Refund.new.avalara_tax_enabled?).to eq(true)
52
+ end
53
+ end
54
+
55
+ describe '#avalara_capture_finalize' do
56
+ subject do
57
+ VCR.use_cassette('order_return_capture') do
58
+ refund.save
59
+ end
60
+ end
61
+ it 'should recieve avalara_capture_finalize and return hash' do
62
+ expect(refund).to receive(:avalara_capture_finalize).and_return(Hash)
63
+ subject
64
+ end
65
+ end
66
+
67
+ context 'full refund' do
68
+ let(:order) { create(:completed_avalara_order) }
69
+ let(:refund) { build(:refund, payment: order.payments.first, amount: order.total.to_f) }
70
+
71
+ subject do
72
+ order.reload
73
+ refund.avalara_capture_finalize
74
+ end
75
+
76
+ it 'returns correct tax calculations' do
77
+ expect(subject['TotalAmount'].to_f.abs).to eq(order.total - order.additional_tax_total)
78
+ expect(subject['TotalTax'].to_f.abs).to eq(order.additional_tax_total)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Shipment, type: :model do
4
+ describe '#avatax_cache_key' do
5
+ it 'should respond with a cache key' do
6
+ shipment = build(:shipment, id: 1, cost: 10.0, promo_total: 0.0)
7
+
8
+ expected_response = "Spree::Shipment-1-10.0-#{shipment.stock_location.cache_key}-0.0"
9
+
10
+ expect(shipment.avatax_cache_key).to eq(expected_response)
11
+ end
12
+ end
13
+
14
+ describe '#avatax_line_code' do
15
+ it 'should equal FR' do
16
+ shipment = create(:shipment)
17
+
18
+ expect(shipment.avatax_line_code).to eq('FR')
19
+ end
20
+ end
21
+
22
+ describe '#shipping_method_tax_code' do
23
+ it 'should return empty string if no tax category assigned to shipment' do
24
+ shipment = create(:shipment)
25
+
26
+ expect(shipment.shipping_method_tax_code).to eq('')
27
+ end
28
+ it 'should return tax code' do
29
+ tax_category = build(:tax_category, name: 'Shipping', tax_code: 'FR000000')
30
+ shipping_method = build(:shipping_method, tax_category: tax_category)
31
+ shipment = create(:shipment, shipping_method: shipping_method)
32
+
33
+ expect(shipment.shipping_method_tax_code).to eq('FR000000')
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::ShippingRate, type: :model do
4
+ let!(:shipping_tax_category) { create(:tax_category, name: 'Shipping', tax_code: 'FR000000') }
5
+ let!(:zone) { create(:zone, name: 'North America', default_tax: true, zone_members: []) }
6
+ let!(:tax_rate) { create(:tax_rate, tax_category: shipping_tax_category, amount: 0.00, included_in_price: false, zone: zone) }
7
+
8
+ let(:shipment) { build(:shipment) }
9
+ let(:shipping_method) { build(:shipping_method) }
10
+ let(:shipping_rate) { Spree::ShippingRate.new(shipment: shipment, shipping_method: shipping_method, cost: 10, tax_rate_id: tax_rate.id) }
11
+
12
+ describe '#tax_rate' do
13
+ it 'returns the tax rate associated with shipping rate' do
14
+ expect(shipping_rate.tax_rate).to eq(tax_rate)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree.user_class do
4
+ it { should belong_to :avalara_entity_use_code }
5
+ end
@@ -0,0 +1,81 @@
1
+ # Run Coverage report
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter 'spec/dummy'
5
+ add_group 'Controllers', 'app/controllers'
6
+ add_group 'Helpers', 'app/helpers'
7
+ add_group 'Mailers', 'app/mailers'
8
+ add_group 'Models', 'app/models'
9
+ add_group 'Views', 'app/views'
10
+ add_group 'Libraries', 'lib'
11
+ end
12
+
13
+ # Configure Rails Environment
14
+ ENV['RAILS_ENV'] = 'test'
15
+
16
+ require File.expand_path('../dummy/config/environment.rb', __FILE__)
17
+
18
+ require 'dotenv'
19
+ Dotenv.load
20
+
21
+ require 'rspec/rails'
22
+ require 'database_cleaner'
23
+ require 'ffaker'
24
+ require 'shoulda/matchers'
25
+ require 'capybara-screenshot/rspec'
26
+
27
+ require 'spree/testing_support/preferences'
28
+ require 'spree/testing_support/authorization_helpers'
29
+ require 'spree/testing_support/capybara_ext'
30
+ require 'spree/testing_support/controller_requests'
31
+ require 'spree/testing_support/factories'
32
+ require 'spree/testing_support/url_helpers'
33
+ require 'spree/testing_support/order_walkthrough'
34
+
35
+
36
+ Capybara.save_and_open_page_path = ENV['CIRCLE_ARTIFACTS'] if ENV['CIRCLE_ARTIFACTS']
37
+
38
+ if ENV['WEBDRIVER'] == 'accessible'
39
+ require 'capybara/accessible'
40
+ Capybara.javascript_driver = :accessible
41
+ end
42
+
43
+ Dir[File.join(File.dirname(__FILE__), 'factories/*.rb')].each { |f| require f }
44
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f }
45
+
46
+ RSpec.configure do |config|
47
+ config.infer_spec_type_from_file_location!
48
+ config.mock_with :rspec
49
+ config.color = true
50
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
51
+ config.use_transactional_fixtures = false
52
+ config.fail_fast = ENV['FAIL_FAST'] || false
53
+ config.order = "random"
54
+
55
+ config.include FactoryGirl::Syntax::Methods
56
+ config.include Spree::TestingSupport::Preferences
57
+ config.include Spree::TestingSupport::UrlHelpers
58
+ config.include Spree::TestingSupport::ControllerRequests, type: :controller
59
+
60
+
61
+ if ENV['WEBDRIVER'] == 'accessible'
62
+ config.around(:each, :inaccessible => true) do |example|
63
+ Capybara::Accessible.skip_audit { example.run }
64
+ end
65
+ end
66
+
67
+ config.before :suite do
68
+ DatabaseCleaner.strategy = :transaction
69
+ DatabaseCleaner.clean_with :truncation
70
+ end
71
+
72
+ config.before :each do
73
+ DatabaseCleaner.strategy = RSpec.current_example.metadata[:js] ? :truncation : :transaction
74
+ DatabaseCleaner.start
75
+ MyConfigPreferences.set_preferences
76
+ end
77
+
78
+ config.after :each do
79
+ DatabaseCleaner.clean
80
+ end
81
+ end
@@ -0,0 +1,8 @@
1
+ class MyConfigPreferences
2
+ def self.set_preferences
3
+ SolidusAvataxCertified::PreferenceSeeder.seed!(false)
4
+ Spree::AvalaraPreference.origin_address.update_attributes(value: "{\"Line1\":\"915 S Jackson St\",\"Line2\":\"\",\"City\":\"Montgomery\",\"Region\":\"AL\",\"PostalCode\":\"36104\",\"Zip4\":\"\",\"Country\":\"US\"}")
5
+ Spree::AvalaraPreference.log_to_stdout.update_attributes(value: 'false')
6
+ Spree::AvalaraPreference.refuse_checkout_address_validation_error.update_attributes(value: 'false')
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'vcr'
2
+
3
+ VCR.configure do |config|
4
+ config.cassette_library_dir = 'spec/vcr'
5
+ config.hook_into :webmock
6
+ config.ignore_localhost = true
7
+ config.configure_rspec_metadata!
8
+ # config.default_cassette_options = { match_requests_on: [:method, :host], record: :new_episodes }
9
+ end