-
Notifications
You must be signed in to change notification settings - Fork 582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(EMI-2112): failed payment order history #10839
Conversation
src/app/utils/getOrderStatus.ts
Outdated
case "PAYMENT_FAILED": | ||
return "payment failed" | ||
default: | ||
return "unknown" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1: Need to check where else this function is used to make sure this text won't render in an unexpected place.
2: The 'unknown' text feels not ideal. I considered suppressing it on the OrderHistoryRow and just rendering no status in those cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to the second part. I do think that not displaying anything if state is not known is better than displaying 'unknown' which just look like a bug to me :)
6c34604
to
cd17866
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. Only had couple of neat picky comments here. Though def defer to our app specialists to weight in on best practices.
const hasFailedPayment = orderStatus === "payment failed" | ||
const isActive = | ||
!hasFailedPayment && | ||
orderStatus && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting as I believe looking at getOrderStatus
below that orderStatus will always be present as there is a default value. So checking it seems redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, at first I was returning null
as the default instead of unknown. Then decided that was out of scope since we are handling all of the known cases, so best to leave it as I found it.
: "black60" | ||
|
||
const hasFailedPayment = orderStatus === "payment failed" | ||
const isActive = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#minor - think this isActive is a bit misleading now as it controls if we are showing the link. And we are showing the button in more cases now just a different button. Maybe something more descriptive as showDetailsButton
and showPaymentUpdateButton
?
const isActive = | ||
!hasFailedPayment && | ||
orderStatus && | ||
!(["canceled", "refunded"] as string[]).includes(orderStatus) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we are doing it array style here maybe we can just include payment failed
here?
> | ||
{orderStatus} | ||
</Text> | ||
{!!orderStatus && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would make sense if orderStatus could possibly be nil, but don't think is a valid pass now. Though I also think that not displaying anything for status is better than displaying the word 'unknown'
variant="fillDark" | ||
onPress={() => | ||
navigate(`/orders/${order.internalID}/payment/new`, { | ||
modal: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting that there are modals in the app. Did not even know those exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a style of system-level navigation where instead of adding a view to a stack you are popping up a single web view that acts independently.
src/app/utils/getOrderStatus.ts
Outdated
case "PAYMENT_FAILED": | ||
return "payment failed" | ||
default: | ||
return "unknown" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to the second part. I do think that not displaying anything if state is not known is better than displaying 'unknown' which just look like a bug to me :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! 🌟 I just added a few comments
renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
|
||
expect(tree.queryByTestId("artist-names")?.children[0]).toBe("Torbjørn Rødland") | ||
expect(screen.getByTestId("artist-names")).toHaveTextContent("Torbjørn Rødland") | ||
}) | ||
|
||
it("displays the partner name", () => { | ||
const tree = renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
|
||
expect(tree.queryByTestId("partner-name")?.children[0]).toBe("Andrea Festa Fine Art") | ||
expect(screen.getByTestId("partner-name")).toHaveTextContent("Andrea Festa Fine Art") | ||
}) | ||
|
||
it("displays the order creation date", () => { | ||
const tree = renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
|
||
expect(tree.queryByTestId("date")?.children[0]).toBe("5/18/2021") | ||
expect(screen.queryByTestId("date")).toHaveTextContent("5/18/2021") | ||
}) | ||
|
||
it("displays the price", () => { | ||
const tree = renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
|
||
expect(tree.queryByTestId("price")?.children[0]).toBe("11,200") | ||
expect(screen.getByTestId("price")).toHaveTextContent("11,200") | ||
}) | ||
|
||
it("displays the display state", () => { | ||
const tree = renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
renderWithRelay({ CommerceOrder: () => mockOrder }) | ||
|
||
expect(tree.queryByTestId("order-status")?.children[0]).toBe("pending") | ||
expect(screen.getByTestId("order-status")).toHaveTextContent("pending") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for refactoring this! 🙏
const isActive = | ||
!hasFailedPayment && | ||
orderStatus && | ||
!(["canceled", "refunded"] as string[]).includes(orderStatus) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: do we need the type casting as string[]
here?
> | ||
{orderStatus} | ||
</Text> | ||
{!!orderStatus && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will always return true, since getOrderStatus
always returns a string that is not empty, maybe we could change the getOrderStatus
return to give back null
or an empty string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the checks like this are because I was returning null
at first, then decided not to mess with it. I'll take a closer look and see if that looks safe in the other places we use it.
@@ -1,6 +1,6 @@ | |||
import { CommerceOrderDisplayStateEnum } from "__generated__/OrderDetailsHeader_info.graphql" | |||
|
|||
export function getOrderStatus(displayState: CommerceOrderDisplayStateEnum) { | |||
export function getOrderStatus(displayState: CommerceOrderDisplayStateEnum): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Do we need the type for the return type to be string
? I believe Typescript infers a type based on the returning value of the function on its own
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another relic of when I added types because it was string | null
- when I changed it I also changed the types.
@erikdstock can we also test these changes on Android and add screenshots? |
I did test them on android - will see if i can get some screenshots together after responding to feedback |
- clean up linter errors in test
a63ceef
to
019047b
Compare
Co-authored-by: Sultan Al-Maari <[email protected]>
This PR resolves EMI-2112
Description
This PR adds a
payment failed
state to the order history along with a CTA to fix the failed payment. The work to expose that new payment failed state is still in progress, so there are no user-facing changes yet.The
getOrderStatus()
method now returns astring | null
rather than the string'unknown'
. Unhandled (null) values are not rendered in the app - this should never happen.PR Checklist
📱Order history (failed payment state simulated)
📱After clicking CTA
To the reviewers 👀
Changelog updates
Changelog updates
Cross-platform user-facing changes
iOS user-facing changes
Android user-facing changes
Dev changes
Need help with something? Have a look at our docs, or get in touch with us.