Skip to content

Commit b7ce614

Browse files
fix: Infer name if not in billing details (#3676)
1 parent a5dcca4 commit b7ce614

File tree

5 files changed

+174
-46
lines changed

5 files changed

+174
-46
lines changed

src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/BillingDetails.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function BillingDetails() {
3030
<EmailAddress />
3131
<PaymentCard
3232
// @ts-expect-error - TODO fix this once we update PaymentCard to TS
33-
subscriptionDetail={subscriptionDetail}
33+
accountDetails={accountDetails}
3434
provider={provider}
3535
owner={owner}
3636
/>

src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import PropTypes from 'prop-types'
22
import { useState } from 'react'
33

4-
import { subscriptionDetailType } from 'services/account'
4+
import { accountDetailsPropType } from 'services/account'
55
import { formatTimestampToCalendarDate } from 'shared/utils/billing'
66
import A from 'ui/A'
77
import Button from 'ui/Button'
@@ -10,8 +10,9 @@ import Icon from 'ui/Icon'
1010
import BankInformation from './BankInformation'
1111
import CardInformation from './CardInformation'
1212
import PaymentMethodForm from './PaymentMethodForm'
13-
function PaymentCard({ subscriptionDetail, provider, owner }) {
13+
function PaymentCard({ accountDetails, provider, owner }) {
1414
const [isFormOpen, setIsFormOpen] = useState(false)
15+
const subscriptionDetail = accountDetails?.subscriptionDetail
1516
const card = subscriptionDetail?.defaultPaymentMethod?.card
1617
const usBankAccount = subscriptionDetail?.defaultPaymentMethod?.usBankAccount
1718

@@ -41,7 +42,7 @@ function PaymentCard({ subscriptionDetail, provider, owner }) {
4142
provider={provider}
4243
owner={owner}
4344
closeForm={() => setIsFormOpen(false)}
44-
subscriptionDetail={subscriptionDetail}
45+
accountDetails={accountDetails}
4546
/>
4647
) : card ? (
4748
<CardInformation card={card} subscriptionDetail={subscriptionDetail} />
@@ -72,7 +73,7 @@ function PaymentCard({ subscriptionDetail, provider, owner }) {
7273
}
7374

7475
PaymentCard.propTypes = {
75-
subscriptionDetail: subscriptionDetailType,
76+
accountDetails: accountDetailsPropType,
7677
provider: PropTypes.string.isRequired,
7778
owner: PropTypes.string.isRequired,
7879
}

src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.test.jsx

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ const subscriptionDetail = {
5555
cancelAtPeriodEnd: false,
5656
}
5757

58+
const accountDetails = {
59+
subscriptionDetail,
60+
}
61+
5862
const usBankSubscriptionDetail = {
5963
defaultPaymentMethod: {
6064
usBankAccount: {
@@ -100,12 +104,10 @@ describe('PaymentCard', () => {
100104
return { user }
101105
}
102106

103-
describe(`when the user doesn't have any subscriptionDetail`, () => {
104-
// NOTE: This test is misleading because we hide this component from a higher level in
105-
// BillingDetails.tsx if there is no subscriptionDetail
107+
describe(`when the user doesn't have any accountDetails`, () => {
106108
it('renders the set payment method message', () => {
107109
render(
108-
<PaymentCard subscriptionDetail={null} provider="gh" owner="codecov" />
110+
<PaymentCard accountDetails={null} provider="gh" owner="codecov" />
109111
)
110112

111113
expect(
@@ -120,9 +122,12 @@ describe('PaymentCard', () => {
120122
it('renders an error message', () => {
121123
render(
122124
<PaymentCard
123-
subscriptionDetail={{
124-
...subscriptionDetail,
125-
defaultPaymentMethod: null,
125+
accountDetails={{
126+
...accountDetails,
127+
subscriptionDetail: {
128+
...accountDetails.subscriptionDetail,
129+
defaultPaymentMethod: null,
130+
},
126131
}}
127132
provider="gh"
128133
owner="codecov"
@@ -142,9 +147,12 @@ describe('PaymentCard', () => {
142147
const { user } = setup()
143148
render(
144149
<PaymentCard
145-
subscriptionDetail={{
146-
...subscriptionDetail,
147-
defaultPaymentMethod: null,
150+
accountDetails={{
151+
...accountDetails,
152+
subscriptionDetail: {
153+
...accountDetails.subscriptionDetail,
154+
defaultPaymentMethod: null,
155+
},
148156
}}
149157
provider="gh"
150158
owner="codecov"
@@ -165,9 +173,12 @@ describe('PaymentCard', () => {
165173
const { user } = setup()
166174
render(
167175
<PaymentCard
168-
subscriptionDetail={{
169-
...subscriptionDetail,
170-
defaultPaymentMethod: null,
176+
accountDetails={{
177+
...accountDetails,
178+
subscriptionDetail: {
179+
...accountDetails.subscriptionDetail,
180+
defaultPaymentMethod: null,
181+
},
171182
}}
172183
provider="gh"
173184
owner="codecov"
@@ -190,7 +201,7 @@ describe('PaymentCard', () => {
190201
it('renders the card', () => {
191202
render(
192203
<PaymentCard
193-
subscriptionDetail={subscriptionDetail}
204+
accountDetails={accountDetails}
194205
provider="gh"
195206
owner="codecov"
196207
/>,
@@ -204,7 +215,7 @@ describe('PaymentCard', () => {
204215
it('renders the next billing', () => {
205216
render(
206217
<PaymentCard
207-
subscriptionDetail={subscriptionDetail}
218+
accountDetails={accountDetails}
208219
provider="gh"
209220
owner="codecov"
210221
/>,
@@ -217,9 +228,15 @@ describe('PaymentCard', () => {
217228

218229
describe('when the user has a US bank account', () => {
219230
it('renders the bank account details', () => {
231+
const testAccountDetails = {
232+
...accountDetails,
233+
subscriptionDetail: {
234+
...usBankSubscriptionDetail,
235+
},
236+
}
220237
render(
221238
<PaymentCard
222-
subscriptionDetail={usBankSubscriptionDetail}
239+
accountDetails={testAccountDetails}
223240
provider="gh"
224241
owner="codecov"
225242
/>,
@@ -235,9 +252,12 @@ describe('PaymentCard', () => {
235252
it(`doesn't render the next billing`, () => {
236253
render(
237254
<PaymentCard
238-
subscriptionDetail={{
239-
...subscriptionDetail,
240-
cancelAtPeriodEnd: true,
255+
accountDetails={{
256+
...accountDetails,
257+
subscriptionDetail: {
258+
...accountDetails.subscriptionDetail,
259+
cancelAtPeriodEnd: true,
260+
},
241261
}}
242262
provider="gh"
243263
owner="codecov"
@@ -260,7 +280,7 @@ describe('PaymentCard', () => {
260280

261281
render(
262282
<PaymentCard
263-
subscriptionDetail={subscriptionDetail}
283+
accountDetails={accountDetails}
264284
provider="gh"
265285
owner="codecov"
266286
/>,
@@ -280,7 +300,7 @@ describe('PaymentCard', () => {
280300
})
281301
render(
282302
<PaymentCard
283-
subscriptionDetail={subscriptionDetail}
303+
accountDetails={accountDetails}
284304
provider="gh"
285305
owner="codecov"
286306
/>,
@@ -305,7 +325,7 @@ describe('PaymentCard', () => {
305325

306326
render(
307327
<PaymentCard
308-
subscriptionDetail={subscriptionDetail}
328+
accountDetails={accountDetails}
309329
provider="gh"
310330
owner="codecov"
311331
/>,
@@ -327,7 +347,7 @@ describe('PaymentCard', () => {
327347
})
328348
render(
329349
<PaymentCard
330-
subscriptionDetail={subscriptionDetail}
350+
accountDetails={accountDetails}
331351
provider="gh"
332352
owner="codecov"
333353
/>,
@@ -354,7 +374,7 @@ describe('PaymentCard', () => {
354374
})
355375
render(
356376
<PaymentCard
357-
subscriptionDetail={subscriptionDetail}
377+
accountDetails={accountDetails}
358378
provider="gh"
359379
owner="codecov"
360380
/>,
@@ -376,7 +396,7 @@ describe('PaymentCard', () => {
376396
})
377397
render(
378398
<PaymentCard
379-
subscriptionDetail={subscriptionDetail}
399+
accountDetails={accountDetails}
380400
provider="gh"
381401
owner="codecov"
382402
/>,

src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentMethodForm.test.tsx

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ import { MemoryRouter, Route } from 'react-router-dom'
66
import { vi } from 'vitest'
77
import { z } from 'zod'
88

9-
import { SubscriptionDetailSchema } from 'services/account/useAccountDetails'
9+
import {
10+
AccountDetailsSchema,
11+
SubscriptionDetailSchema,
12+
} from 'services/account/useAccountDetails'
1013

11-
import PaymentMethodForm from './PaymentMethodForm'
14+
import PaymentMethodForm, { getEmail, getName } from './PaymentMethodForm'
1215

1316
const queryClient = new QueryClient()
1417

@@ -66,6 +69,26 @@ const subscriptionDetail: z.infer<typeof SubscriptionDetailSchema> = {
6669
trialEnd: null,
6770
}
6871

72+
const accountDetails: z.infer<typeof AccountDetailsSchema> = {
73+
name: 'John Doe',
74+
75+
subscriptionDetail: subscriptionDetail,
76+
activatedStudentCount: 0,
77+
activatedUserCount: 0,
78+
checkoutSessionId: null,
79+
delinquent: null,
80+
inactiveUserCount: 0,
81+
integrationId: null,
82+
nbActivePrivateRepos: null,
83+
planAutoActivate: null,
84+
planProvider: null,
85+
repoTotalCredits: 0,
86+
rootOrganization: null,
87+
scheduleDetail: null,
88+
studentCount: 0,
89+
usesInvoice: false,
90+
}
91+
6992
const mocks = {
7093
useUpdatePaymentMethod: vi.fn(),
7194
}
@@ -90,7 +113,7 @@ describe('PaymentMethodForm', () => {
90113

91114
render(
92115
<PaymentMethodForm
93-
subscriptionDetail={subscriptionDetail}
116+
accountDetails={accountDetails}
94117
provider="gh"
95118
owner="codecov"
96119
closeForm={() => {}}
@@ -111,7 +134,7 @@ describe('PaymentMethodForm', () => {
111134
})
112135
render(
113136
<PaymentMethodForm
114-
subscriptionDetail={subscriptionDetail}
137+
accountDetails={accountDetails}
115138
provider="gh"
116139
owner="codecov"
117140
closeForm={() => {}}
@@ -133,7 +156,7 @@ describe('PaymentMethodForm', () => {
133156
})
134157
render(
135158
<PaymentMethodForm
136-
subscriptionDetail={subscriptionDetail}
159+
accountDetails={accountDetails}
137160
provider="gh"
138161
owner="codecov"
139162
closeForm={() => {}}
@@ -155,7 +178,7 @@ describe('PaymentMethodForm', () => {
155178
})
156179
render(
157180
<PaymentMethodForm
158-
subscriptionDetail={subscriptionDetail}
181+
accountDetails={accountDetails}
159182
provider="gh"
160183
owner="codecov"
161184
closeForm={closeForm}
@@ -181,7 +204,7 @@ describe('PaymentMethodForm', () => {
181204
})
182205
render(
183206
<PaymentMethodForm
184-
subscriptionDetail={subscriptionDetail}
207+
accountDetails={accountDetails}
185208
provider="gh"
186209
owner="codecov"
187210
closeForm={() => {}}
@@ -203,7 +226,7 @@ describe('PaymentMethodForm', () => {
203226
})
204227
render(
205228
<PaymentMethodForm
206-
subscriptionDetail={subscriptionDetail}
229+
accountDetails={accountDetails}
207230
provider="gh"
208231
owner="codecov"
209232
closeForm={() => {}}
@@ -215,4 +238,62 @@ describe('PaymentMethodForm', () => {
215238
expect(screen.queryByRole('button', { name: /Cancel/i })).toBeDisabled()
216239
})
217240
})
241+
242+
describe('when the email is missing from billing details', () => {
243+
it('infers one from the rest of the data', () => {
244+
const accountDetailsWithoutBillingEmail = {
245+
246+
subscriptionDetail: {
247+
defaultPaymentMethod: {
248+
billingDetails: {
249+
email: null,
250+
},
251+
},
252+
},
253+
} as z.infer<typeof AccountDetailsSchema>
254+
255+
const email = getEmail(accountDetailsWithoutBillingEmail)
256+
expect(email).toBe('[email protected]')
257+
})
258+
})
259+
260+
describe('when the name is missing from billing details', () => {
261+
it('uses latestInvoice customerName when billing name is missing', () => {
262+
const accountDetailsWithoutBillingName = {
263+
subscriptionDetail: {
264+
defaultPaymentMethod: {
265+
billingDetails: {
266+
name: undefined,
267+
},
268+
},
269+
latestInvoice: {
270+
customerName: 'Customer Name',
271+
},
272+
},
273+
} as unknown as z.infer<typeof AccountDetailsSchema>
274+
275+
const name = getName(accountDetailsWithoutBillingName)
276+
expect(name).toBe('Customer Name')
277+
})
278+
279+
it('uses account name when billing name and invoice name are missing', () => {
280+
const accountDetailsWithoutBillingName = {
281+
name: 'Account Name',
282+
subscriptionDetail: {
283+
defaultPaymentMethod: {
284+
billingDetails: {
285+
name: undefined,
286+
},
287+
},
288+
latestInvoice: {
289+
customerName: undefined,
290+
},
291+
},
292+
} as unknown as z.infer<typeof AccountDetailsSchema>
293+
294+
const name = getName(accountDetailsWithoutBillingName)
295+
296+
expect(name).toBe('Account Name')
297+
})
298+
})
218299
})

0 commit comments

Comments
 (0)