Skip to content

Commit

Permalink
Add controller tests for renewals/payments (#1209)
Browse files Browse the repository at this point in the history
# What it does

Adds a controller test for `Renewals::PaymentsController`, based heavily
on the one we have for `Signup::PaymentController`. This is a followup
to #1192, which fixed a bug but did not include tests for timing
reasons.

# Why it is important

This is a critical flow in the application, and we'd like to ensure that
it is still working as intended 😄

# Implementation notes

* There's a decent amount of duplication between
`Renewals::PaymentsController` and `Signup::PaymentController`, and the
same is true of their tests. It is looking like we may end up re-working
the payment flows as a part of upcoming work, so I opted to not do
anything too invasive at this time.

# Your bandwidth for additional changes to this PR

_Please choose one of the following to help the project maintainers
provide the appropriate level of support:_

- [x] I have the time and interest to make additional changes to this PR
based on feedback.
- [ ] I am interested in feedback but don't need to make the changes
myself.
- [ ] I don't have time or interest in making additional changes to this
work.
- [ ] Other or not sure (please describe):
  • Loading branch information
jim authored Dec 1, 2023
1 parent d0d3246 commit dc8da11
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 1 deletion.
2 changes: 1 addition & 1 deletion app/controllers/renewal/payments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def callback
end

Rails.logger.error(errors)
reset_session
session.delete(:attempts)
flash[:error] = "There was an error processing your payment. Please come into the library to complete signup."
redirect_to renewal_confirmation_url
end
Expand Down
166 changes: 166 additions & 0 deletions test/controllers/renewal/payments_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
require "test_helper"

module Renewal
class PaymentsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers

setup do
create(:agreement_document)
@member = create(:verified_member)
@membership = create(:membership, member: @member, started_at: 13.months.ago, ended_at: 1.month.ago)
create(:adjustment,
kind: Adjustment.kinds[:payment],
payment_source: Adjustment.payment_sources[:square],
amount: Money.new(50))
create(:adjustment,
adjustable: @membership,
kind: Adjustment.kinds[:membership],
amount: Money.new(-50))
sign_in @member.user
end

test "creates a checkout_url" do
mock_result = Minitest::Mock.new
mock_result.expect :success?, true
mock_result.expect :value, "https://squareup.com/checkout/12345"

mock_checkout = Minitest::Mock.new
Time.use_zone "America/Chicago" do
mock_checkout.expect :checkout_url, mock_result, [{
amount: Money.new(1200),
email: @member.email,
return_to: "http://example.com/renewal/payments/callback",
member_id: @member.id,
date: Date.current
}]

SquareCheckout.stub :new, mock_checkout do
post renewal_payments_url, params: {membership_payment_form: {amount_dollars: "12"}}
end

assert_redirected_to "https://squareup.com/checkout/12345"

assert_mock mock_result
assert_mock mock_checkout
end
end

test "fails to create a checkout_url" do
mock_result = Minitest::Mock.new
mock_result.expect :success?, false
mock_result.expect :error, [{code: "SOMETHING_WENT_WRONG"}]

mock_checkout = Minitest::Mock.new
mock_checkout.expect :checkout_url, mock_result, [Hash]

SquareCheckout.stub :new, mock_checkout do
post renewal_payments_url, params: {membership_payment_form: {amount_dollars: "12"}}
end

assert_redirected_to "http://example.com/renewal/payments/new"
follow_redirect!

assert_select ".toast-error", /There was a problem connecting to our payment processor/

assert_mock mock_result
assert_mock mock_checkout
end

test "successful callback invocation" do
mock_result = Minitest::Mock.new
mock_result.expect :success?, true
mock_result.expect :value, Money.new(1234)

mock_checkout = Minitest::Mock.new
mock_checkout.expect :fetch_transaction, mock_result, [{
member: @member,
transaction_id: "abcd1234"
}]

SquareCheckout.stub :new, mock_checkout do
assert_difference "Membership.count" => 1, "Adjustment.count" => 2 do
get callback_renewal_payments_url, params: {transactionId: "abcd1234"}
end
end

assert_redirected_to renewal_confirmation_url
assert_equal 1234, session[:amount]
refute session[:member_id]

assert_mock mock_result
assert_mock mock_checkout
end

test "failed callback invocation" do
mock_result = Minitest::Mock.new
mock_result.expect :success?, false
mock_result.expect :error, [{code: "ERROR_CODE"}]

mock_checkout = Minitest::Mock.new
mock_checkout.expect :fetch_transaction, mock_result, [Hash]

SquareCheckout.stub :new, mock_checkout do
assert_no_difference ["Membership.count", "Adjustment.count"] do
get callback_renewal_payments_url, params: {transactionId: "abcd1234"}
end
end

assert_redirected_to "http://example.com/renewal/confirmation"

follow_redirect!
assert_select ".toast-error", /There was an error processing your payment/

assert_mock mock_result
assert_mock mock_checkout
end

test "failed callback invocation by not finding a transaction" do
mock_result = Minitest::Mock.new
mock_result.expect :success?, false
mock_result.expect :error, [{code: "NOT_FOUND"}]

mock_checkout = Minitest::Mock.new
mock_checkout.expect :fetch_transaction, mock_result, [Hash]

SquareCheckout.stub :new, mock_checkout do
assert_no_difference ["Membership.count", "Adjustment.count"] do
get callback_renewal_payments_url, params: {transactionId: "abcd1234"}
end
end

assert_equal 200, response.status

assert_equal 1, session[:attempts]

assert_mock mock_result
assert_mock mock_checkout
end

test "failed callback invocation by not finding a transaction 10 times" do
11.times do |i|
mock_result = Minitest::Mock.new
mock_result.expect :success?, false
mock_result.expect :error, [{code: "NOT_FOUND"}]

mock_checkout = Minitest::Mock.new
mock_checkout.expect :fetch_transaction, mock_result, [Hash]

SquareCheckout.stub :new, mock_checkout do
get callback_renewal_payments_url, params: {transactionId: "abcd1234"}
end

assert_mock mock_result
assert_mock mock_checkout

if i < 10
assert_equal 200, response.status
assert_equal i + 1, session[:attempts]
else
assert_redirected_to "http://example.com/renewal/confirmation"
assert_match(/There was an error processing your payment/, flash[:error])
refute session[:attempts]
end
end
end
end
end

0 comments on commit dc8da11

Please sign in to comment.