Skip to content

Instantly share code, notes, and snippets.

@chrisgibson
Created October 10, 2022 16:04
Show Gist options
  • Save chrisgibson/b9d5d76b38ab75e2bf21e5a10e8b2052 to your computer and use it in GitHub Desktop.
Save chrisgibson/b9d5d76b38ab75e2bf21e5a10e8b2052 to your computer and use it in GitHub Desktop.
Rails + Stripe JS testing
<!-- app/viwes/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<%= javascript_include_tag "#{STRIPE_JS_HOST}/v3/" %>
</head>
</html>
# config/initializers/stripe.rb
unless defined? STRIPE_JS_HOST
STRIPE_JS_HOST = ENV.fetch("STRIPE_JS_HOST", "https://js.stripe.com")
end
group :test do
gem "roda"
end
# spec/support/fake_stripe.rb
# Stand-in for Stripe.js in tests.
#
# Serves up a mocked version of the Stripe.js v3 (in
# spec/support/fake_stripe/fake_stripe_v3.js) that provides the "payment"
# element.
class FakeStripe
def self.boot
Capybara::Server.new(App.freeze.app, port: server_port).tap(&:boot)
end
def self.boot_once
@boot_once ||= boot
end
def self.server_port
@server_port ||= begin
server = TCPServer.new(0)
server.addr[1]
ensure
server&.close
end
end
class App < Roda
route do |r|
r.get "v3/" do
response["Content-Type"] = "text/javascript"
response.write File.read(File.expand_path("fake_stripe/fake_stripe_v3.js", __dir__))
end
end
end
end
STRIPE_JS_HOST = "http://localhost:#{FakeStripe.server_port}"
// spec/support/fake_stripe/fale_stripe_v3.js
/* Mocked version of Stripe.js v3 for use in tests.
*
* See spec/support/fake_stripe.rb.
*/
class StripeElement {
mount(el) {
if (typeof el === 'string') {
el = document.querySelector(el)
}
el.innerHTML = '<h1>Fake Stripe v3</h1>'
}
on(event, handler) {
if (event == 'ready') {
handler()
}
}
addEventListener() {}
}
window.Stripe = () => {
return {
elements: () => {
return {
create: (type, options) => new StripeElement(),
getElement: name => new StripeElement(),
}
},
confirmPayment: ({ elements, confirmParams } = {}) => {
// success
window.location.href = confirmParams.return_url
return Promise.resolve()
// failure
// return Promise.resolve({ error: {} })
},
}
}
# spec/system/checkout_spec.rb
require "rails_helper"
RSpec.describe "Checkout", type: :system do
before do
FakeStripe.boot_once
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment