solidus_paypal_commerce_platform 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +41 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.rubocop.yml +56 -0
- data/Gemfile +33 -0
- data/LICENSE +26 -0
- data/README.md +173 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform.js +2 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform/namespace.js +1 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform/wizard.js +28 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform.js +3 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +191 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +26 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/namespace.js +1 -0
- data/app/assets/stylesheets/spree/backend/solidus_paypal_commerce_platform.css +4 -0
- data/app/assets/stylesheets/spree/frontend/solidus_paypal_commerce_platform.css +17 -0
- data/app/controllers/solidus_paypal_commerce_platform/orders_controller.rb +83 -0
- data/app/controllers/solidus_paypal_commerce_platform/payments_controller.rb +44 -0
- data/app/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb +19 -0
- data/app/controllers/solidus_paypal_commerce_platform/shipping_rates_controller.rb +31 -0
- data/app/controllers/solidus_paypal_commerce_platform/wizard_controller.rb +47 -0
- data/app/decorators/solidus_paypal_commerce_platform/remove_required_phone_from_address.rb +13 -0
- data/app/helpers/solidus_paypal_commerce_platform/button_options_helper.rb +21 -0
- data/app/jobs/solidus_paypal_commerce_platform/application_job.rb +6 -0
- data/app/jobs/solidus_paypal_commerce_platform/webhook_job.rb +22 -0
- data/app/models/solidus_paypal_commerce_platform/gateway.rb +88 -0
- data/app/models/solidus_paypal_commerce_platform/payment_method.rb +75 -0
- data/app/models/solidus_paypal_commerce_platform/payment_source.rb +27 -0
- data/app/models/solidus_paypal_commerce_platform/paypal_address.rb +81 -0
- data/app/models/solidus_paypal_commerce_platform/paypal_order.rb +107 -0
- data/app/models/solidus_paypal_commerce_platform/pricing_options.rb +9 -0
- data/app/models/solidus_paypal_commerce_platform/wizard.rb +40 -0
- data/app/overrides/spree/admin/payment_methods/form/insert_email_verification_notification.rb +9 -0
- data/app/overrides/spree/admin/payment_methods/index/insert_setup_wizards.rb +17 -0
- data/app/overrides/spree/admin/payments/log_entries/add_paypal_debug_id.rb +9 -0
- data/app/overrides/spree/orders/edit/insert_cart_buttons.rb +9 -0
- data/app/overrides/spree/payments/payment/add_paypal_email_to_payment.rb +9 -0
- data/app/overrides/spree/products/cart_form/insert_product_buttons.rb +10 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_available_to_users.html.erb +6 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_paypal_wizard.html.erb +16 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_setup_wizards.html.erb +16 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payments/_log_entries.html.erb +32 -0
- data/bin/console +17 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +18 -0
- data/bin/rake +7 -0
- data/bin/sandbox +86 -0
- data/bin/setup +8 -0
- data/codecov.yml +14 -0
- data/config/locales/en.yml +37 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20200521190038_add_paypal_commerce_platform_sources.rb +13 -0
- data/lib/generators/solidus_paypal_commerce_platform/install/install_generator.rb +38 -0
- data/lib/solidus_paypal_commerce_platform.rb +21 -0
- data/lib/solidus_paypal_commerce_platform/access_token_authorization_request.rb +21 -0
- data/lib/solidus_paypal_commerce_platform/client.rb +84 -0
- data/lib/solidus_paypal_commerce_platform/configuration.rb +64 -0
- data/lib/solidus_paypal_commerce_platform/engine.rb +45 -0
- data/lib/solidus_paypal_commerce_platform/factories.rb +14 -0
- data/lib/solidus_paypal_commerce_platform/fetch_merchant_credentials_request.rb +17 -0
- data/lib/solidus_paypal_commerce_platform/version.rb +5 -0
- data/lib/views/api/spree/api/payments/source_views/_paypal_commerce_platform.json.jbuilder +3 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_paypal_commerce_platform.html.erb +1 -0
- data/lib/views/backend/spree/admin/payments/source_views/_paypal_commerce_platform.html.erb +18 -0
- data/lib/views/backend/spree/admin/shared/preference_fields/_paypal_select.html.erb +13 -0
- data/lib/views/frontend/solidus_paypal_commerce_platform/cart/_cart_buttons.html.erb +3 -0
- data/lib/views/frontend/solidus_paypal_commerce_platform/payments/_payment.html.erb +4 -0
- data/lib/views/frontend/solidus_paypal_commerce_platform/product/_product_buttons.html.erb +3 -0
- data/lib/views/frontend/spree/checkout/payment/_paypal_commerce_platform.html.erb +13 -0
- data/lib/views/frontend/spree/orders/payment/_paypal_commerce_platform.html.erb +17 -0
- data/lib/views/frontend/spree/products/payment/_paypal_commerce_platform.html.erb +15 -0
- data/solidus_paypal_commerce_platform.gemspec +39 -0
- data/spec/features/backend/new_payment_method_spec.rb +40 -0
- data/spec/features/frontend/cart_spec.rb +38 -0
- data/spec/features/frontend/checkout_spec.rb +81 -0
- data/spec/features/frontend/product_spec.rb +79 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.COMPLETED.v2.json +121 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.PROCESSED.v2.json +121 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v1.json +50 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v2.json +72 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v1.json +50 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v2.json +68 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v1.json +51 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v2.json +63 -0
- data/spec/jobs/solidus_paypal_commerce_platform/webhook_job_spec.rb +44 -0
- data/spec/lib/solidus_paypal_commerce_platform/client_spec.rb +21 -0
- data/spec/lib/solidus_paypal_commerce_platform/configuration_spec.rb +67 -0
- data/spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb +102 -0
- data/spec/models/solidus_paypal_commerce_platform/payment_source_spec.rb +62 -0
- data/spec/models/solidus_paypal_commerce_platform/paypal_address_spec.rb +55 -0
- data/spec/models/solidus_paypal_commerce_platform/wizard_spec.rb +9 -0
- data/spec/requests/solidus_paypal_commerce_platform/orders_controller_spec.rb +36 -0
- data/spec/requests/solidus_paypal_commerce_platform/shipping_rates_controller_spec.rb +44 -0
- data/spec/requests/solidus_paypal_commerce_platform/wizard_controller_spec.rb +44 -0
- data/spec/spec_helper.rb +30 -0
- metadata +258 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'deface'
|
4
|
+
require 'spree/core'
|
5
|
+
require 'solidus_paypal_commerce_platform'
|
6
|
+
require 'solidus_webhooks'
|
7
|
+
|
8
|
+
module SolidusPaypalCommercePlatform
|
9
|
+
class Engine < Rails::Engine
|
10
|
+
include SolidusSupport::EngineExtensions
|
11
|
+
|
12
|
+
isolate_namespace SolidusPaypalCommercePlatform
|
13
|
+
|
14
|
+
engine_name 'solidus_paypal_commerce_platform'
|
15
|
+
|
16
|
+
initializer "solidus_paypal_commerce_platform.add_payment_method", after: "spree.register.payment_methods" do |app|
|
17
|
+
app.config.spree.payment_methods << SolidusPaypalCommercePlatform::PaymentMethod
|
18
|
+
SolidusPaypalCommercePlatform::PaymentMethod.allowed_admin_form_preference_types << :paypal_select
|
19
|
+
Spree::PermittedAttributes.source_attributes.concat [:paypal_order_id, :authorization_id, :paypal_email]
|
20
|
+
end
|
21
|
+
|
22
|
+
initializer "solidus_paypal_commerce_platform.add_wizard", after: "spree.register.payment_methods" do |app|
|
23
|
+
# Adding the class set below - if this is ported to core, we can remove this line.
|
24
|
+
Spree::Core::Environment.add_class_set("payment_setup_wizards")
|
25
|
+
app.config.spree.payment_setup_wizards << "SolidusPaypalCommercePlatform::Wizard"
|
26
|
+
end
|
27
|
+
|
28
|
+
initializer "solidus_paypal_commerce_platform.set_pricing_options_class" do
|
29
|
+
def (Spree::Config).pricing_options_class
|
30
|
+
SolidusPaypalCommercePlatform::PricingOptions
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
initializer "solidus_paypal_commerce_platform.webhooks" do
|
35
|
+
SolidusWebhooks.config.register_webhook_handler :solidus_paypal_commerce_platform, ->(payload) {
|
36
|
+
SolidusPaypalCommercePlatform::WebhooksJob.perform_now(payload)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
# use rspec for tests
|
41
|
+
config.generators do |g|
|
42
|
+
g.test_framework :rspec
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FactoryBot.define do
|
4
|
+
factory :paypal_payment_method, class: 'SolidusPaypalCommercePlatform::PaymentMethod' do
|
5
|
+
type { "SolidusPaypalCommercePlatform::PaymentMethod" }
|
6
|
+
name { "PayPal Payment Method" }
|
7
|
+
preferences {
|
8
|
+
{
|
9
|
+
client_id: SecureRandom.hex(8),
|
10
|
+
client_secret: SecureRandom.hex(10)
|
11
|
+
}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusPaypalCommercePlatform
|
4
|
+
# https://developer.paypal.com/docs/api/partner-referrals/v1/#merchant-integration_credentials
|
5
|
+
class FetchMerchantCredentialsRequest
|
6
|
+
attr_accessor :verb, :path, :headers, :body
|
7
|
+
|
8
|
+
def initialize(partner_merchant_id:, access_token:)
|
9
|
+
@verb = "GET"
|
10
|
+
@path = "/v1/customer/partners/#{partner_merchant_id}/merchant-integrations/credentials"
|
11
|
+
@headers = {
|
12
|
+
"Content-Type" => "application/json",
|
13
|
+
"Authorization" => "Bearer #{access_token}"
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= t('virtual_terminal_notice_html') %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<fieldset data-hook="credit_card">
|
2
|
+
<legend align="center"><%= SolidusPaypalCommercePlatform::PaymentMethod.model_name.human %></legend>
|
3
|
+
|
4
|
+
<div class="row">
|
5
|
+
<div class="alpha six columns">
|
6
|
+
<dl>
|
7
|
+
<dt><%= I18n.t("spree.identifier") %>:</dt>
|
8
|
+
<dd><%= payment.number %></dd>
|
9
|
+
|
10
|
+
<dt><%= I18n.t("paypal_capture_id") %>:</dt>
|
11
|
+
<dd><%= payment.source.capture_id %></dd>
|
12
|
+
|
13
|
+
<dt><%= I18n.t("paypal_email") %>:</dt>
|
14
|
+
<dd><%= payment.source.paypal_email %></dd>
|
15
|
+
</dl>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</fieldset>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<% label = local_assigns[:label].presence %>
|
2
|
+
<% html_options = {class: 'custom-select fullwidth'}.update(local_assigns[:html_options] || {}) %>
|
3
|
+
<% options = @object.send("#{attribute}_options") %>
|
4
|
+
|
5
|
+
<div class="field">
|
6
|
+
<% if local_assigns[:form] %>
|
7
|
+
<%= form.label attribute, label %>
|
8
|
+
<%= form.select attribute, options, {}, html_options %>
|
9
|
+
<% else %>
|
10
|
+
<%= label_tag name, label %>
|
11
|
+
<%= select_tag name, value, html_options %>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<% Spree::PaymentMethod.available_to_users.select{ |payment_method| payment_method.try(:display_on_product_page) }.each do |payment_method| %>
|
2
|
+
<%= render partial: "spree/products/payment/#{payment_method.product_page_partial_name}", locals: {payment_method: payment_method} %>
|
3
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<script src="<%= payment_method.javascript_sdk_url(order: @order) %>"></script>
|
2
|
+
|
3
|
+
<div id="paypal-button-container"></div>
|
4
|
+
<input type="hidden" name="payment_source[<%= payment_method.id %>][paypal_order_id]" id="payments_source_paypal_order_id">
|
5
|
+
<input type="hidden" name="payment_source[<%= payment_method.id %>][paypal_email]" id="payments_source_paypal_email">
|
6
|
+
|
7
|
+
<script>
|
8
|
+
$( document ).ready(function() {
|
9
|
+
SolidusPaypalCommercePlatform.renderButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
|
10
|
+
})
|
11
|
+
</script>
|
12
|
+
|
13
|
+
<div id="paypal_commerce_platform_overlay"></div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div style="margin-left:auto;margin-right:auto;width:50%;margin-top:20px;">
|
2
|
+
<script src="<%= payment_method.javascript_sdk_url(order: @order) %>">
|
3
|
+
</script>
|
4
|
+
|
5
|
+
<div id="paypal-button-container"></div>
|
6
|
+
|
7
|
+
<script>
|
8
|
+
Spree.current_order_id = "<%= @order.number %>"
|
9
|
+
Spree.current_order_token = "<%= @order.guest_token %>"
|
10
|
+
SolidusPaypalCommercePlatform.checkout_url = "<%= checkout_url %>"
|
11
|
+
$( document ).ready(function() {
|
12
|
+
SolidusPaypalCommercePlatform.renderCartButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
|
13
|
+
})
|
14
|
+
</script>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div id="paypal_commerce_platform_overlay"></div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<div style="margin-top:20px;">
|
2
|
+
<script src="<%= payment_method.javascript_sdk_url %>">
|
3
|
+
</script>
|
4
|
+
|
5
|
+
<div id="paypal-button-container"></div>
|
6
|
+
|
7
|
+
<script>
|
8
|
+
SolidusPaypalCommercePlatform.checkout_url = "<%= checkout_url %>"
|
9
|
+
$( document ).ready(function() {
|
10
|
+
SolidusPaypalCommercePlatform.renderProductButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
|
11
|
+
})
|
12
|
+
</script>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div id="paypal_commerce_platform_overlay"></div>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/solidus_paypal_commerce_platform/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'solidus_paypal_commerce_platform'
|
7
|
+
spec.version = SolidusPaypalCommercePlatform::VERSION
|
8
|
+
spec.authors = ['Sean Denny', 'Elia Schito']
|
9
|
+
spec.email = 'contact@solidus.io'
|
10
|
+
|
11
|
+
spec.summary = 'Integrate Solidus with Paypal Commerce Platform'
|
12
|
+
spec.homepage = 'https://github.com/nebulab/solidus_paypal_commerce_platform#readme'
|
13
|
+
spec.license = 'BSD-3-Clause'
|
14
|
+
|
15
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
16
|
+
spec.metadata['source_code_uri'] = 'https://github.com/nebulab/solidus_paypal_commerce_platform'
|
17
|
+
spec.metadata['changelog_uri'] = 'https://github.com/nebulab/solidus_paypal_commerce_platform/releases'
|
18
|
+
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new('~> 2.5')
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") }
|
24
|
+
|
25
|
+
spec.files = files.grep_v(%r{^(test|spec|features)/})
|
26
|
+
spec.test_files = files.grep(%r{^(test|spec|features)/})
|
27
|
+
spec.bindir = "exe"
|
28
|
+
spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
|
31
|
+
spec.add_dependency 'deface', '~> 1.5'
|
32
|
+
spec.add_dependency 'solidus_core', ['>= 2.0.0', '< 3']
|
33
|
+
spec.add_dependency 'solidus_support', '~> 0.5'
|
34
|
+
spec.add_dependency 'solidus_webhooks', '~> 0.2.0'
|
35
|
+
|
36
|
+
spec.add_dependency 'paypal-checkout-sdk'
|
37
|
+
|
38
|
+
spec.add_development_dependency 'solidus_dev_support'
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "creating a new payment" do
|
4
|
+
stub_authorization!
|
5
|
+
|
6
|
+
it "displays PayPal Commerce Platform as an option" do
|
7
|
+
visit "/admin/payment_methods/new"
|
8
|
+
expect(page).to have_select('payment_method_type', options: [
|
9
|
+
"PayPal Commerce Platform",
|
10
|
+
"Bogus Credit Card Payments",
|
11
|
+
"Check Payments",
|
12
|
+
"Simple Bogus Credit Card Payments",
|
13
|
+
"Store Credit Payments",
|
14
|
+
])
|
15
|
+
select "PayPal Commerce Platform", from: 'payment_method_type'
|
16
|
+
fill_in "Name", with: "PayPal!"
|
17
|
+
click_on "Create"
|
18
|
+
expect(page).to have_text("Payment Method has been successfully created!")
|
19
|
+
|
20
|
+
fill_in "Client", with: "cli-123"
|
21
|
+
fill_in "Client secret", with: "cli-sec-123"
|
22
|
+
click_on "Update"
|
23
|
+
expect(page).to have_text("Payment Method has been successfully updated!")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "displays the onboarding button", :js do
|
27
|
+
visit "/admin/payment_methods"
|
28
|
+
|
29
|
+
# main_window = current_window
|
30
|
+
|
31
|
+
within ".setup-wizard" do
|
32
|
+
paypal_button = page.find("button")
|
33
|
+
expect(paypal_button.text).to eq("Setup PayPal Commerce Platform")
|
34
|
+
# TODO: make this more complete
|
35
|
+
# paypal_window = window_opened_by do
|
36
|
+
# paypal_button.click
|
37
|
+
# end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "Cart page" do
|
4
|
+
describe "paypal payment method" do
|
5
|
+
let(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:address) }
|
6
|
+
let(:paypal_payment_method) { create(:paypal_payment_method) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
user = create(:user)
|
10
|
+
order.user = user
|
11
|
+
|
12
|
+
paypal_payment_method
|
13
|
+
allow_any_instance_of(Spree::OrdersController).to receive_messages(
|
14
|
+
current_order: order,
|
15
|
+
try_spree_current_user: user
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def paypal_script_options
|
20
|
+
script_tag_url = URI(page.find('script[src*="sdk/js?"]', visible: false)[:src])
|
21
|
+
script_tag_url.query.split('&')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "generate a js file with the correct credentials and intent attached" do
|
25
|
+
visit '/cart'
|
26
|
+
expect(paypal_script_options).to include("client-id=#{paypal_payment_method.preferences[:client_id]}")
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when auto-capture is set to true" do
|
30
|
+
it "generate a js file with intent capture" do
|
31
|
+
paypal_payment_method.update(auto_capture: true)
|
32
|
+
visit '/cart'
|
33
|
+
expect(paypal_script_options).to include("client-id=#{paypal_payment_method.preferences[:client_id]}")
|
34
|
+
expect(paypal_script_options).to include("intent=capture")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "Checkout" do
|
4
|
+
describe "paypal payment method" do
|
5
|
+
let(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:payment) }
|
6
|
+
let(:paypal_payment_method) { create(:paypal_payment_method) }
|
7
|
+
let(:failed_response) { OpenStruct.new(status_code: 500) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
user = create(:user)
|
11
|
+
order.user = user
|
12
|
+
order.recalculate
|
13
|
+
|
14
|
+
paypal_payment_method
|
15
|
+
allow_any_instance_of(Spree::CheckoutController).to receive_messages(
|
16
|
+
current_order: order, try_spree_current_user: user
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def paypal_script_options
|
21
|
+
script_tag_url = URI(page.find('script[src*="sdk/js?"]', visible: false)[:src])
|
22
|
+
script_tag_url.query.split('&')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "generates a js file with the correct credentials and intent attached" do
|
26
|
+
visit '/checkout/payment'
|
27
|
+
expect(paypal_script_options).to include("client-id=#{paypal_payment_method.preferences[:client_id]}")
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when auto-capture is set to true" do
|
31
|
+
it "generates a js file with intent capture" do
|
32
|
+
paypal_payment_method.update(auto_capture: true)
|
33
|
+
visit '/checkout/payment'
|
34
|
+
expect(paypal_script_options).to include("client-id=#{paypal_payment_method.preferences[:client_id]}")
|
35
|
+
expect(paypal_script_options).to include("intent=capture")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when no payment has been made" do
|
40
|
+
it "fails to process" do
|
41
|
+
visit '/checkout/payment'
|
42
|
+
choose(option: paypal_payment_method.id)
|
43
|
+
click_button("Save and Continue")
|
44
|
+
expect(page).to have_content("Payments source PayPal order can't be blank")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when a payment has been made" do
|
49
|
+
it "proceeds to the next step" do
|
50
|
+
visit '/checkout/payment'
|
51
|
+
choose(option: paypal_payment_method.id)
|
52
|
+
find(:xpath, "//input[@id='payments_source_paypal_order_id']", visible: false).set SecureRandom.hex(8)
|
53
|
+
click_button("Save and Continue")
|
54
|
+
expect(page).to have_css(".current", text: "Confirm")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "records the paypal email address" do
|
58
|
+
visit '/checkout/payment'
|
59
|
+
choose(option: paypal_payment_method.id)
|
60
|
+
find(:xpath, "//input[@id='payments_source_paypal_order_id']", visible: false).set SecureRandom.hex(8)
|
61
|
+
find(:xpath, "//input[@id='payments_source_paypal_email']", visible: false).set "fake@email.com"
|
62
|
+
click_button("Save and Continue")
|
63
|
+
expect(Spree::Payment.last.source.paypal_email).to eq "fake@email.com"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when a payment fails" do
|
68
|
+
before { allow_any_instance_of(PayPal::PayPalHttpClient).to receive(:execute) { failed_response } }
|
69
|
+
|
70
|
+
it "redirects the user back to the payments page" do
|
71
|
+
visit '/checkout/payment'
|
72
|
+
choose(option: paypal_payment_method.id)
|
73
|
+
find(:xpath, "//input[@id='payments_source_paypal_order_id']", visible: false).set SecureRandom.hex(8)
|
74
|
+
click_button("Save and Continue")
|
75
|
+
click_button("Place Order")
|
76
|
+
expect(page).to have_current_path("/checkout/payment")
|
77
|
+
expect(page).to have_content("Your payment was declined")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "Product page", js: true do
|
4
|
+
describe "paypal button" do
|
5
|
+
let(:paypal_payment_method) { create(:paypal_payment_method) }
|
6
|
+
let(:product) { create(:product, variants: [variant, variant_two]) }
|
7
|
+
let(:store) { create(:store) }
|
8
|
+
let(:variant) { create(:variant) }
|
9
|
+
let(:variant_two) { create(:variant) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
paypal_payment_method
|
13
|
+
end
|
14
|
+
|
15
|
+
def paypal_script_options
|
16
|
+
script_tag_url = URI(page.find('script[src*="sdk/js?"]', visible: false)[:src])
|
17
|
+
script_tag_url.query.split('&')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "generates a js file with the correct credentials and intent attached" do
|
21
|
+
visit '/products/' + product.slug
|
22
|
+
expect(paypal_script_options).to include("client-id=#{paypal_payment_method.preferences[:client_id]}")
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when auto-capture is set to true" do
|
26
|
+
it "generates a js file with intent capture" do
|
27
|
+
paypal_payment_method.update(auto_capture: true)
|
28
|
+
visit '/products/' + product.slug
|
29
|
+
expect(paypal_script_options).to include("client-id=#{paypal_payment_method.preferences[:client_id]}")
|
30
|
+
expect(paypal_script_options).to include("intent=capture")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "order creation" do
|
35
|
+
before do
|
36
|
+
allow_any_instance_of(Spree::Core::ControllerHelpers::Store).to receive(:current_store) { store }
|
37
|
+
visit '/products/' + product.slug
|
38
|
+
|
39
|
+
# Stubbing out paypal methods since their JS doesn't load in correctly on tests
|
40
|
+
page.execute_script("paypal = {}")
|
41
|
+
page.execute_script("paypal.render = function(){}")
|
42
|
+
page.execute_script("paypal.Buttons = function(){return paypal}")
|
43
|
+
|
44
|
+
# Waiting until the paypal button becomes available, because the SPCP namespace
|
45
|
+
# isn't immediately available
|
46
|
+
page.find("#paypal-button-container")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "creates an order successfully" do
|
50
|
+
page.evaluate_script("SolidusPaypalCommercePlatform.createOrder()")
|
51
|
+
|
52
|
+
expect(Spree::Order.last).not_to be nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it "sets the Spree number and token variables" do
|
56
|
+
page.evaluate_script("SolidusPaypalCommercePlatform.createOrder()")
|
57
|
+
|
58
|
+
expect(page.evaluate_script("Spree.current_order_id")).to eq Spree::Order.last.number
|
59
|
+
expect(page.evaluate_script("Spree.current_order_token")).to eq Spree::Order.last.guest_token
|
60
|
+
end
|
61
|
+
|
62
|
+
it "uses the specified quantity" do
|
63
|
+
quantity = 12
|
64
|
+
fill_in('quantity', with: quantity)
|
65
|
+
|
66
|
+
page.evaluate_script("SolidusPaypalCommercePlatform.createOrder()")
|
67
|
+
|
68
|
+
expect(Spree::Order.last.line_items.first.quantity).to eq quantity
|
69
|
+
end
|
70
|
+
|
71
|
+
it "uses the selected variant" do
|
72
|
+
page.choose("variant_id_#{variant_two.id}")
|
73
|
+
page.evaluate_script("SolidusPaypalCommercePlatform.createOrder()")
|
74
|
+
|
75
|
+
expect(Spree::Order.last.line_items.first.variant_id).to eq variant_two.id
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|