Merge pull request #5202 from luisramos0/improve_checkout_js

Improve Checkout error handling in JS
This commit is contained in:
Luis Ramos
2020-04-15 22:25:05 +01:00
committed by GitHub
2 changed files with 64 additions and 13 deletions

View File

@@ -14,15 +14,28 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE
submit: =>
Loading.message = t 'submitting_order'
$http.put('/checkout.json', {order: @preprocess()}).success (data, status)=>
Navigation.go data.path
.error (response, status)=>
if response.path
Navigation.go response.path
else
Loading.clear()
@errors = response.errors
RailsFlashLoader.loadFlash(response.flash)
$http.put('/checkout.json', {order: @preprocess()})
.then (response) =>
Navigation.go response.data.path
.catch (response) =>
try
@handle_checkout_error_response(response)
catch error
@loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error
throw error # generate a BugsnagJS alert
handle_checkout_error_response: (response) =>
if response.data.path
Navigation.go response.data.path
else
throw response unless response.data.flash
@errors = response.data.errors
@loadFlash(response.data.flash)
loadFlash: (flash) =>
Loading.clear()
RailsFlashLoader.loadFlash(flash)
# Rails wants our Spree::Address data to be provided with _attributes
preprocess: ->

View File

@@ -3,10 +3,13 @@ describe 'Checkout service', ->
orderData = null
$httpBackend = null
Navigation = null
navigationSpy = null
flash = null
scope = null
FlashLoaderMock =
loadFlash: (arg)->
loadFlash: (arg) ->
Loading =
clear: (arg)->
paymentMethods = [{
id: 99
test: "foo"
@@ -48,6 +51,7 @@ describe 'Checkout service', ->
module 'Darkswarm'
module ($provide)->
$provide.value "RailsFlashLoader", FlashLoaderMock
$provide.value "Loading", Loading
$provide.value "currentOrder", orderData
$provide.value "shippingMethods", shippingMethods
$provide.value "paymentMethods", paymentMethods
@@ -61,7 +65,7 @@ describe 'Checkout service', ->
scope.Checkout = Checkout
Navigation = $injector.get("Navigation")
flash = $injector.get("flash")
spyOn(Navigation, "go") # Stubbing out writes to window.location
navigationSpy = spyOn(Navigation, "go") # Stubbing out writes to window.location
it "defaults to no shipping method", ->
expect(Checkout.order.shipping_method_id).toEqual null
@@ -116,12 +120,46 @@ describe 'Checkout service', ->
$httpBackend.flush()
expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith {error: "frogs"}
it "puts errors into the scope", ->
$httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "frogs"}}
it "puts errors into the scope when there is a flash messages", ->
$httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "frogs"}, flash: {error: "flash frogs"}}
Checkout.submit()
$httpBackend.flush()
expect(Checkout.errors).toEqual {error: "frogs"}
it "throws exception and sends generic flash message when there are errors but no flash message", ->
$httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "broken response"}}
try
Checkout.submit()
$httpBackend.flush()
catch error
expect(error.data.errors.error).toBe("broken response")
expect(Checkout.errors).toEqual {}
it "throws an exception and sends a flash message to the flash service when reponse doesnt contain errors nor a flash message", ->
spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location
$httpBackend.expectPUT("/checkout.json").respond 400, "broken response"
try
Checkout.submit()
$httpBackend.flush()
catch error
expect(error.data).toBe("broken response")
expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") })
it "throws an exception and sends a flash message to the flash service when an exception is thrown while handling the error", ->
spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location
navigationSpy.and.callFake(-> throw "unexpected error")
$httpBackend.expectPUT("/checkout.json").respond 400, {path: 'path'}
try
Checkout.submit()
$httpBackend.flush()
catch error
expect(error).toBe("unexpected error")
expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") })
describe "when using the Stripe Connect gateway", ->
beforeEach inject ($injector, StripeElements) ->
Checkout.order.payment_method_id = 666