Skip to content

Commit 469b6d6

Browse files
committed
test: updates tests
1 parent c57bcc8 commit 469b6d6

File tree

6 files changed

+164
-112
lines changed

6 files changed

+164
-112
lines changed

src/Apps/Order2/Routes/Checkout/Components/CheckoutModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const CheckoutModal: React.FC<{
3333
let canReload = false
3434
let canDismiss = false
3535

36-
let defaultTitle = "Checkout Error"
36+
let defaultTitle = "Checkout error"
3737
let defaultDescription: string
3838

3939
switch (error) {

src/Apps/Order2/Routes/Checkout/Components/ExpressCheckout/__tests__/Order2ExpressCheckoutUI.jest.tsx

Lines changed: 132 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { flushPromiseQueue } from "DevTools/flushPromiseQueue"
66
import { setupTestWrapperTL } from "DevTools/setupTestWrapperTL"
77
import type { Order2ExpressCheckoutUI_Test_Query } from "__generated__/Order2ExpressCheckoutUI_Test_Query.graphql"
88
import { useEffect } from "react"
9-
import React from "react"
109
import { graphql } from "react-relay"
1110
import { useTracking } from "react-tracking"
1211
import { Order2ExpressCheckoutUI } from "../Order2ExpressCheckoutUI"
@@ -644,45 +643,19 @@ describe("ExpressCheckoutUI", () => {
644643
})
645644
})
646645

647-
it("displays error when there is an error", async () => {
648-
const mockErrorRef = { current: "test_error_code" }
649-
jest.spyOn(React, "useRef").mockReturnValue(mockErrorRef)
646+
it("does not track cancel event when there is an existing error", async () => {
647+
// Set up a pre-existing error in context (e.g. from a failed payment)
648+
mockMessages.EXPRESS_CHECKOUT = {
649+
error: { title: "An error occurred", message: "Something went wrong" } as any,
650+
}
651+
mockCheckoutContext.messages = { ...mockMessages }
650652

651-
const { mockResolveLastOperation } = renderWithRelay({
652-
Order: () => ({ ...orderData }),
653-
})
653+
renderWithRelay({ Order: () => ({ ...orderData }) })
654654

655655
fireEvent.click(screen.getByTestId("express-checkout-cancel"))
656656

657-
// Resolve the mutations
658-
await mockResolveLastOperation({
659-
unsetOrderPaymentMethodPayload: () => ({
660-
orderOrError: {
661-
__typename: "OrderMutationSuccess",
662-
order: orderData,
663-
},
664-
}),
665-
})
666-
667-
await mockResolveLastOperation({
668-
unsetOrderFulfillmentOptionPayload: () => ({
669-
orderOrError: {
670-
__typename: "OrderMutationSuccess",
671-
order: orderData,
672-
},
673-
}),
674-
})
675-
676-
await flushPromiseQueue()
677-
678-
// Verify error was set for the express checkout section
679-
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith(
680-
expect.objectContaining({
681-
section: "EXPRESS_CHECKOUT",
682-
error: expect.objectContaining({
683-
title: "An error occurred",
684-
}),
685-
}),
657+
expect(trackEvent).not.toHaveBeenCalledWith(
658+
expect.objectContaining({ action: "clickedCancelExpressCheckout" }),
686659
)
687660
})
688661
})
@@ -729,89 +702,157 @@ describe("ExpressCheckoutUI", () => {
729702
expect(window.location.reload).not.toHaveBeenCalled()
730703
})
731704

732-
describe("Error message handling by error code", () => {
733-
it("shows payment failed message for backend processing errors", async () => {
734-
const mockErrorRef = { current: "create_credit_card_failed" }
735-
jest.spyOn(React, "useRef").mockReturnValue(mockErrorRef)
705+
describe("Error handling", () => {
706+
describe("handleSubmitError", () => {
707+
it("sets a 'not available' error when insufficient inventory", async () => {
708+
const stripeModule = jest.requireMock("@stripe/react-stripe-js")
709+
stripeModule.useElements.mockReturnValueOnce({
710+
submit: jest.fn(async () => ({
711+
error: {
712+
code: "insufficient_inventory",
713+
message: "Artwork unavailable",
714+
},
715+
})),
716+
update: mockElementsUpdate,
717+
})
736718

737-
const { mockResolveLastOperation } = renderWithRelay({
738-
Order: () => ({ ...orderData }),
739-
})
719+
renderWithRelay({ Order: () => ({ ...orderData }) })
740720

741-
fireEvent.click(screen.getByTestId("express-checkout-cancel"))
721+
fireEvent.click(screen.getByTestId("express-checkout-confirm"))
722+
await flushPromiseQueue()
742723

743-
// Resolve the mutations
744-
await mockResolveLastOperation({
745-
unsetOrderPaymentMethodPayload: () => ({
746-
orderOrError: {
747-
__typename: "OrderMutationSuccess",
748-
order: orderData,
724+
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith({
725+
section: "EXPRESS_CHECKOUT",
726+
error: {
727+
title: "Not available",
728+
message: "Sorry, the work is no longer available.",
729+
code: "insufficient_inventory",
749730
},
750-
}),
731+
})
751732
})
752733

753-
await mockResolveLastOperation({
754-
unsetOrderFulfillmentOptionPayload: () => ({
755-
orderOrError: {
756-
__typename: "OrderMutationSuccess",
757-
order: orderData,
734+
it("sets a payment processing error when charge authorization fails", async () => {
735+
const stripeModule = jest.requireMock("@stripe/react-stripe-js")
736+
stripeModule.useElements.mockReturnValueOnce({
737+
submit: jest.fn(async () => ({
738+
error: {
739+
code: "charge_authorization_failed",
740+
message: "Your card was declined",
741+
},
742+
})),
743+
update: mockElementsUpdate,
744+
})
745+
746+
renderWithRelay({ Order: () => ({ ...orderData }) })
747+
748+
fireEvent.click(screen.getByTestId("express-checkout-confirm"))
749+
await flushPromiseQueue()
750+
751+
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith({
752+
section: "EXPRESS_CHECKOUT",
753+
error: {
754+
title: "An error occurred while processing your payment",
755+
message: "Your card was declined",
756+
code: "charge_authorization_failed",
758757
},
759-
}),
758+
})
760759
})
761760

762-
await flushPromiseQueue()
761+
it("sets a generic error for unhandled submit error codes", async () => {
762+
const stripeModule = jest.requireMock("@stripe/react-stripe-js")
763+
stripeModule.useElements.mockReturnValueOnce({
764+
submit: jest.fn(async () => ({
765+
error: {
766+
code: "unexpected_error",
767+
message: "Something went wrong",
768+
},
769+
})),
770+
update: mockElementsUpdate,
771+
})
763772

764-
// Verify error was set for the express checkout section with payment failed message
765-
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith(
766-
expect.objectContaining({
773+
renderWithRelay({ Order: () => ({ ...orderData }) })
774+
775+
fireEvent.click(screen.getByTestId("express-checkout-confirm"))
776+
await flushPromiseQueue()
777+
778+
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith({
767779
section: "EXPRESS_CHECKOUT",
768780
error: expect.objectContaining({
769-
title: "Payment failed",
781+
title: "An error occurred",
782+
code: "unexpected_error",
770783
}),
771-
}),
772-
)
784+
})
785+
})
773786
})
774787

775-
it("shows fallback message for unhandled errors", async () => {
776-
const mockErrorRef = { current: "unknown_error" }
777-
jest.spyOn(React, "useRef").mockReturnValue(mockErrorRef)
788+
it("sets an error and calls reject when handleShippingAddressChange fails", async () => {
789+
const mockReject = jest.fn()
790+
const mockResolve = jest.fn()
778791

779-
const { mockResolveLastOperation } = renderWithRelay({
792+
const { mockRejectLastOperation } = renderWithRelay({
780793
Order: () => ({ ...orderData }),
781794
})
782795

783-
fireEvent.click(screen.getByTestId("express-checkout-cancel"))
796+
const elementProps = mockExpressCheckoutElement.mock.calls[0][0]
784797

785-
// Resolve the mutations
786-
await mockResolveLastOperation({
787-
unsetOrderPaymentMethodPayload: () => ({
788-
orderOrError: {
789-
__typename: "OrderMutationSuccess",
790-
order: orderData,
791-
},
792-
}),
798+
elementProps.onShippingAddressChange({
799+
address: {
800+
city: "New York",
801+
state: "NY",
802+
country: "US",
803+
postal_code: "10013",
804+
},
805+
name: "Buyer Name",
806+
resolve: mockResolve,
807+
reject: mockReject,
793808
})
794809

795-
await mockResolveLastOperation({
796-
unsetOrderFulfillmentOptionPayload: () => ({
797-
orderOrError: {
798-
__typename: "OrderMutationSuccess",
799-
order: orderData,
800-
},
810+
await flushPromiseQueue()
811+
812+
mockRejectLastOperation(new Error("Network error"))
813+
814+
await flushPromiseQueue()
815+
816+
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith({
817+
section: "EXPRESS_CHECKOUT",
818+
error: expect.objectContaining({
819+
title: "An error occurred",
820+
code: "shipping_address_update_error",
801821
}),
802822
})
823+
expect(mockReject).toHaveBeenCalled()
824+
})
825+
826+
it("sets an error and calls reject when handleShippingRateChange fails", async () => {
827+
const mockReject = jest.fn()
828+
const mockResolve = jest.fn()
829+
830+
const { mockRejectLastOperation } = renderWithRelay({
831+
Order: () => ({ ...orderData }),
832+
})
833+
834+
const elementProps = mockExpressCheckoutElement.mock.calls[0][0]
835+
836+
elementProps.onShippingRateChange({
837+
shippingRate: { id: "DOMESTIC_FLAT", amount: 4200 },
838+
resolve: mockResolve,
839+
reject: mockReject,
840+
})
803841

804842
await flushPromiseQueue()
805843

806-
// Verify error was set for the express checkout section with fallback message
807-
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith(
808-
expect.objectContaining({
809-
section: "EXPRESS_CHECKOUT",
810-
error: expect.objectContaining({
811-
title: "An error occurred",
812-
}),
844+
mockRejectLastOperation(new Error("Network error"))
845+
846+
await flushPromiseQueue()
847+
848+
expect(mockSetSectionErrorMessage).toHaveBeenCalledWith({
849+
section: "EXPRESS_CHECKOUT",
850+
error: expect.objectContaining({
851+
title: "An error occurred",
852+
code: "shipping_rate_update_error",
813853
}),
814-
)
854+
})
855+
expect(mockReject).toHaveBeenCalled()
815856
})
816857
})
817858
})

src/Apps/Order2/Routes/Checkout/Components/__tests__/CriticalErrorModal.jest.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe("CriticalErrorModal", () => {
4444
it("shows the loading timeout message with reload button", () => {
4545
render(<CheckoutModal error={CheckoutModalError.LOADING_TIMEOUT} />)
4646

47-
expect(screen.getByText("Checkout Error")).toBeInTheDocument()
47+
expect(screen.getByText("Checkout error")).toBeInTheDocument()
4848
expect(
4949
screen.getByText("There was an error loading your checkout."),
5050
).toBeInTheDocument()
@@ -126,7 +126,7 @@ describe("CriticalErrorModal", () => {
126126
it("shows the default error message without reload button", () => {
127127
render(<CheckoutModal error={CheckoutModalError.OTHER_ERROR} />)
128128

129-
expect(screen.getByText("Checkout Error")).toBeInTheDocument()
129+
expect(screen.getByText("Checkout error")).toBeInTheDocument()
130130
expect(
131131
screen.getByText(
132132
"There was an error with your checkout. Please return to the artwork and try again.",
@@ -184,11 +184,17 @@ describe("CriticalErrorModal", () => {
184184
})
185185
})
186186

187-
describe("stripe_error error", () => {
187+
describe("CHARGE_AUTHORIZATION_FAILED error", () => {
188188
it("shows payment authentication error message with Continue button", () => {
189-
render(<CheckoutModal error={CheckoutModalError.CHARGE_AUTHORIZATION_FAILED} />)
189+
render(
190+
<CheckoutModal
191+
error={CheckoutModalError.CHARGE_AUTHORIZATION_FAILED}
192+
/>,
193+
)
190194

191-
expect(screen.getByText("An error occurred")).toBeInTheDocument()
195+
expect(
196+
screen.getByText("An error occurred while processing your payment"),
197+
).toBeInTheDocument()
192198
expect(
193199
screen.getByText(
194200
"We are unable to authenticate your payment method. Please choose a different payment method and try again.",
@@ -199,7 +205,11 @@ describe("CriticalErrorModal", () => {
199205
})
200206

201207
it("dismisses modal when Continue button is clicked", async () => {
202-
render(<CheckoutModal error={CheckoutModalError.CHARGE_AUTHORIZATION_FAILED} />)
208+
render(
209+
<CheckoutModal
210+
error={CheckoutModalError.CHARGE_AUTHORIZATION_FAILED}
211+
/>,
212+
)
203213

204214
const continueButton = screen.getByText("Continue")
205215
await userEvent.click(continueButton)
@@ -209,7 +219,11 @@ describe("CriticalErrorModal", () => {
209219
})
210220

211221
it("dismisses modal when X button is clicked", async () => {
212-
render(<CheckoutModal error={CheckoutModalError.CHARGE_AUTHORIZATION_FAILED} />)
222+
render(
223+
<CheckoutModal
224+
error={CheckoutModalError.CHARGE_AUTHORIZATION_FAILED}
225+
/>,
226+
)
213227

214228
const closeButton = screen.getByLabelText("Close")
215229
await userEvent.click(closeButton)

src/Apps/Order2/Routes/Checkout/Components/__tests__/Order2ReviewStep.jest.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,6 @@ describe("Order2ReviewStep", () => {
503503
await waitFor(() => {
504504
expect(mockCheckoutModal.showCheckoutErrorModal).toHaveBeenCalledWith({
505505
error: CheckoutModalError.CHARGE_AUTHORIZATION_FAILED,
506-
title: "An error occurred while processing your payment",
507506
description: "Authentication failed",
508507
onClose: expect.any(Function),
509508
})
@@ -599,7 +598,6 @@ describe("Order2ReviewStep", () => {
599598
await waitFor(() => {
600599
expect(mockCheckoutModal.showCheckoutErrorModal).toHaveBeenCalledWith({
601600
error: CheckoutModalError.CHARGE_AUTHORIZATION_FAILED,
602-
title: "An error occurred while processing your payment",
603601
description: "Authentication failed",
604602
onClose: expect.any(Function),
605603
})
@@ -637,7 +635,6 @@ describe("Order2ReviewStep", () => {
637635
await waitFor(() => {
638636
expect(mockCheckoutModal.showCheckoutErrorModal).toHaveBeenCalledWith({
639637
error: CheckoutModalError.CHARGE_AUTHORIZATION_FAILED,
640-
title: "An error occurred while processing your payment",
641638
description: "Some other error",
642639
onClose: expect.any(Function),
643640
})

0 commit comments

Comments
 (0)