mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
CheckoutController can render payment gateway error messages as json
This commit is contained in:
@@ -12,7 +12,7 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeJ
|
||||
|
||||
submit: =>
|
||||
Loading.message = t 'submitting_order'
|
||||
$http.put('/checkout', {order: @preprocess()}).success (data, status)=>
|
||||
$http.put('/checkout.json', {order: @preprocess()}).success (data, status)=>
|
||||
Navigation.go data.path
|
||||
.error (response, status)=>
|
||||
if response.path
|
||||
|
||||
@@ -48,7 +48,7 @@ class CheckoutController < Spree::CheckoutController
|
||||
format.html do
|
||||
respond_with(@order, :location => order_path(@order))
|
||||
end
|
||||
format.js do
|
||||
format.json do
|
||||
render json: {path: order_path(@order)}, status: 200
|
||||
end
|
||||
end
|
||||
@@ -141,7 +141,7 @@ class CheckoutController < Spree::CheckoutController
|
||||
format.html do
|
||||
render :edit
|
||||
end
|
||||
format.js do
|
||||
format.json do
|
||||
render json: {errors: @order.errors, flash: flash.to_hash}.to_json, status: 400
|
||||
end
|
||||
end
|
||||
@@ -222,4 +222,12 @@ class CheckoutController < Spree::CheckoutController
|
||||
params[:order][:payments_attributes].first.delete :source_attributes
|
||||
end
|
||||
end
|
||||
|
||||
def rescue_from_spree_gateway_error(error)
|
||||
flash[:error] = t(:spree_gateway_error_flash_for_checkout, error: error.message)
|
||||
respond_to do |format|
|
||||
format.html { render :edit }
|
||||
format.json { render json: { flash: flash.to_hash }, status: 400 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -766,6 +766,10 @@ en:
|
||||
require_login_html: "Please %{login} if you have an account already. Otherwise, %{register} to become a customer."
|
||||
require_customer_html: "Please %{contact} %{enterprise} to become a customer."
|
||||
|
||||
|
||||
# Front-end controller translations
|
||||
spree_gateway_error_flash_for_checkout: "There was a problem with your payment information: %{error}"
|
||||
|
||||
# Printable Invoice Columns
|
||||
invoice_billing_address: "Billing address:"
|
||||
invoice_column_tax: "GST"
|
||||
|
||||
@@ -69,14 +69,14 @@ describe CheckoutController do
|
||||
it "clears the ship address when re-rendering edit" do
|
||||
controller.should_receive(:clear_ship_address).and_return true
|
||||
order.stub(:update_attributes).and_return false
|
||||
spree_post :update, order: {}
|
||||
spree_post :update, format: :json, order: {}
|
||||
end
|
||||
|
||||
it "clears the ship address when the order state cannot be advanced" do
|
||||
controller.should_receive(:clear_ship_address).and_return true
|
||||
order.stub(:update_attributes).and_return true
|
||||
order.stub(:next).and_return false
|
||||
spree_post :update, order: {}
|
||||
spree_post :update, format: :json, order: {}
|
||||
end
|
||||
|
||||
it "only clears the ship address with a pickup shipping method" do
|
||||
@@ -133,7 +133,7 @@ describe CheckoutController do
|
||||
end
|
||||
|
||||
it "returns errors" do
|
||||
xhr :post, :update, order: {}, use_route: :spree
|
||||
spree_post :update, format: :json, order: {}
|
||||
response.status.should == 400
|
||||
response.body.should == {errors: assigns[:order].errors, flash: {}}.to_json
|
||||
end
|
||||
@@ -141,7 +141,7 @@ describe CheckoutController do
|
||||
it "returns flash" do
|
||||
order.stub(:update_attributes).and_return true
|
||||
order.stub(:next).and_return false
|
||||
xhr :post, :update, order: {}, use_route: :spree
|
||||
spree_post :update, format: :json, order: {}
|
||||
response.body.should == {errors: assigns[:order].errors, flash: {error: "Payment could not be processed, please check the details you entered"}}.to_json
|
||||
end
|
||||
|
||||
@@ -152,7 +152,7 @@ describe CheckoutController do
|
||||
order.stub(:update_attributes).and_return true
|
||||
order.stub(:state).and_return "complete"
|
||||
|
||||
xhr :post, :update, order: {}, use_route: :spree
|
||||
spree_post :update, format: :json, order: {}
|
||||
response.status.should == 200
|
||||
response.body.should == {path: spree.order_path(order)}.to_json
|
||||
end
|
||||
@@ -173,7 +173,7 @@ describe CheckoutController do
|
||||
true
|
||||
end
|
||||
|
||||
xhr :post, :update, order: {}, use_route: :spree
|
||||
spree_post :update, format: :json, order: {}
|
||||
response.status.should == 200
|
||||
end
|
||||
|
||||
@@ -181,7 +181,7 @@ describe CheckoutController do
|
||||
order.stub(:update_attributes).and_return true
|
||||
order.stub(:next) { raise ActiveRecord::StaleObjectError.new(Spree::Variant.new, 'update') }
|
||||
|
||||
xhr :post, :update, order: {}, use_route: :spree
|
||||
spree_post :update, format: :json, order: {}
|
||||
response.status.should == 400
|
||||
end
|
||||
end
|
||||
|
||||
@@ -91,27 +91,27 @@ describe 'Checkout service', ->
|
||||
|
||||
describe "submitting", ->
|
||||
it "Posts the Checkout to the server", ->
|
||||
$httpBackend.expectPUT("/checkout", {order: Checkout.preprocess()}).respond 200, {path: "test"}
|
||||
$httpBackend.expectPUT("/checkout.json", {order: Checkout.preprocess()}).respond 200, {path: "test"}
|
||||
Checkout.submit()
|
||||
$httpBackend.flush()
|
||||
|
||||
describe "when there is an error", ->
|
||||
it "redirects when a redirect is given", ->
|
||||
$httpBackend.expectPUT("/checkout").respond 400, {path: 'path'}
|
||||
$httpBackend.expectPUT("/checkout.json").respond 400, {path: 'path'}
|
||||
Checkout.submit()
|
||||
$httpBackend.flush()
|
||||
expect(Navigation.go).toHaveBeenCalledWith 'path'
|
||||
|
||||
it "sends flash messages to the flash service", ->
|
||||
spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location
|
||||
$httpBackend.expectPUT("/checkout").respond 400, {flash: {error: "frogs"}}
|
||||
$httpBackend.expectPUT("/checkout.json").respond 400, {flash: {error: "frogs"}}
|
||||
Checkout.submit()
|
||||
|
||||
$httpBackend.flush()
|
||||
expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith {error: "frogs"}
|
||||
|
||||
it "puts errors into the scope", ->
|
||||
$httpBackend.expectPUT("/checkout").respond 400, {errors: {error: "frogs"}}
|
||||
$httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "frogs"}}
|
||||
Checkout.submit()
|
||||
$httpBackend.flush()
|
||||
expect(Checkout.errors).toEqual {error: "frogs"}
|
||||
|
||||
@@ -14,7 +14,7 @@ describe "Submitting Stripe Connect charge requests", type: :request do
|
||||
let!(:order) { line_item.order }
|
||||
let(:address) { create(:address) }
|
||||
let(:token) { "token123" }
|
||||
let(:params) { { order: {
|
||||
let(:params) { { format: :json, order: {
|
||||
shipping_method_id: shipping_method.id,
|
||||
payments_attributes: [{payment_method_id: payment_method.id, source_attributes: { gateway_payment_profile_id: token, cc_type: "visa", last_digits: "4242", month: 10, year: 2025 }}],
|
||||
bill_address_attributes: address.attributes.slice("firstname","lastname","address1","address2","phone","city","zipcode","state_id","country_id"),
|
||||
@@ -33,12 +33,12 @@ describe "Submitting Stripe Connect charge requests", type: :request do
|
||||
# Saves the card against the user
|
||||
stub_request(:post, "https://sk_test_123456:@api.stripe.com/v1/customers")
|
||||
.with(:body => { card: token, email: order.email})
|
||||
.to_return(status: 200, body: JSON.generate({ id: "cus_A123", default_card: "card_XyZ456", sources: { data: [{id: "1"}] } }), headers: {})
|
||||
.to_return(status: 200, body: JSON.generate(store_response_mock))
|
||||
|
||||
# Requests a token from the newly saved card
|
||||
stub_request(:post, "https://api.stripe.com/v1/tokens")
|
||||
.with(:body => { card: "card_XyZ456", customer: "cus_A123"})
|
||||
.to_return(status: 200, body: JSON.generate({id: "newtoken_123"}), headers: {})
|
||||
.to_return(status: 200, body: JSON.generate({id: "newtoken_123"}))
|
||||
|
||||
# Charges the card
|
||||
stub_request(:post, "https://sk_test_123456:@api.stripe.com/v1/charges")
|
||||
@@ -46,12 +46,14 @@ describe "Submitting Stripe Connect charge requests", type: :request do
|
||||
.to_return(body: JSON.generate(charge_response_mock))
|
||||
end
|
||||
|
||||
context "and the charge request is accepted" do
|
||||
context "and the store and charge requests are accepted" do
|
||||
let(:store_response_mock) { { id: "cus_A123", default_card: "card_XyZ456", sources: { data: [{id: "1"}] } } }
|
||||
let(:charge_response_mock) { { id: "ch_1234", object: "charge", amount: 2000} }
|
||||
|
||||
it "should process the payment, and stores the card/customer details" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to redirect_to(spree.order_path(order))
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response["path"]).to eq spree.order_path(order)
|
||||
expect(order.payments.completed.count).to be 1
|
||||
card = order.payments.completed.first.source
|
||||
expect(card.gateway_customer_profile_id).to eq "cus_A123"
|
||||
@@ -59,12 +61,28 @@ describe "Submitting Stripe Connect charge requests", type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
context "when the store request returns an error message" do
|
||||
let(:store_response_mock) { { error: { message: "Bup-bow..."} } }
|
||||
let(:charge_response_mock) { { id: "ch_1234", object: "charge", amount: 2000} }
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response["flash"]["error"]).to eq I18n.t(:spree_gateway_error_flash_for_checkout, error: 'Bup-bow...')
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
end
|
||||
|
||||
context "when the charge request returns an error message" do
|
||||
let(:store_response_mock) { { id: "cus_A123", default_card: "card_XyZ456", sources: { data: [{id: "1"}] } } }
|
||||
let(:charge_response_mock) { { error: { message: "Bup-bow..."} } }
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to render_template(:edit)
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response["flash"]["error"]).to eq I18n.t(:payment_processing_failed)
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
end
|
||||
@@ -98,12 +116,25 @@ describe "Submitting Stripe Connect charge requests", type: :request do
|
||||
|
||||
it "should process the payment, and keep the profile ids" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to redirect_to(spree.order_path(order))
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response["path"]).to eq spree.order_path(order)
|
||||
expect(order.payments.completed.count).to be 1
|
||||
card = order.payments.completed.first.source
|
||||
expect(card.gateway_customer_profile_id).to eq "cus_Z456"
|
||||
expect(card.gateway_payment_profile_id).to eq "card_AbC123"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the charge request returns an error message" do
|
||||
let(:charge_response_mock) { { error: { message: "Bup-bow..."} } }
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response["flash"]["error"]).to eq I18n.t(:payment_processing_failed)
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user