Skip to content
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-2196): Consolidated global AddressFormFields component + usage in Auction/Invoice apps #14898

Merged
merged 13 commits into from
Nov 26, 2024
13 changes: 8 additions & 5 deletions src/Apps/Auction/Components/Form/AddressFormWithCreditCard.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { Join, Spacer, Text } from "@artsy/palette"
import { CreditCardInput } from "Components/CreditCardInput"
import { useFormContext } from "Apps/Auction/Hooks/useFormContext"
import { AddressForm } from "./AddressForm"
import { AddressFormFields } from "Components/Address/AddressFormFields"
import { useAuctionFormContext } from "Apps/Auction/Hooks/useAuctionFormContext"
import { AuctionFormValues } from "Apps/Auction/Components/Form/Utils/initialValues"

export const AddressFormWithCreditCard: React.FC<React.PropsWithChildren<unknown>> = () => {
export const AddressFormWithCreditCard: React.FC<React.PropsWithChildren<
unknown
>> = () => {
const {
setFieldValue,
setFieldTouched,
setFieldError,
errors,
touched,
} = useFormContext()
} = useAuctionFormContext()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this changed because the name was coming up in searches in multiple places and caused me to confuse myself. Maybe not worth it though.


return (
<Join separator={<Spacer y={2} />}>
Expand Down Expand Up @@ -44,7 +47,7 @@ export const AddressFormWithCreditCard: React.FC<React.PropsWithChildren<unknown
required
/>

<AddressForm />
<AddressFormFields<AuctionFormValues> withPhoneNumber />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here as well is the auction registration route using our new form withPhoneNumber. I wondered if i should use the schema constructor helper mentioned earlier in this tour on the formik context here but haven't done it yet.

</Join>
)
}
5 changes: 3 additions & 2 deletions src/Apps/Auction/Components/Form/ConditionsOfSaleCheckbox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Checkbox, Spacer, Text } from "@artsy/palette"
import { useFormContext } from "Apps/Auction/Hooks/useFormContext"
import { useAuctionFormContext } from "Apps/Auction/Hooks/useAuctionFormContext"

import { RouterLink } from "System/Components/RouterLink"

export const ConditionsOfSaleCheckbox: React.FC<React.PropsWithChildren<unknown>> = () => {
Expand All @@ -9,7 +10,7 @@ export const ConditionsOfSaleCheckbox: React.FC<React.PropsWithChildren<unknown>
errors,
setFieldTouched,
setFieldValue,
} = useFormContext()
} = useAuctionFormContext()

const showErrorMessage = !!(touched.agreeToTerms && errors.agreeToTerms)

Expand Down
5 changes: 3 additions & 2 deletions src/Apps/Auction/Components/Form/ErrorStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Banner, BannerProps, Flex, Text } from "@artsy/palette"
import { errorMessageForBidding } from "Apps/Auction/Components/Form/Utils/errorMessages"
import { useFormContext } from "Apps/Auction/Hooks/useFormContext"
import { useAuctionFormContext } from "Apps/Auction/Hooks/useAuctionFormContext"

import { RouterLink } from "System/Components/RouterLink"

export const ErrorStatus = () => {
const { status } = useFormContext()
const { status } = useAuctionFormContext()

if (!status) {
return null
Expand Down
4 changes: 2 additions & 2 deletions src/Apps/Auction/Components/Form/Utils/initialValues.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { FormikHelpers } from "formik"
import { Address, emptyAddress } from "Components/Address/AddressForm"
import { Address, emptyAddress } from "Components/Address/utils"

export interface AuctionFormValues {
address: Address
agreeToTerms: boolean
creditCard?: boolean
phoneNumber?: string
phoneNumber: string
selectedBid?: string
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { mount } from "enzyme"
import { AddressFormWithCreditCard } from "Apps/Auction/Components/Form/AddressFormWithCreditCard"
import { useFormContext } from "Apps/Auction/Hooks/useFormContext"
import { useAuctionFormContext } from "Apps/Auction/Hooks/useAuctionFormContext"

jest.mock("Apps/Auction/Hooks/useFormContext")
jest.mock("Apps/Auction/Hooks/useAuctionFormContext")

jest.mock("Components/CreditCardInput", () => ({
CreditCardInput: () => null,
}))
jest.mock("../AddressForm", () => ({
AddressForm: () => null,
jest.mock("Components/Address/AddressFormFields", () => ({
AddressFormFields: () => null,
}))

describe("AddressFormWithCreditCard", () => {
const mockUseFormContext = useFormContext as jest.Mock
const mockuseAuctionFormContext = useAuctionFormContext as jest.Mock
const setFieldTouched = jest.fn()
const setFieldValue = jest.fn()
const setFieldError = jest.fn()
Expand All @@ -22,7 +22,7 @@ describe("AddressFormWithCreditCard", () => {
}

beforeAll(() => {
mockUseFormContext.mockImplementation(() => {
mockuseAuctionFormContext.mockImplementation(() => {
return {
setFieldTouched,
setFieldValue,
Expand All @@ -35,7 +35,7 @@ describe("AddressFormWithCreditCard", () => {
it("renders correct components", () => {
const wrapper = getWrapper()
expect(wrapper.find("CreditCardInput")).toHaveLength(1)
expect(wrapper.find("AddressForm")).toHaveLength(1)
expect(wrapper.find("AddressFormFields")).toHaveLength(1)
})

describe("credit card error handling", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { mount } from "enzyme"
import { useFormContext } from "Apps/Auction/Hooks/useFormContext"
import { useAuctionFormContext } from "Apps/Auction/Hooks/useAuctionFormContext"

import { ConditionsOfSaleCheckbox } from "Apps/Auction/Components/Form/ConditionsOfSaleCheckbox"

jest.mock("Apps/Auction/Hooks/useFormContext")
jest.mock("Apps/Auction/Hooks/useAuctionFormContext")
jest.mock("System/Hooks/useFeatureFlag")

describe("ConditionsOfSaleCheckbox", () => {
const mockUseFormContext = useFormContext as jest.Mock
const mockuseAuctionFormContext = useAuctionFormContext as jest.Mock
const setFieldTouched = jest.fn()
const setFieldValue = jest.fn()
const formProps = {
Expand All @@ -22,13 +23,13 @@ describe("ConditionsOfSaleCheckbox", () => {
}

beforeAll(() => {
mockUseFormContext.mockImplementation(() => {
mockuseAuctionFormContext.mockImplementation(() => {
return formProps
})
})

it("shows error message if error", () => {
mockUseFormContext.mockImplementation(() => {
mockuseAuctionFormContext.mockImplementation(() => {
return {
...formProps,
touched: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { mount } from "enzyme"
import { useFormContext } from "Apps/Auction/Hooks/useFormContext"
import { useAuctionFormContext } from "Apps/Auction/Hooks/useAuctionFormContext"

import { ErrorStatus } from "Apps/Auction/Components/Form/ErrorStatus"

jest.mock("Apps/Auction/Hooks/useFormContext")
jest.mock("Apps/Auction/Hooks/useAuctionFormContext")

describe("ErrorStatus", () => {
const mockUseFormContext = useFormContext as jest.Mock
const mockuseAuctionFormContext = useAuctionFormContext as jest.Mock
let status

const getWrapper = () => {
mockUseFormContext.mockImplementation(() => {
mockuseAuctionFormContext.mockImplementation(() => {
return {
status,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { flushPromiseQueue } from "DevTools/flushPromiseQueue"
import { useAuctionTracking } from "Apps/Auction/Hooks/useAuctionTracking"
import { useRefreshUserData } from "Apps/Auction/Queries/useRefreshUserData"

jest.mock("Components/Address/AddressForm", () => ({
toStripeAddress: jest.fn(),
}))
jest.mock("Components/Address/utils", () => {
const actual = jest.requireActual("Components/Address/utils")
return { ...actual, toStripeAddress: jest.fn() }
})

jest.mock("Apps/Auction/Queries/useRefreshUserData")
jest.mock("Apps/Auction/Hooks/useAuctionTracking")
Expand All @@ -39,6 +40,7 @@ describe("useCreateTokenAndSubmit", () => {

const values = {
phoneNumber: "+1 (123) 456-7890",
address: {},
}

const helpers = {
Expand Down Expand Up @@ -252,6 +254,7 @@ describe("useCreateTokenAndSubmit", () => {
it("sets submitting to false at the very end", async () => {
await setupHook()
await flushPromiseQueue()

expect(helpers.setSubmitting).toHaveBeenCalledWith(false)
})
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AuctionFormValues } from "Apps/Auction/Components/Form/Utils/initialValues"
import { useFormikContext } from "formik"

export const useFormContext = () => {
export const useAuctionFormContext = () => {
const context = useFormikContext<AuctionFormValues>()
return context
}
17 changes: 11 additions & 6 deletions src/Apps/Auction/Hooks/useCreateTokenAndSubmit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { AuctionRegistrationRoute_me$data } from "__generated__/AuctionRegistrat
import { AuctionRegistrationRoute_sale$data } from "__generated__/AuctionRegistrationRoute_sale.graphql"
import { AuctionBidRoute_me$data } from "__generated__/AuctionBidRoute_me.graphql"
import { AuctionBidRoute_sale$data } from "__generated__/AuctionBidRoute_sale.graphql"
import { toStripeAddress } from "Components/Address/AddressForm"
import { toStripeAddress } from "Components/Address/utils"
import { useRefreshUserData } from "Apps/Auction/Queries/useRefreshUserData"
import {
errorMessageForCard,
Expand Down Expand Up @@ -80,11 +80,16 @@ export const useCreateTokenAndSubmit = ({

helpers.setSubmitting(true)

if (!values.address) {
helpers.setStatus("SUBMISSION_FAILED")
return
}
Comment on lines +83 to +86
Copy link
Contributor Author

@erikdstock erikdstock Nov 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caused a bunch of test failures [fixed here] even though I don't think it would be an issue in real life due to form validations. I only did it to satisfy some ts complaints about using the ! so we could remove it.


try {
const { error, token } = await stripe.createToken(
cardNumberElement,
toStripeAddress(values.address!)
)!
toStripeAddress(values.address)
)

if (error) {
helpers.setFieldError("creditCard", error.message)
Expand All @@ -94,16 +99,16 @@ export const useCreateTokenAndSubmit = ({
await submitAddCreditCardAndUpdateProfileMutation({
variables: {
creditCardInput: {
token: token?.id!,
token: token.id,
},
profileInput: {
phone: values.phoneNumber,
},
},
rejectIf: res => {
if (res.createCreditCard?.creditCardOrError?.mutationError) {
const mutationErrorDetail = res.createCreditCard?.creditCardOrError
?.mutationError?.detail!
const mutationErrorDetail =
res.createCreditCard.creditCardOrError.mutationError.detail

helpers.setFieldError(
"creditCard",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "__generated__/PricingTransparencyQuery.graphql"
import { useSystemContext } from "System/Hooks/useSystemContext"
import { SystemQueryRenderer } from "System/Relay/SystemQueryRenderer"
import { useFormContext } from "Apps/Auction/Hooks/useFormContext"
import { useAuctionFormContext } from "Apps/Auction/Hooks/useAuctionFormContext"

import {
Text,
Expand Down Expand Up @@ -86,8 +86,8 @@ export const PricingTransparencyQueryRenderer = ({
artworkId,
}: Omit<PricingTransparencyQuery$variables, "bidAmountMinor">) => {
const { relayEnvironment } = useSystemContext()
const { values } = useFormContext()
const bidAmountMinor = parseInt(values.selectedBid!)
const { values } = useAuctionFormContext()
const bidAmountMinor = parseInt(values.selectedBid || "0")

// Hack to prevent invalid refetch / preloader state during route transition
// when the url changes after user places a successful bid and we redirect
Expand Down
Loading