solidus_paypal_commerce_platform 0.3.2 → 0.5.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +25 -2
  3. data/.rubocop.yml +6 -5
  4. data/CHANGELOG.md +180 -122
  5. data/Gemfile +16 -3
  6. data/README.md +27 -2
  7. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +3 -1
  8. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +14 -0
  9. data/app/controllers/solidus_paypal_commerce_platform/orders_controller.rb +1 -1
  10. data/app/controllers/solidus_paypal_commerce_platform/payments_controller.rb +4 -2
  11. data/app/helpers/solidus_paypal_commerce_platform/button_options_helper.rb +4 -0
  12. data/app/models/solidus_paypal_commerce_platform/gateway.rb +20 -3
  13. data/app/models/solidus_paypal_commerce_platform/payment_method.rb +21 -1
  14. data/app/models/solidus_paypal_commerce_platform/payment_source.rb +12 -1
  15. data/app/models/solidus_paypal_commerce_platform/paypal_order.rb +6 -21
  16. data/app/models/solidus_paypal_commerce_platform/wizard.rb +1 -1
  17. data/bin/rails-engine +1 -1
  18. data/config/locales/en.yml +34 -1
  19. data/db/migrate/20211220133406_add_paypal_funding_source_to_paypal_commerce_platform_sources.rb +5 -0
  20. data/lib/paypal/access_token.rb +22 -0
  21. data/lib/paypal/lib.rb +19 -0
  22. data/lib/paypal/paypal_checkout_sdk/orders/orders_authorize_request.rb +44 -0
  23. data/lib/paypal/paypal_checkout_sdk/orders/orders_capture_request.rb +42 -0
  24. data/lib/paypal/paypal_checkout_sdk/orders/orders_create_request.rb +36 -0
  25. data/lib/paypal/paypal_checkout_sdk/orders/orders_get_request.rb +26 -0
  26. data/lib/paypal/paypal_checkout_sdk/orders/orders_patch_request.rb +77 -0
  27. data/lib/paypal/paypal_checkout_sdk/orders/orders_validate_request.rb +34 -0
  28. data/lib/paypal/paypal_checkout_sdk/payments/authorizations_capture_request.rb +38 -0
  29. data/lib/paypal/paypal_checkout_sdk/payments/authorizations_get_request.rb +26 -0
  30. data/lib/paypal/paypal_checkout_sdk/payments/authorizations_reauthorize_request.rb +45 -0
  31. data/lib/paypal/paypal_checkout_sdk/payments/authorizations_void_request.rb +27 -0
  32. data/lib/paypal/paypal_checkout_sdk/payments/captures_get_request.rb +26 -0
  33. data/lib/paypal/paypal_checkout_sdk/payments/captures_refund_request.rb +40 -0
  34. data/lib/paypal/paypal_checkout_sdk/payments/refunds_get_request.rb +26 -0
  35. data/lib/paypal/paypal_environment.rb +39 -0
  36. data/lib/paypal/paypal_http_client.rb +56 -0
  37. data/lib/paypal/token_requests.rb +42 -0
  38. data/lib/solidus_paypal_commerce_platform/access_token_authorization_request.rb +1 -1
  39. data/lib/solidus_paypal_commerce_platform/client.rb +4 -4
  40. data/lib/solidus_paypal_commerce_platform/configuration.rb +4 -4
  41. data/lib/solidus_paypal_commerce_platform/engine.rb +11 -3
  42. data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_authorize_request.rb +48 -0
  43. data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_capture_request.rb +46 -0
  44. data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_patch_request.rb +80 -0
  45. data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_validate_request.rb +36 -0
  46. data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/payments/authorizations_reauthorize_request.rb +50 -0
  47. data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/payments/captures_refund_request.rb +43 -0
  48. data/lib/solidus_paypal_commerce_platform/testing_support/factories.rb +2 -1
  49. data/lib/solidus_paypal_commerce_platform/version.rb +1 -1
  50. data/lib/solidus_paypal_commerce_platform.rb +1 -0
  51. data/lib/views/backend/spree/admin/payments/source_views/_paypal_commerce_platform.html.erb +3 -0
  52. data/lib/views/frontend/solidus_paypal_commerce_platform/payments/_payment.html.erb +4 -0
  53. data/lib/views/frontend/spree/checkout/payment/_paypal_commerce_platform.html.erb +17 -3
  54. data/solidus_paypal_commerce_platform.gemspec +9 -8
  55. metadata +52 -78
  56. data/spec/features/backend/new_payment_method_spec.rb +0 -40
  57. data/spec/features/frontend/cart_spec.rb +0 -46
  58. data/spec/features/frontend/checkout_spec.rb +0 -89
  59. data/spec/features/frontend/product_spec.rb +0 -91
  60. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.COMPLETED.v2.json +0 -121
  61. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.PROCESSED.v2.json +0 -121
  62. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v1.json +0 -50
  63. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v2.json +0 -72
  64. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v1.json +0 -50
  65. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v2.json +0 -68
  66. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v1.json +0 -51
  67. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v2.json +0 -63
  68. data/spec/jobs/solidus_paypal_commerce_platform/webhook_job_spec.rb +0 -44
  69. data/spec/lib/solidus_paypal_commerce_platform/client_spec.rb +0 -21
  70. data/spec/lib/solidus_paypal_commerce_platform/configuration_spec.rb +0 -91
  71. data/spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb +0 -129
  72. data/spec/models/solidus_paypal_commerce_platform/payment_source_spec.rb +0 -62
  73. data/spec/models/solidus_paypal_commerce_platform/paypal_address_spec.rb +0 -67
  74. data/spec/models/solidus_paypal_commerce_platform/paypal_order_spec.rb +0 -33
  75. data/spec/models/solidus_paypal_commerce_platform/state_guesser_spec.rb +0 -38
  76. data/spec/models/solidus_paypal_commerce_platform/wizard_spec.rb +0 -9
  77. data/spec/requests/solidus_paypal_commerce_platform/orders_controller_spec.rb +0 -36
  78. data/spec/requests/solidus_paypal_commerce_platform/shipping_rates_controller_spec.rb +0 -44
  79. data/spec/requests/solidus_paypal_commerce_platform/wizard_controller_spec.rb +0 -44
  80. data/spec/spec_helper.rb +0 -32
  81. data/spec/support/capybara.rb +0 -11
  82. data/spec/support/paypal_sdk_script_tag_helper.rb +0 -13
@@ -1,51 +0,0 @@
1
- {
2
- "id": "WH-2JG62852X9350413N-40V56408FN023574K",
3
- "create_time": "2014-10-22T23:49:03Z",
4
- "resource_type": "capture",
5
- "event_type": "PAYMENT.CAPTURE.REFUNDED",
6
- "summary": "A $ 0.15 USD capture payment was refunded",
7
- "resource": {
8
- "parent_payment": "PAY-7PD36489JY0066936KREEERQ",
9
- "update_time": "2014-10-22T23:48:57Z",
10
- "amount": {
11
- "total": "-0.15",
12
- "currency": "USD"
13
- },
14
- "create_time": "2014-10-22T23:48:57Z",
15
- "links": [
16
- {
17
- "href": "https://api.paypal.com/v1/payments/refund/8VC964970N548345V",
18
- "rel": "self",
19
- "method": "GET"
20
- },
21
- {
22
- "href": "https://api.paypal.com/v1/payments/payment/PAY-7PD36489JY0066936KREEERQ",
23
- "rel": "parent_payment",
24
- "method": "GET"
25
- },
26
- {
27
- "href": "https://api.paypal.com/v1/payments/capture/5LK72275CG489890D",
28
- "rel": "capture",
29
- "method": "GET"
30
- }
31
- ],
32
- "id": "8VC964970N548345V",
33
- "state": "completed",
34
- "capture_id": "5LK72275CG489890D"
35
- },
36
- "links": [
37
- {
38
- "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-2JG62852X9350413N-40V56408FN023574K",
39
- "rel": "self",
40
- "method": "GET",
41
- "encType": "application/json"
42
- },
43
- {
44
- "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-2JG62852X9350413N-40V56408FN023574K/resend",
45
- "rel": "resend",
46
- "method": "POST",
47
- "encType": "application/json"
48
- }
49
- ],
50
- "event_version": "1.0"
51
- }
@@ -1,63 +0,0 @@
1
- {
2
- "id": "WH-1GE84257G0350133W-6RW800890C634293G",
3
- "create_time": "2018-08-15T19:14:04.543Z",
4
- "resource_type": "refund",
5
- "event_type": "PAYMENT.CAPTURE.REFUNDED",
6
- "summary": "A $ 0.99 USD capture payment was refunded",
7
- "resource": {
8
- "seller_payable_breakdown": {
9
- "gross_amount": {
10
- "currency_code": "USD",
11
- "value": "0.99"
12
- },
13
- "paypal_fee": {
14
- "currency_code": "USD",
15
- "value": "0.02"
16
- },
17
- "net_amount": {
18
- "currency_code": "USD",
19
- "value": "0.97"
20
- },
21
- "total_refunded_amount": {
22
- "currency_code": "USD",
23
- "value": "1.98"
24
- }
25
- },
26
- "amount": {
27
- "currency_code": "USD",
28
- "value": "0.99"
29
- },
30
- "update_time": "2018-08-15T12:13:29-07:00",
31
- "create_time": "2018-08-15T12:13:29-07:00",
32
- "links": [
33
- {
34
- "href": "https://api.paypal.com/v2/payments/refunds/1Y107995YT783435V",
35
- "rel": "self",
36
- "method": "GET"
37
- },
38
- {
39
- "href": "https://api.paypal.com/v2/payments/captures/0JF852973C016714D",
40
- "rel": "up",
41
- "method": "GET"
42
- }
43
- ],
44
- "id": "1Y107995YT783435V",
45
- "status": "COMPLETED"
46
- },
47
- "links": [
48
- {
49
- "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-1GE84257G0350133W-6RW800890C634293G",
50
- "rel": "self",
51
- "method": "GET",
52
- "encType": "application/json"
53
- },
54
- {
55
- "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-1GE84257G0350133W-6RW800890C634293G/resend",
56
- "rel": "resend",
57
- "method": "POST",
58
- "encType": "application/json"
59
- }
60
- ],
61
- "event_version": "1.0",
62
- "resource_version": "2.0"
63
- }
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::WebhookJob do
4
- let(:paypal_order_id) { SecureRandom.uuid }
5
- let(:capture_id) { SecureRandom.uuid }
6
- let(:refund_id) { SecureRandom.uuid }
7
-
8
- let(:payment_source) {
9
- SolidusPaypalCommercePlatform::PaymentSource.new(
10
- paypal_order_id: paypal_order_id,
11
- capture_id: capture_id,
12
- refund_id: refund_id,
13
- payment_method: create(:paypal_payment_method),
14
- )
15
- }
16
-
17
- let(:payment) {
18
- create(:order).payments.create!(
19
- payment_method: payment_source.payment_method,
20
- source: payment_source,
21
- )
22
- }
23
-
24
- [
25
- ["CHECKOUT.ORDER.COMPLETED.v2", "paypal_order_id"],
26
- ["CHECKOUT.ORDER.PROCESSED.v2", "paypal_order_id"],
27
- ["PAYMENT.CAPTURE.COMPLETED.v1", "capture_id"],
28
- ["PAYMENT.CAPTURE.COMPLETED.v2", "capture_id"],
29
- ["PAYMENT.CAPTURE.DENIED.v1", "capture_id"],
30
- ["PAYMENT.CAPTURE.DENIED.v2", "capture_id"],
31
- ["PAYMENT.CAPTURE.REFUNDED.v1", "capture_id"],
32
- ["PAYMENT.CAPTURE.REFUNDED.v2", "refund_id"],
33
- ].each do |(event, source_attr)|
34
- describe event do
35
- let(:payload) { JSON.parse(File.read("#{__dir__}/fixtures/#{event}.json")) }
36
- let(source_attr) { payload.dig("resource", "id") }
37
-
38
- it 'inserts a log entry for the corresponding payment source' do
39
- expect { described_class.perform_now(payload) }.to change(payment.log_entries, :count).by(1)
40
- expect(YAML.load(payment.log_entries.last.details)).to eq(payload)
41
- end
42
- end
43
- end
44
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::Client do
4
- subject(:client) { described_class.new(client_id: "1234") }
5
-
6
- describe '#execute_with_response' do
7
- let(:request_class) { SolidusPaypalCommercePlatform::Gateway::OrdersCaptureRequest }
8
- let(:paypal_request) { double(:request, class: request_class) }
9
- let(:paypal_response) { double(:response, status_code: status_code, result: nil, headers: {}) }
10
- let(:status_code) { 201 }
11
-
12
- it 'forwards to the upstream client adding i18n response messages' do
13
- allow_any_instance_of(PayPal::PayPalHttpClient)
14
- .to receive(:execute).with(paypal_request).and_return(paypal_response)
15
-
16
- response = subject.execute_with_response(paypal_request)
17
-
18
- expect(response.message).to eq("Payment captured")
19
- end
20
- end
21
- end
@@ -1,91 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::Configuration do
4
- let(:subject) { described_class.new }
5
-
6
- describe '#default_env' do
7
- it "uses ENV['PAYPAL_ENV'] when present" do
8
- expect(ENV).to receive(:[]).with("PAYPAL_ENV").and_return("foo").at_least(:once)
9
- expect(subject.default_env).to eq("foo")
10
- end
11
-
12
- it "falls back to Rails.env if ENV['PAYPAL_ENV'] is not set" do
13
- expect(ENV).to receive(:[]).with("PAYPAL_ENV").and_return(nil).at_least(:once)
14
-
15
- allow(Rails).to receive(:env).and_return("development".inquiry)
16
- expect(subject.default_env).to eq("sandbox")
17
-
18
- allow(Rails).to receive(:env).and_return("test".inquiry)
19
- expect(subject.default_env).to eq("sandbox")
20
-
21
- allow(Rails).to receive(:env).and_return("production".inquiry)
22
- expect(subject.default_env).to eq("live")
23
-
24
- allow(Rails).to receive(:env).and_return("staging".inquiry)
25
- expect{ subject.default_env }.to raise_error(described_class::InvalidEnvironment)
26
- end
27
- end
28
-
29
- describe '#env' do
30
- it 'returns a string inquirer' do
31
- expect(subject.env).to eq("sandbox")
32
- expect(subject.env).to be_sandbox
33
-
34
- subject.env = "live"
35
- expect(subject.env).to eq("live")
36
- expect(subject.env).to be_live
37
-
38
- subject.env = "sandbox"
39
- expect(subject.env).to eq("sandbox")
40
- expect(subject.env).to be_sandbox
41
- end
42
-
43
- it 'raises an error when assigned an unsupported value' do
44
- expect{ subject.env = "foo" }.to raise_error(described_class::InvalidEnvironment)
45
- end
46
- end
47
-
48
- describe '#env_class' do
49
- it 'changes based on the current env' do
50
- subject.env = "live"
51
- expect(subject.env_class).to eq(PayPal::LiveEnvironment)
52
-
53
- subject.env = "sandbox"
54
- expect(subject.env_class).to eq(PayPal::SandboxEnvironment)
55
- end
56
- end
57
-
58
- describe '#env_domain' do
59
- it 'changes based on the current env' do
60
- subject.env = "live"
61
- expect(subject.env_domain).to eq("www.paypal.com")
62
-
63
- subject.env = "sandbox"
64
- expect(subject.env_domain).to eq("www.sandbox.paypal.com")
65
- end
66
- end
67
-
68
- describe "#state_guesser_class" do
69
- before do
70
- stub_const('SolidusPaypalCommercePlatform::BetterStateGuesser', Class.new)
71
- end
72
-
73
- it "returns a class" do
74
- expect(subject.state_guesser_class).to be_kind_of(Class)
75
- end
76
-
77
- it "is settable" do
78
- expect(subject.state_guesser_class).to eq(SolidusPaypalCommercePlatform::StateGuesser)
79
-
80
- subject.state_guesser_class = "SolidusPaypalCommercePlatform::BetterStateGuesser"
81
-
82
- expect(subject.state_guesser_class).to eq(SolidusPaypalCommercePlatform::BetterStateGuesser)
83
- end
84
- end
85
-
86
- describe "#partner_code" do
87
- it "returns the correct code" do
88
- expect(subject.partner_code).to eq("Solidus_PCP_SP")
89
- end
90
- end
91
- end
@@ -1,129 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::PaymentMethod, type: :model do
4
- let(:paypal_payment_method) { create(:paypal_payment_method) }
5
- let(:payment) { create(:payment) }
6
- let(:completed_payment) { create(:payment, :completed) }
7
- let(:response) { Struct(status_code: status_code, result: result, headers: headers) }
8
- let(:status_code) { 201 }
9
- let(:result) { nil }
10
- let(:headers) { {} }
11
-
12
- def Struct(data) # rubocop:disable Naming/MethodName
13
- Struct.new(*data.keys, keyword_init: true).new(data)
14
- end
15
-
16
- before { allow_any_instance_of(PayPal::PayPalHttpClient).to receive(:execute) { response } }
17
-
18
- describe "#purchase" do
19
- let(:result) { Struct(purchase_units: [Struct(payments: payments)]) }
20
- let(:payments) { Struct(captures: [Struct(id: SecureRandom.hex(4))]) }
21
-
22
- it "sends a purchase request to paypal" do
23
- paypal_order_id = SecureRandom.hex(8)
24
- source = paypal_payment_method.payment_source_class.create(paypal_order_id: paypal_order_id)
25
- expect_request(:OrdersCaptureRequest).to receive(:new).with(paypal_order_id).and_call_original
26
- paypal_payment_method.purchase(1000, source, {})
27
- end
28
- end
29
-
30
- describe "#authorize" do
31
- let(:result) { Struct(purchase_units: [Struct(payments: payments)]) }
32
- let(:payments) { Struct(authorizations: [Struct(id: SecureRandom.hex(4))]) }
33
-
34
- it "sends an authorize request to paypal" do
35
- paypal_order_id = SecureRandom.hex(8)
36
- source = paypal_payment_method.payment_source_class.create(paypal_order_id: paypal_order_id)
37
- expect_request(:OrdersAuthorizeRequest).to receive(:new).with(paypal_order_id)
38
- paypal_payment_method.authorize(1000, source, {})
39
- end
40
- end
41
-
42
- describe "#capture" do
43
- let(:result) { Struct(id: SecureRandom.hex(4)) }
44
-
45
- it "sends a capture request to paypal" do
46
- authorization_id = SecureRandom.hex(8)
47
- source = paypal_payment_method.payment_source_class.create(authorization_id: authorization_id)
48
- payment.source = source
49
- expect_request(:AuthorizationsCaptureRequest).to receive(:new).with(authorization_id).and_call_original
50
- paypal_payment_method.capture(1000, {}, originator: payment)
51
- end
52
- end
53
-
54
- describe "#void" do
55
- it "sends a void request to paypal" do
56
- authorization_id = SecureRandom.hex(8)
57
- source = paypal_payment_method.payment_source_class.create(authorization_id: authorization_id)
58
- payment.source = source
59
- expect_request(:AuthorizationsVoidRequest).to receive(:new).with(authorization_id)
60
- paypal_payment_method.void(nil, originator: payment)
61
- end
62
- end
63
-
64
- describe "#credit" do
65
- let(:result) { Struct(id: SecureRandom.hex(4)) }
66
-
67
- it "sends a refund request to paypal" do
68
- capture_id = SecureRandom.hex(4)
69
- source = paypal_payment_method.payment_source_class.create(capture_id: capture_id)
70
- completed_payment.source = source
71
- expect_request(:CapturesRefundRequest).to receive(:new).with(capture_id).and_call_original
72
- paypal_payment_method.credit(1000, {}, originator: completed_payment.refunds.new(amount: 12))
73
- expect(source.refund_id).not_to be_blank
74
- end
75
- end
76
-
77
- describe '.javascript_sdk_url' do
78
- subject(:url) { URI(paypal_payment_method.javascript_sdk_url(order: order)) }
79
-
80
- context 'when checkout_steps include "confirm"' do
81
- let(:order) { instance_double(Spree::Order, checkout_steps: { "confirm" => "bar" }) }
82
-
83
- it 'sets autocommit' do
84
- expect(url.query.split("&")).to include("commit=false")
85
- end
86
- end
87
-
88
- context 'when checkout_steps does not include "confirm"' do
89
- let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }
90
-
91
- it 'disables autocommit' do
92
- expect(url.query.split("&")).to include("commit=true")
93
- end
94
- end
95
-
96
- context 'when checkout_steps does not include "delivery"' do
97
- let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }
98
-
99
- it 'disables autocommit' do
100
- expect(url.query.split("&")).to include("shipping_preference=NO_SHIPPING")
101
- end
102
- end
103
-
104
- context 'when messaging is turned on' do
105
- let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }
106
-
107
- it 'includes messaging component' do
108
- paypal_payment_method.preferences.update(display_credit_messaging: true)
109
- expect(url.query.split("&")).to include("components=buttons%2Cmessages")
110
- end
111
- end
112
-
113
- context 'when messaging is turned off' do
114
- let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }
115
-
116
- it 'only includes buttons components' do
117
- paypal_payment_method.preferences.update(display_credit_messaging: false)
118
- expect(url.query.split("&")).not_to include("messages")
119
- expect(url.query.split("&")).to include("components=buttons")
120
- end
121
- end
122
- end
123
-
124
- private
125
-
126
- def expect_request(name)
127
- expect(SolidusPaypalCommercePlatform::Gateway.const_get(name))
128
- end
129
- end
@@ -1,62 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::PaymentSource, type: :model do
4
- let(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:payment) }
5
- let(:paypal_payment_method) { create(:paypal_payment_method) }
6
- let(:paypal_order_id) { "foo-123" }
7
- let(:payment_source) {
8
- described_class.new(
9
- paypal_order_id: paypal_order_id,
10
- payment_method: paypal_payment_method,
11
- )
12
- }
13
- let(:payment) {
14
- order.payments.create!(
15
- payment_method: paypal_payment_method,
16
- source: payment_source
17
- )
18
- }
19
- let(:paypal_order_status) { "COMPLETED" }
20
-
21
- before do
22
- allow_any_instance_of(SolidusPaypalCommercePlatform::Client).to receive(:execute) do |_client, request|
23
- expect(request).to be_a(SolidusPaypalCommercePlatform::Gateway::OrdersGetRequest) # rubocop:disable RSpec/ExpectInHook
24
- OpenStruct.new(result: OpenStruct.new(status: paypal_order_status))
25
- end
26
- end
27
-
28
- describe '#actions' do
29
- context 'when the payment is not yet completed' do
30
- it 'shows "capture" and "void"' do
31
- expect(payment.actions).to contain_exactly("capture", "void")
32
- end
33
- end
34
-
35
- context 'when the payment is completed and captured' do
36
- before do
37
- payment.update!(state: :completed, amount: 123)
38
- payment_source.update!(capture_id: 1234)
39
- end
40
-
41
- it 'shows "credit"' do
42
- expect(payment.actions).to contain_exactly("credit")
43
- end
44
-
45
- context 'when the PayPal order status is not COMPLETED' do
46
- let(:paypal_order_status) { "FOOBAR" }
47
-
48
- it 'hides the "credit" action' do
49
- expect(payment.actions).not_to include("credit")
50
- end
51
- end
52
- end
53
-
54
- context 'when it cannot capture' do
55
- it 'also cannot void' do
56
- # One for "capture", and one for "void"
57
- expect(payment_source).to receive(:can_capture?).and_return(false).twice
58
- expect(payment.actions).not_to include("void")
59
- end
60
- end
61
- end
62
- end
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::PaypalAddress, type: :model do
4
- let(:order) { create(:order) }
5
- let(:original_address) { create(:address) }
6
- let(:address) { create(:address, name_attributes) }
7
- let(:params) {
8
- {
9
- updated_address: {
10
- admin_area_1: address.state.abbr,
11
- admin_area_2: address.city,
12
- address_line_1: address.address1,
13
- address_line_2: address.address2,
14
- postal_code: address.zipcode,
15
- country_code: address.country.iso
16
- },
17
- recipient: {
18
- name: {
19
- given_name: "Alexander",
20
- surname: "Hamilton"
21
- }
22
- }
23
- }
24
- }
25
-
26
- describe "#update_address" do
27
- subject{ order.ship_address }
28
-
29
- it "formats PayPal addresses correctly" do
30
- order.ship_address = original_address
31
-
32
- described_class.new(order).update(params)
33
-
34
- expect(subject.state).to eq address.state
35
- expect(subject.city).to eq address.city
36
- expect(subject.address1).to eq address.address1
37
- expect(subject.address2).to eq address.address2
38
- expect(subject.zipcode).to eq address.zipcode
39
- expect(subject.country).to eq address.country
40
- if SolidusSupport.combined_first_and_last_name_in_address?
41
- expect(subject.name).to eq address.name
42
- else
43
- expect(subject.firstname).to eq address.firstname
44
- expect(subject.lastname).to eq address.lastname
45
- end
46
- expect(subject.phone).to eq original_address.phone
47
- end
48
-
49
- context "when no address exists" do
50
- it "produce a valid address" do
51
- order.ship_address = nil
52
-
53
- described_class.new(order).update(params)
54
-
55
- expect(subject).to be_present
56
- end
57
- end
58
- end
59
-
60
- def name_attributes
61
- if SolidusSupport.combined_first_and_last_name_in_address?
62
- { name: "Alexander Hamilton" }
63
- else
64
- { firstname: "Alexander", lastname: "Hamilton" }
65
- end
66
- end
67
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe SolidusPaypalCommercePlatform::PaypalOrder, type: :model do
6
- describe '#to_json' do
7
- subject(:to_json) { described_class.new(order).to_json('intent') }
8
-
9
- let(:order) { create(:order_ready_to_complete) }
10
-
11
- it { expect { to_json }.not_to raise_error }
12
-
13
- if Spree.solidus_gem_version >= Gem::Version.new('2.11')
14
- it 'returns the name of the user' do
15
- expect(to_json).to match hash_including(
16
- purchase_units: array_including(
17
- hash_including(shipping: hash_including(name: { full_name: 'John Von Doe' }))
18
- ),
19
- payer: hash_including(name: { given_name: 'John', surname: 'Von Doe' })
20
- )
21
- end
22
- else
23
- it 'returns the name and surname of the user' do
24
- expect(to_json).to match hash_including(
25
- purchase_units: array_including(
26
- hash_including(shipping: hash_including(name: { full_name: 'John' }))
27
- ),
28
- payer: hash_including(name: { given_name: 'John', surname: nil })
29
- )
30
- end
31
- end
32
- end
33
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::StateGuesser, type: :model do
4
- let(:country) { create(:country, iso: "IT") }
5
- let!(:state) { create(:state, country: country, name: "Abruzzo") }
6
-
7
- describe "#guess" do
8
- context "with a guessable state error" do
9
- it "correctly guesses the state" do
10
- expect(
11
- described_class.new("Pescara", country).guess
12
- ).to eq state
13
- end
14
-
15
- it "guesses the state using an abbreviation" do
16
- expect(
17
- described_class.new("PE", country).guess
18
- ).to eq state
19
- end
20
- end
21
-
22
- context "with an unsolvable state error" do
23
- it "returns nil" do
24
- expect(
25
- described_class.new("Gondor", country).guess
26
- ).to eq nil
27
- end
28
- end
29
-
30
- context "with an already correct state" do
31
- it "returns the correct state" do
32
- expect(
33
- described_class.new("Abruzzo", country).guess
34
- ).to eq state
35
- end
36
- end
37
- end
38
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::Wizard do
4
- describe "#nonce" do
5
- it 'is between 45 and 128 chars long' do
6
- expect(subject.nonce.size).to be_between(45, 128)
7
- end
8
- end
9
- end
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe SolidusPaypalCommercePlatform::OrdersController, type: :request do
4
- stub_authorization!
5
- let(:order) { create(:order_with_line_items) }
6
-
7
- describe "GET /solidus_paypal_commerce_platform/verify_total" do
8
- context "when the amount is correct" do
9
- it "passes" do
10
- params = {
11
- order_id: order.number,
12
- paypal_total: order.total,
13
- format: :json
14
- }
15
-
16
- get solidus_paypal_commerce_platform.verify_total_path, params: params
17
-
18
- expect(response).to have_http_status(:ok)
19
- end
20
- end
21
-
22
- context "when the amount is incorrect" do
23
- it "fails" do
24
- params = {
25
- order_id: order.number,
26
- paypal_total: order.total - 1,
27
- format: :json
28
- }
29
-
30
- get solidus_paypal_commerce_platform.verify_total_path, params: params
31
-
32
- expect(response).to have_http_status(:bad_request)
33
- end
34
- end
35
- end
36
- end