Files
danbooru/test/functional/webhooks_controller_test.rb
evazion d0bb4ed398 user upgrades: add bank payment methods for European countries.
Add the following bank redirect payment methods:

* https://stripe.com/docs/payments/bancontact
* https://stripe.com/docs/payments/eps
* https://stripe.com/docs/payments/giropay
* https://stripe.com/docs/payments/ideal
* https://stripe.com/docs/payments/p24

These methods are used in Austria, Belgium, Germany, the Netherlands,
and Poland.

These methods require payments to be denominated in EUR, which means we
have to set prices in both USD and EUR, and we have to automatically
detect which currency to use based on the user's country. We also have
to automatically detect which payment methods to offer based on the
user's country. We do this by using Cloudflare's CF-IPCountry header to
geolocate the user's country.

This also switches to using prices and products defined in Stripe
instead of generated on-the-fly when creating the checkout.
2020-12-31 06:50:10 -06:00

152 lines
5.6 KiB
Ruby

require 'test_helper'
class WebhooksControllerTest < ActionDispatch::IntegrationTest
setup do
StripeMock.start
end
teardown do
StripeMock.stop
end
def post_webhook(*args, payment_status: "paid", **metadata)
event = StripeMock.mock_webhook_event(*args, payment_status: payment_status, metadata: metadata)
signature = generate_stripe_signature(event)
headers = { "Stripe-Signature": signature }
post receive_webhooks_path(source: "stripe"), headers: headers, params: event, as: :json
end
# https://github.com/stripe-ruby-mock/stripe-ruby-mock/issues/467#issuecomment-634674913
# https://stripe.com/docs/webhooks/signatures
def generate_stripe_signature(event)
time = Time.now
secret = UserUpgrade.stripe_webhook_secret
signature = Stripe::Webhook::Signature.compute_signature(time, event.to_json, secret)
Stripe::Webhook::Signature.generate_header(time, signature, scheme: Stripe::Webhook::Signature::EXPECTED_SCHEME)
end
context "The webhooks controller" do
context "receive action" do
context "for a request from an unrecognized source" do
should "fail" do
post receive_webhooks_path(source: "blah")
assert_response 400
end
end
context "for a Stripe webhook" do
context "with a missing signature" do
should "fail" do
event = StripeMock.mock_webhook_event("payment_intent.created")
post receive_webhooks_path(source: "stripe"), params: event, as: :json
assert_response 400
end
end
context "with an invalid signature" do
should "fail" do
event = StripeMock.mock_webhook_event("payment_intent.created")
headers = { "Stripe-Signature": "blah" }
post receive_webhooks_path(source: "stripe"), headers: headers, params: event, as: :json
assert_response 400
end
end
context "for a payment_intent.created event" do
should "work" do
post_webhook("payment_intent.created")
assert_response 200
end
end
context "for a checkout.session.completed event" do
context "for completed event with an unpaid payment status" do
should "not upgrade the user" do
@user_upgrade = create(:self_gold_upgrade)
post_webhook("checkout.session.completed", { user_upgrade_id: @user_upgrade.id, payment_status: "unpaid" })
assert_response 200
assert_equal("processing", @user_upgrade.reload.status)
assert_equal(User::Levels::MEMBER, @user_upgrade.recipient.reload.level)
end
end
context "for a self upgrade" do
context "to Gold" do
should "upgrade the user" do
@user_upgrade = create(:self_gold_upgrade)
post_webhook("checkout.session.completed", { user_upgrade_id: @user_upgrade.id })
assert_response 200
assert_equal("complete", @user_upgrade.reload.status)
assert_equal(User::Levels::GOLD, @user_upgrade.recipient.reload.level)
end
end
context "to Platinum" do
should "upgrade the user" do
@user_upgrade = create(:self_platinum_upgrade)
post_webhook("checkout.session.completed", { user_upgrade_id: @user_upgrade.id })
assert_response 200
assert_equal("complete", @user_upgrade.reload.status)
assert_equal(User::Levels::PLATINUM, @user_upgrade.recipient.reload.level)
end
end
context "from Gold to Platinum" do
should "upgrade the user" do
@user_upgrade = create(:self_gold_to_platinum_upgrade)
post_webhook("checkout.session.completed", { user_upgrade_id: @user_upgrade.id })
assert_response 200
assert_equal("complete", @user_upgrade.reload.status)
assert_equal(User::Levels::PLATINUM, @user_upgrade.recipient.reload.level)
end
end
end
context "for a gifted upgrade" do
context "to Gold" do
should "upgrade the user" do
@user_upgrade = create(:gift_gold_upgrade)
post_webhook("checkout.session.completed", { user_upgrade_id: @user_upgrade.id })
assert_response 200
assert_equal("complete", @user_upgrade.reload.status)
assert_equal(User::Levels::GOLD, @user_upgrade.recipient.reload.level)
end
end
context "to Platinum" do
should "upgrade the user" do
@user_upgrade = create(:gift_platinum_upgrade)
post_webhook("checkout.session.completed", { user_upgrade_id: @user_upgrade.id })
assert_response 200
assert_equal("complete", @user_upgrade.reload.status)
assert_equal(User::Levels::PLATINUM, @user_upgrade.recipient.reload.level)
end
end
context "from Gold to Platinum" do
should "upgrade the user" do
@user_upgrade = create(:gift_gold_to_platinum_upgrade)
post_webhook("checkout.session.completed", { user_upgrade_id: @user_upgrade.id })
assert_response 200
assert_equal("complete", @user_upgrade.reload.status)
assert_equal(User::Levels::PLATINUM, @user_upgrade.recipient.reload.level)
end
end
end
end
end
end
end
end