workarea-paypal 2.0.10 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.json +2 -1
  3. data/.gitignore +16 -11
  4. data/CHANGELOG.md +86 -2
  5. data/README.md +105 -6
  6. data/Rakefile +1 -2
  7. data/UPGRADE.md +46 -0
  8. data/app/assets/javascripts/workarea/storefront/paypal/config.js.erb +44 -0
  9. data/app/assets/javascripts/workarea/storefront/paypal/modules/paypal_buttons.js +71 -0
  10. data/app/assets/javascripts/workarea/storefront/paypal/modules/paypal_hosted_fields.js +96 -0
  11. data/app/assets/javascripts/workarea/storefront/paypal/modules/update_checkout_submit_text.js +11 -5
  12. data/app/assets/javascripts/workarea/storefront/paypal/templates/paypal_fields.jst.ejs +43 -0
  13. data/app/controllers/workarea/storefront/checkout/place_order_controller.decorator +6 -4
  14. data/app/controllers/workarea/storefront/paypal_controller.rb +32 -26
  15. data/app/helpers/workarea/storefront/paypal_helper.rb +38 -0
  16. data/app/models/workarea/payment.decorator +17 -3
  17. data/app/models/workarea/payment/authorize/paypal.rb +13 -13
  18. data/app/models/workarea/payment/capture/paypal.rb +10 -20
  19. data/app/models/workarea/payment/null_address.rb +37 -0
  20. data/app/models/workarea/payment/purchase/paypal.rb +1 -25
  21. data/app/models/workarea/payment/refund/paypal.rb +3 -6
  22. data/app/models/workarea/payment/tender/paypal.rb +14 -2
  23. data/app/services/workarea/paypal/approve_order.rb +104 -0
  24. data/app/services/workarea/paypal/create_order.rb +177 -0
  25. data/app/services/workarea/paypal/update_order.rb +44 -0
  26. data/app/views/workarea/admin/orders/tenders/_paypal.html.haml +5 -2
  27. data/app/views/workarea/api/orders/tenders/_paypal.json.jbuilder +7 -1
  28. data/app/views/workarea/storefront/carts/_paypal_checkout.html.haml +6 -1
  29. data/app/views/workarea/storefront/checkouts/_paypal_payment.html.haml +17 -6
  30. data/app/views/workarea/storefront/order_mailer/tenders/_paypal.html.haml +5 -3
  31. data/app/views/workarea/storefront/orders/tenders/_paypal.html.haml +9 -2
  32. data/app/views/workarea/storefront/paypal/_paypal_sdk.html.haml +1 -0
  33. data/app/workers/workarea/paypal/handle_webhook_event.rb +64 -0
  34. data/config/initializers/append_points.rb +17 -5
  35. data/config/initializers/fields.rb +27 -0
  36. data/config/initializers/workarea.rb +41 -5
  37. data/config/locales/en.yml +15 -5
  38. data/config/routes.rb +5 -2
  39. data/lib/tasks/workarea/create_webhooks.rake +29 -0
  40. data/lib/workarea/paypal.rb +22 -18
  41. data/lib/workarea/paypal/engine.rb +4 -0
  42. data/lib/workarea/paypal/gateway.rb +200 -0
  43. data/lib/workarea/paypal/requests/create_webhook.rb +21 -0
  44. data/lib/workarea/paypal/requests/delete_webhook.rb +17 -0
  45. data/lib/workarea/paypal/requests/generate_token.rb +21 -0
  46. data/lib/workarea/paypal/requests/list_webhooks.rb +17 -0
  47. data/lib/workarea/paypal/version.rb +1 -1
  48. data/package.json +9 -0
  49. data/test/dummy/config/initializers/workarea.rb +1 -1
  50. data/test/factories/workarea/capture_completed_webhook.json +70 -0
  51. data/test/factories/workarea/capture_denied_webhook.json +68 -0
  52. data/test/factories/workarea/paypal.rb +34 -0
  53. data/test/helpers/workarea/storefront/paypal_helper_test.rb +35 -0
  54. data/test/integration/workarea/storefront/paypal_integration_test.rb +104 -294
  55. data/test/integration/workarea/storefront/paypal_place_order_integration_test.rb +42 -0
  56. data/test/lib/workarea/paypal/gateway_test.rb +236 -0
  57. data/test/models/workarea/payment/authorize/paypal_test.rb +57 -46
  58. data/test/models/workarea/payment/capture/paypal_test.rb +9 -51
  59. data/test/models/workarea/payment/null_address_test.rb +53 -0
  60. data/test/models/workarea/payment/refund/paypal_test.rb +39 -38
  61. data/test/models/workarea/paypal_payment_test.rb +65 -0
  62. data/test/models/workarea/search/paypal_order_text_test.rb +14 -0
  63. data/test/services/workarea/paypal/approve_order_test.rb +35 -0
  64. data/test/services/workarea/paypal/create_order_test.rb +127 -0
  65. data/test/services/workarea/paypal/update_order_test.rb +73 -0
  66. data/test/support/workarea/paypal_setup.rb +49 -0
  67. data/test/system/workarea/storefront/cart_system_test.decorator +1 -1
  68. data/test/system/workarea/storefront/logged_in_checkout_system_test.decorator +1 -1
  69. data/test/vcr_cassettes/paypal_approve_order.yml +106 -0
  70. data/test/vcr_cassettes/paypal_create_order.yml +110 -0
  71. data/test/vcr_cassettes/paypal_gateway_create_order.yml +105 -0
  72. data/test/vcr_cassettes/paypal_gateway_generate_token.yml +103 -0
  73. data/test/vcr_cassettes/paypal_gateway_get_order.yml +103 -0
  74. data/test/vcr_cassettes/paypal_gateway_update_order.yml +199 -0
  75. data/test/vcr_cassettes/paypal_gateway_webhooks.yml +403 -0
  76. data/test/vcr_cassettes/paypal_update_order.yml +204 -0
  77. data/test/workers/workarea/paypal/handle_webhook_event_test.rb +60 -0
  78. data/workarea-paypal.gemspec +2 -1
  79. metadata +64 -13
  80. data/app/services/workarea/paypal/setup.rb +0 -114
  81. data/app/services/workarea/paypal/update.rb +0 -69
  82. data/app/views/workarea/storefront/checkouts/_paypal_error.html.haml +0 -6
  83. data/app/views/workarea/storefront/order_mailer/tenders/_paypal.text.haml +0 -2
  84. data/test/dummy/config/initializers/session_store.rb +0 -3
  85. data/test/integration/workarea/storefront/place_order_integration_test.decorator +0 -11
  86. data/test/models/workarea/payment/purchase/paypal_test.rb +0 -94
  87. data/test/models/workarea/payment_test.decorator +0 -34
  88. data/test/models/workarea/search/admin/order_test.decorator +0 -32
  89. data/test/services/workarea/paypal/setup_test.rb +0 -120
  90. data/test/services/workarea/paypal/update_test.rb +0 -221
@@ -0,0 +1,21 @@
1
+ module Workarea
2
+ module Paypal
3
+ module Requests
4
+ class CreateWebhook
5
+ attr_accessor :path, :body, :headers, :verb
6
+
7
+ def initialize
8
+ @headers = {}
9
+ @body = nil
10
+ @verb = "POST"
11
+ @path = "/v1/notifications/webhooks"
12
+ @headers["Content-Type"] = "application/json"
13
+ end
14
+
15
+ def request_body(body)
16
+ @body = body
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module Workarea
2
+ module Paypal
3
+ module Requests
4
+ class DeleteWebhook
5
+ attr_accessor :path, :body, :headers, :verb
6
+
7
+ def initialize(id)
8
+ @headers = {}
9
+ @body = nil
10
+ @verb = "DELETE"
11
+ @path = "/v1/notifications/webhooks/#{id}"
12
+ @headers["Content-Type"] = "application/json"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Workarea
2
+ module Paypal
3
+ module Requests
4
+ class GenerateToken
5
+ attr_accessor :path, :body, :headers, :verb
6
+
7
+ def initialize
8
+ @headers = {}
9
+ @body = nil
10
+ @verb = "POST"
11
+ @path = "/v1/identity/generate-token"
12
+ @headers["Content-Type"] = "application/json"
13
+ end
14
+
15
+ def request_body(body)
16
+ @body = body
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module Workarea
2
+ module Paypal
3
+ module Requests
4
+ class ListWebhooks
5
+ attr_accessor :path, :body, :headers, :verb
6
+
7
+ def initialize
8
+ @headers = {}
9
+ @body = nil
10
+ @verb = "GET"
11
+ @path = "/v1/notifications/webhooks"
12
+ @headers["Content-Type"] = "application/json"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,5 @@
1
1
  module Workarea
2
2
  module Paypal
3
- VERSION = '2.0.10'.freeze
3
+ VERSION = '3.0.4'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,9 @@
1
+ {
2
+ "devDependencies": {
3
+ "eslint": "~5.16.0",
4
+ "eslint-config-recommended": "~4.0.0",
5
+ "stylelint": "~10.1.0",
6
+ "stylelint-config-recommended-scss": "~3.3.0",
7
+ "stylelint-scss": "~3.9.2"
8
+ }
9
+ }
@@ -1,5 +1,5 @@
1
1
  Workarea.configure do |config|
2
2
  # Basic site info
3
- config.site_name = 'Workarea Workarea3 Plugin'
3
+ config.site_name = 'Workarea Paypal Plugin'
4
4
  config.host = 'www.example.com'
5
5
  end
@@ -0,0 +1,70 @@
1
+ {
2
+ "id": "WH-58D329510W468432D-8HN650336L201105X",
3
+ "event_version": "1.0",
4
+ "create_time": "2019-02-14T21:50:07.940Z",
5
+ "resource_type": "capture",
6
+ "resource_version": "2.0",
7
+ "event_type": "PAYMENT.CAPTURE.COMPLETED",
8
+ "summary": "Payment completed for $ 5.00 USD",
9
+ "resource": {
10
+ "id": "CAPTURE001",
11
+ "amount": {
12
+ "currency_code": "USD",
13
+ "value": "5.00"
14
+ },
15
+ "final_capture": true,
16
+ "seller_protection": {
17
+ "status": "ELIGIBLE",
18
+ "dispute_categories": [
19
+ "ITEM_NOT_RECEIVED",
20
+ "UNAUTHORIZED_TRANSACTION"
21
+ ]
22
+ },
23
+ "seller_receivable_breakdown": {
24
+ "gross_amount": {
25
+ "currency_code": "USD",
26
+ "value": "5.00"
27
+ },
28
+ "paypal_fee": {
29
+ "currency_code": "USD",
30
+ "value": "0.73"
31
+ },
32
+ "net_amount": {
33
+ "currency_code": "USD",
34
+ "value": "4.27"
35
+ }
36
+ },
37
+ "status": "COMPLETED",
38
+ "create_time": "2019-02-14T21:49:58Z",
39
+ "update_time": "2019-02-14T21:49:58Z",
40
+ "links": [
41
+ {
42
+ "href": "https://api.paypal.com/v2/payments/captures/CAPTURE001",
43
+ "rel": "self",
44
+ "method": "GET"
45
+ },
46
+ {
47
+ "href": "https://api.paypal.com/v2/payments/captures/CAPTURE001/refund",
48
+ "rel": "refund",
49
+ "method": "POST"
50
+ },
51
+ {
52
+ "href": "https://api.paypal.com/v2/payments/authorizations/7W5147081L658180V",
53
+ "rel": "up",
54
+ "method": "GET"
55
+ }
56
+ ]
57
+ },
58
+ "links": [
59
+ {
60
+ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-58D329510W468432D-8HN650336L201105X",
61
+ "rel": "self",
62
+ "method": "GET"
63
+ },
64
+ {
65
+ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-58D329510W468432D-8HN650336L201105X/resend",
66
+ "rel": "resend",
67
+ "method": "POST"
68
+ }
69
+ ]
70
+ }
@@ -0,0 +1,68 @@
1
+ {
2
+ "id": "WH-4SW78779LY2325805-07E03580SX1414828",
3
+ "create_time": "2019-02-14T22:20:08.370Z",
4
+ "resource_type": "capture",
5
+ "event_type": "PAYMENT.CAPTURE.DENIED",
6
+ "summary": "A USD 5.00 USD capture payment was denied",
7
+ "resource": {
8
+ "amount": {
9
+ "currency_code": "USD",
10
+ "value": "5.00"
11
+ },
12
+ "seller_protection": {
13
+ "status": "ELIGIBLE",
14
+ "dispute_categories": [
15
+ "ITEM_NOT_RECEIVED",
16
+ "UNAUTHORIZED_TRANSACTION"
17
+ ]
18
+ },
19
+ "update_time": "2019-02-14T22:20:01Z",
20
+ "create_time": "2019-02-14T22:18:14Z",
21
+ "final_capture": true,
22
+ "seller_receivable_breakdown": {
23
+ "gross_amount": {
24
+ "currency_code": "USD",
25
+ "value": "5.00"
26
+ },
27
+ "net_amount": {
28
+ "currency_code": "USD",
29
+ "value": "5.00"
30
+ }
31
+ },
32
+ "links": [
33
+ {
34
+ "href": "https://api.paypal.com/v2/payments/captures/CAPTURE001",
35
+ "rel": "self",
36
+ "method": "GET"
37
+ },
38
+ {
39
+ "href": "https://api.paypal.com/v2/payments/captures/CAPTURE001/refund",
40
+ "rel": "refund",
41
+ "method": "POST"
42
+ },
43
+ {
44
+ "href": "https://api.paypal.com/v2/payments/authorizations/2W543679LP5841156",
45
+ "rel": "up",
46
+ "method": "GET"
47
+ }
48
+ ],
49
+ "id": "CAPTURE001",
50
+ "status": "DECLINED"
51
+ },
52
+ "links": [
53
+ {
54
+ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-4SW78779LY2325805-07E03580SX1414828",
55
+ "rel": "self",
56
+ "method": "GET",
57
+ "encType": "application/json"
58
+ },
59
+ {
60
+ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-4SW78779LY2325805-07E03580SX1414828/resend",
61
+ "rel": "resend",
62
+ "method": "POST",
63
+ "encType": "application/json"
64
+ }
65
+ ],
66
+ "event_version": "1.0",
67
+ "resource_version": "2.0"
68
+ }
@@ -0,0 +1,34 @@
1
+
2
+ module Workarea
3
+ module Factories
4
+ module Paypal
5
+ Factories.add(self)
6
+
7
+ def webhook_capture_completed_payload
8
+ JSON.parse(File.read(webhook_capture_completed_path))
9
+ end
10
+
11
+ def webhook_capture_completed_path
12
+ Workarea::Paypal::Engine.root.join(
13
+ 'test',
14
+ 'factories',
15
+ 'workarea',
16
+ 'capture_completed_webhook.json'
17
+ )
18
+ end
19
+
20
+ def webhook_capture_denied_payload
21
+ JSON.parse(File.read(webhook_capture_denied_path))
22
+ end
23
+
24
+ def webhook_capture_denied_path
25
+ Workarea::Paypal::Engine.root.join(
26
+ 'test',
27
+ 'factories',
28
+ 'workarea',
29
+ 'capture_denied_webhook.json'
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Storefront
5
+ class PaypalHelperTest < ViewTest
6
+ include PaypalSetup
7
+
8
+ def test_include_paypal_javascript_tag
9
+ Workarea.config.paypal_sdk_params = {
10
+ commit: false,
11
+ debug: true
12
+ }
13
+
14
+ result = include_paypal_javascript_tag
15
+ assert_includes(result, 'commit=false')
16
+ assert_includes(result, 'debug=true')
17
+ assert_includes(result, "client-id=#{Workarea::Paypal.gateway.client_id}")
18
+ assert_includes(result, 'components=buttons')
19
+ assert_includes(result, 'data-partner-attribution-id="Workarea_SP"')
20
+ refute_includes(result, 'hosted-fields')
21
+ refute_includes(result, 'data-client-token')
22
+
23
+ Workarea.config.use_paypal_hosted_fields = true
24
+ result = include_paypal_javascript_tag(
25
+ params: { foo: 'bar' },
26
+ data: { baz: 'qux' }
27
+ )
28
+
29
+ assert_includes(result, 'foo=bar')
30
+ assert_includes(result, 'data-baz="qux"')
31
+ assert_includes(result, 'components=buttons%2Chosted-fields')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -3,346 +3,156 @@ require 'test_helper'
3
3
  module Workarea
4
4
  module Storefront
5
5
  class PaypalIntengrationTest < Workarea::IntegrationTest
6
- delegate :gateway, to: Workarea::Paypal
6
+ def assert_paypal_create_order
7
+ Paypal::CreateOrder.any_instance.expects(:perform)
8
+ .returns(OpenStruct.new(id: 'test123'))
9
+ end
10
+
11
+ def assert_paypal_approve_order
12
+ Paypal::ApproveOrder.any_instance.expects(:perform).returns(true)
13
+ end
14
+
15
+ def product
16
+ @product ||= create_product(
17
+ variants: [{ sku: 'SKU1', regular: 6.to_m, tax_code: '001' }]
18
+ )
19
+ end
7
20
 
8
- setup :stub_paypal_setup_redirect_url
21
+ def add_item_to_cart
22
+ post storefront.cart_items_path, params: {
23
+ product_id: product.id,
24
+ sku: product.skus.first,
25
+ quantity: 2
26
+ }
27
+ end
9
28
 
10
- def test_start_starts_checkout_when_guest
29
+ def test_create_starts_checkout_when_guest
11
30
  add_item_to_cart
12
31
  Workarea::Checkout.any_instance.expects(:start_as).with(:guest)
13
- get storefront.start_paypal_path
32
+ assert_paypal_create_order
33
+
34
+ post storefront.paypal_path, xhr: true
14
35
  end
15
36
 
16
- def test_start_starts_checkout_when_logged_in
37
+ def test_create_starts_checkout_when_logged_in
17
38
  add_item_to_cart
18
- user = User.new
19
39
 
20
- Workarea::Storefront::PaypalController
21
- .any_instance
22
- .stubs(:current_user)
23
- .returns(user)
40
+ user = create_user(email: 'test@workarea.com')
41
+ set_current_user(user)
24
42
 
25
43
  Workarea::Checkout.any_instance.expects(:start_as).with(user)
26
- get storefront.start_paypal_path
44
+ assert_paypal_create_order
45
+
46
+ post storefront.paypal_path, xhr: true
27
47
  end
28
48
 
29
- def test_start_does_not_start_checkout_from_checkout
49
+ def test_create_does_not_start_checkout_from_checkout
30
50
  add_item_to_cart
51
+ Workarea::Order.last.touch_checkout!
52
+
31
53
  Workarea::Checkout.any_instance.expects(:start_as).never
54
+ assert_paypal_create_order
32
55
 
33
- get storefront.start_paypal_path, params: { from_checkout: 'from_checkout' }
56
+ post storefront.paypal_path, xhr: true
34
57
  end
35
58
 
36
- def test_start_prices_the_order
59
+ def test_create_success
37
60
  add_item_to_cart
38
- Workarea::Pricing.expects(:perform)
39
61
 
40
- get storefront.start_paypal_path
41
- end
62
+ assert_paypal_create_order
42
63
 
43
- def test_start_uses_setup_to_redirect
44
- add_item_to_cart
45
- get storefront.start_paypal_path
46
- assert_redirected_to('http://paypal.com')
47
- end
64
+ post storefront.paypal_path, xhr: true
48
65
 
49
- def test_start_redirects_to_cart_if_empty
50
- get storefront.start_paypal_path
51
- assert_redirected_to(storefront.cart_path)
66
+ json = JSON.parse(response.body)
67
+ assert(json['id'].present?)
52
68
  end
53
69
 
54
- def test_start_rdirects_to_cart_if_inventory_is_not_available
55
- product = create_product(variants: [{ sku: 'SKU', regular: 5 }])
70
+ def test_create_on_existing_paypal_order
71
+ add_item_to_cart
56
72
 
57
- post storefront.cart_items_path, params: {
58
- product_id: product.id,
59
- sku: product.skus.first,
60
- quantity: 1
61
- }
73
+ order = Order.carts.last
74
+ order.touch_checkout!
62
75
 
63
- create_inventory(
64
- id: product.skus.first,
65
- policy: 'standard',
66
- available: 0
67
- )
76
+ payment = Payment.find_or_initialize_by(id: order.id)
77
+ payment.build_paypal(paypal_id: '0987', approved: true)
78
+ payment.save!
68
79
 
69
- get storefront.start_paypal_path
70
- assert_redirected_to(storefront.cart_path)
71
- end
80
+ Paypal::CreateOrder.any_instance.expects(:perform).never
72
81
 
73
- def test_complete_sets_the_current_order
74
- add_item_to_cart
75
- stub_paypal_update_apply
76
- Workarea::Storefront::PaypalController
77
- .any_instance
78
- .expects(:current_order=)
79
- get storefront.complete_paypal_path(order_id: order.id)
80
- end
82
+ post storefront.paypal_path, xhr: true
81
83
 
82
- def test_complete_applies_a_paupal_update
83
- add_item_to_cart
84
- Workarea::Paypal::Update
85
- .any_instance
86
- .expects(:apply)
87
-
88
- get storefront.complete_paypal_path(order_id: order.id)
84
+ json = JSON.parse(response.body)
85
+ assert_equal('0987', json['id'])
86
+ refute(payment.reload.paypal.approved?)
89
87
  end
90
88
 
91
- def test_complete_redirects_to_checkout_path
89
+ def test_create_failure
92
90
  add_item_to_cart
93
- stub_paypal_update_apply
94
- Workarea::Checkout
95
- .any_instance
96
- .stubs(:complete?)
97
- .returns(true)
98
- get storefront.complete_paypal_path(order_id: order.id)
99
- assert_redirected_to(storefront.checkout_payment_path)
100
- end
101
91
 
102
- def test_complete_redirects_to_payment_as_purchasable
103
- shipping_method = create_shipping_service
104
- product = create_product(variants: [{ sku: 'SKU', regular: 49.to_m }])
92
+ Paypal::CreateOrder.any_instance.expects(:perform).raises(
93
+ Paypal::Gateway::RequestError.new('failed')
94
+ )
105
95
 
106
- post storefront.cart_items_path, params: {
107
- product_id: product.id,
108
- sku: product.skus.first,
109
- quantity: 2
110
- }
96
+ post storefront.paypal_path, xhr: true
111
97
 
112
- order = Workarea::Order.last
113
-
114
- Workarea::Shipping.find_or_create_by(id: order.id)
115
- Workarea::Payment.find_or_create_by(id: order.id)
116
-
117
- checkout = Workarea::Checkout.new(order)
118
- checkout.update(
119
- shipping_address: {
120
- first_name: 'Test',
121
- last_name: 'User',
122
- street: '1 Main St',
123
- street_2: nil,
124
- city: 'San Jose',
125
- region: 'CA',
126
- postal_code: '95131',
127
- country: 'US'
128
- },
129
- billing_address: {
130
- first_name: 'Test',
131
- last_name: 'User',
132
- street: '1 Main St',
133
- street_2: nil,
134
- city: 'San Jose',
135
- region: 'CA',
136
- postal_code: '95131',
137
- country: 'US'
138
- },
139
- shipping_method_id: shipping_method.id,
140
- payment: 'paypal'
141
- )
98
+ assert_equal(500, response.status)
99
+ assert(flash[:error].present?)
100
+ end
142
101
 
143
- gateway.expects(:details_for).returns(details)
102
+ def test_update_success
103
+ add_item_to_cart
144
104
 
145
- get storefront.complete_paypal_path(order_id: order.id)
105
+ PaypalController.any_instance.expects(:check_inventory).returns(true)
106
+ Paypal::ApproveOrder.any_instance.expects(:perform).returns(true)
107
+ Workarea::Checkout.any_instance.expects(:complete?).returns(true)
146
108
 
147
- assert_redirected_to(storefront.checkout_payment_path)
148
- end
109
+ put storefront.paypal_approved_path('1234'), xhr: true
149
110
 
150
- def test_complete_redirects_to_address_if_paypal_address_invalid
151
- Workarea.with_config do |config|
152
- config.allow_shipping_address_po_box = false
153
-
154
- details.params['PaymentDetails']['ShipToAddress'] = {
155
- 'Name' => 'Test User',
156
- 'Street1' => 'PO Box 123',
157
- 'Street2' => nil,
158
- 'CityName' => 'San Jose',
159
- 'StateOrProvince' => 'CA',
160
- 'Country' => 'US',
161
- 'CountryName' => 'United States',
162
- 'Phone' => '610-867-5309',
163
- 'PostalCode' => '95131',
164
- 'AddressID' => nil,
165
- 'AddressOwner' => 'PayPal',
166
- 'ExternalAddressID' => nil,
167
- 'AddressStatus' => 'Confirmed'
168
- }
169
-
170
- gateway.expects(:details_for).returns(details)
171
-
172
- product = create_product(variants: [{ sku: 'SKU', regular: 5 }])
173
-
174
- post storefront.cart_items_path, params: {
175
- product_id: product.id,
176
- sku: product.skus.first,
177
- quantity: 1
178
- }
179
-
180
- order = Order.first
181
-
182
- get storefront.complete_paypal_path(order_id: order.id)
183
- assert_redirected_to(storefront.checkout_addresses_path)
184
- end
111
+ json = JSON.parse(response.body)
112
+ assert(json['success'])
113
+ assert_equal(storefront.checkout_payment_path, json['redirect_url'])
185
114
  end
186
115
 
187
- private
116
+ def test_update_failure
117
+ add_item_to_cart
188
118
 
189
- def order
190
- @order ||= create_order
191
- end
119
+ PaypalController.any_instance.expects(:check_inventory).returns(true)
120
+ Paypal::ApproveOrder.any_instance.expects(:perform).returns(true)
121
+ Workarea::Checkout.any_instance.expects(:complete?).returns(false)
122
+
123
+ put storefront.paypal_approved_path('1234'), xhr: true
124
+
125
+ json = JSON.parse(response.body)
126
+ refute(json['success'])
127
+ assert(flash[:error].present?)
128
+ end
129
+
130
+ def test_events
131
+ payment = create_payment(paypal: { paypal_id: '123', approved: true }).tap do |p|
132
+ p.paypal.build_transaction(
133
+ action: 'authorize',
134
+ amount: 5.to_m,
135
+ response: ActiveMerchant::Billing::Response.new(
136
+ true,
137
+ 'PayPal capture succeeded',
138
+ id: 'CAPTURE001',
139
+ status: 'PENDING'
140
+ )
141
+ ).save!
142
+ end
192
143
 
193
- def product
194
- @product ||= create_product(
195
- variants: [{ sku: 'SKU1', regular: 6.to_m, tax_code: '001' }]
196
- )
197
- end
144
+ post storefront.paypal_event_path,
145
+ params: webhook_capture_completed_payload
198
146
 
199
- def details
200
- @details ||= stub(
201
- email: 'bcrouse@workarea.com',
202
- token: 'EC-3LX76108SH791964A',
203
- payer_id: 'MDJZZYJ9SZJ52',
204
- params: {
205
- 'timestamp' => '2012-02-16T15:22:17Z',
206
- 'ack' => 'Success',
207
- 'correlation_id' => 'e5e29daee048a',
208
- 'version' => '62.0',
209
- 'build' => '2571254',
210
- 'token' => 'EC-3LX76108SH791964A',
211
- 'payer' => 'bcrouse@workarea.com',
212
- 'payer_id' => 'MDJZZYJ9SZJ52',
213
- 'payer_status' => 'verified',
214
- 'salutation' => nil,
215
- 'first_name' => 'Test',
216
- 'middle_name' => nil,
217
- 'last_name' => 'User',
218
- 'suffix' => nil,
219
- 'payer_country' => 'US',
220
- 'payer_business' => nil,
221
- 'name' => 'Test Product 866',
222
- 'street1' => '1 Main St',
223
- 'street2' => nil,
224
- 'city_name' => 'San Jose',
225
- 'state_or_province' => 'CA',
226
- 'country' => 'US',
227
- 'country_name' => 'United States',
228
- 'postal_code' => '95131',
229
- 'address_owner' => 'PayPal',
230
- 'address_status' => 'Confirmed',
231
- 'order_total' => '98.00',
232
- 'order_total_currency_id' => 'USD',
233
- 'item_total' => '98.00',
234
- 'item_total_currency_id' => 'USD',
235
- 'shipping_total' => '0.00',
236
- 'shipping_total_currency_id' => 'USD',
237
- 'handling_total' => '0.00',
238
- 'handling_total_currency_id' => 'USD',
239
- 'tax_total' => '0.00',
240
- 'tax_total_currency_id' => 'USD',
241
- 'phone' => nil,
242
- 'address_id' => nil,
243
- 'external_address_id' => nil,
244
- 'quantity' => '2',
245
- 'tax' => '0.00',
246
- 'tax_currency_id' => 'USD',
247
- 'amount' => '49.00',
248
- 'amount_currency_id' => 'USD',
249
- 'ebay_item_payment_details_item' => nil,
250
- 'insurance_total' => '0.00',
251
- 'insurance_total_currency_id' => 'USD',
252
- 'shipping_discount' => '0.00',
253
- 'shipping_discount_currency_id' => 'USD',
254
- 'insurance_option_offered' => 'false',
255
- 'seller_details' => nil,
256
- 'payment_request_id' => nil,
257
- 'order_url' => nil,
258
- 'soft_descriptor' => nil,
259
- 'checkout_status' => 'PaymentActionNotInitiated',
260
- 'Token' => 'EC-3LX76108SH791964A',
261
- 'PayerInfo' => {
262
- 'Payer' => 'bcrouse@workarea.com',
263
- 'PayerID' => 'MDJZZYJ9SZJ52',
264
- 'PayerStatus' => 'verified',
265
- 'PayerName' => {
266
- 'Salutation' => nil,
267
- 'FirstName' => 'Test',
268
- 'MiddleName' => nil,
269
- 'LastName' => 'User',
270
- 'Suffix' => nil
271
- },
272
- 'PayerCountry' => 'US',
273
- 'PayerBusiness' => nil,
274
- 'Address' => {
275
- 'Name' => 'Test User',
276
- 'Street1' => '1 Main St',
277
- 'Street2' => nil,
278
- 'CityName' => 'San Jose',
279
- 'StateOrProvince' => 'CA',
280
- 'Country' => 'US',
281
- 'CountryName' => 'United States',
282
- 'PostalCode' => '95131',
283
- 'AddressOwner' => 'PayPal',
284
- 'AddressStatus' => 'Confirmed'
285
- }
286
- },
287
- 'PaymentDetails' => {
288
- 'OrderTotal' => '98.00',
289
- 'ItemTotal' => '98.00',
290
- 'ShippingTotal' => '0.00',
291
- 'HandlingTotal' => '0.00',
292
- 'TaxTotal' => '0.00',
293
- 'ShipToAddress' => {
294
- 'Name' => 'Test User',
295
- 'Street1' => '1 Main St',
296
- 'Street2' => nil,
297
- 'CityName' => 'San Jose',
298
- 'StateOrProvince' => 'CA',
299
- 'Country' => 'US',
300
- 'CountryName' => 'United States',
301
- 'PostalCode' => '95131',
302
- 'AddressID' => nil,
303
- 'AddressOwner' => 'PayPal',
304
- 'ExternalAddressID' => nil,
305
- 'AddressStatus' => 'Confirmed'
306
- },
307
- 'PaymentDetailsItem' => {
308
- 'Name' => 'Test Product 866',
309
- 'Quantity' => '2',
310
- 'Tax' => '0.00',
311
- 'Amount' => '49.00',
312
- 'EbayItemPaymentDetailsItem' => nil
313
- },
314
- 'InsuranceTotal' => '0.00',
315
- 'ShippingDiscount' => '0.00',
316
- 'InsuranceOptionOffered' => 'false',
317
- 'SellerDetails' => nil,
318
- 'PaymentRequestID' => nil,
319
- 'OrderURL' => nil,
320
- 'SoftDescriptor' => nil
321
- },
322
- 'CheckoutStatus' => 'PaymentActionNotInitiated'
323
- }
324
- )
325
- end
147
+ assert(response.ok?)
326
148
 
327
- def add_item_to_cart
328
- post storefront.cart_items_path, params: {
329
- product_id: product.id,
330
- sku: product.skus.first,
331
- quantity: 2
332
- }
333
- end
149
+ payment.reload
334
150
 
335
- def stub_paypal_setup_redirect_url
336
- Workarea::Paypal::Setup
337
- .any_instance
338
- .stubs(:redirect_url)
339
- .returns('http://paypal.com')
340
- end
151
+ assert_equal(2, payment.paypal.transactions.count)
341
152
 
342
- def stub_paypal_update_apply
343
- Workarea::Paypal::Update
344
- .any_instance
345
- .stubs(:apply)
153
+ txn = payment.paypal.transactions.captures.first
154
+ assert(txn.success?)
155
+ assert_equal(5.to_m, txn.amount)
346
156
  end
347
157
  end
348
158
  end