Skip to content

Commit 7b9fe28

Browse files
authored
chore: Migrate useEnterpriseAccountDetails to TS Query V5 (#3571)
1 parent 0993878 commit 7b9fe28

File tree

6 files changed

+106
-66
lines changed

6 files changed

+106
-66
lines changed

src/pages/PlanPage/subRoutes/CurrentOrgPlan/AccountOrgs/AccountOrgs.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { MemoryRouter, Route, useLocation } from 'react-router'
1111

1212
import AccountOrgs from './AccountOrgs'
1313

14-
import { Account } from '../hooks/useEnterpriseAccountDetails'
14+
import { Account } from '../queries/EnterpriseAccountDetailsQueryOpts'
1515

1616
const mockAccount: Account = {
1717
name: 'my-account',

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Icon from 'ui/Icon'
1616
import Spinner from 'ui/Spinner'
1717
import { Tooltip } from 'ui/Tooltip'
1818

19-
import { Account } from '../hooks/useEnterpriseAccountDetails'
19+
import { Account } from '../queries/EnterpriseAccountDetailsQueryOpts'
2020
import { InfiniteAccountOrganizationsQueryOpts } from '../queries/InfiniteAccountOrganizationsQueryOpts'
2121

2222
interface AccountOrgsArgs {

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

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
2+
import {
3+
QueryClientProvider as QueryClientProviderV5,
4+
QueryClient as QueryClientV5,
5+
} from '@tanstack/react-queryV5'
26
import { render, screen } from '@testing-library/react'
37
import noop from 'lodash/noop'
48
import { graphql, http, HttpResponse } from 'msw'
59
import { setupServer } from 'msw/node'
10+
import { Suspense } from 'react'
611
import { MemoryRouter, Route } from 'react-router-dom'
712
import { z } from 'zod'
813

@@ -12,21 +17,13 @@ import { Plans } from 'shared/utils/billing'
1217
import { AlertOptions, type AlertOptionsType } from 'ui/Alert'
1318

1419
import CurrentOrgPlan from './CurrentOrgPlan'
15-
import { useEnterpriseAccountDetails } from './hooks/useEnterpriseAccountDetails'
20+
import { EnterpriseAccountDetailsRequestSchema } from './queries/EnterpriseAccountDetailsQueryOpts'
1621

1722
vi.mock('./BillingDetails', () => ({ default: () => 'BillingDetails' }))
1823
vi.mock('./CurrentPlanCard', () => ({ default: () => 'CurrentPlanCard' }))
1924
vi.mock('./LatestInvoiceCard', () => ({ default: () => 'LatestInvoiceCard' }))
2025
vi.mock('./AccountOrgs', () => ({ default: () => 'AccountOrgs' }))
2126

22-
const queryClient = new QueryClient({
23-
defaultOptions: {
24-
queries: {
25-
retry: false,
26-
},
27-
},
28-
})
29-
3027
const mockedAccountDetails = {
3128
planProvider: 'github',
3229
rootOrganization: {},
@@ -81,26 +78,38 @@ const mockEnterpriseAccountDetailsHundredPercent = {
8178
},
8279
}
8380

81+
const queryClient = new QueryClient({
82+
defaultOptions: { queries: { retry: false } },
83+
})
84+
85+
const queryClientV5 = new QueryClientV5({
86+
defaultOptions: { queries: { retry: false } },
87+
})
88+
8489
const alertOptionWrapperCreator = (
8590
alertOptionString: AlertOptionsType | '',
8691
isCancellation?: boolean
8792
) => {
8893
const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
8994
<MemoryRouter initialEntries={['/billing/gh/codecov']}>
9095
<Route path="/billing/:provider/:owner">
91-
<QueryClientProvider client={queryClient}>
92-
<PlanUpdatedPlanNotificationContext.Provider
93-
value={{
94-
updatedNotification: {
95-
alertOption: alertOptionString,
96-
isCancellation,
97-
},
98-
setUpdatedNotification: noop,
99-
}}
100-
>
101-
{children}
102-
</PlanUpdatedPlanNotificationContext.Provider>
103-
</QueryClientProvider>
96+
<QueryClientProviderV5 client={queryClientV5}>
97+
<QueryClientProvider client={queryClient}>
98+
<Suspense fallback={<div>Loading</div>}>
99+
<PlanUpdatedPlanNotificationContext.Provider
100+
value={{
101+
updatedNotification: {
102+
alertOption: alertOptionString,
103+
isCancellation,
104+
},
105+
setUpdatedNotification: noop,
106+
}}
107+
>
108+
{children}
109+
</PlanUpdatedPlanNotificationContext.Provider>
110+
</Suspense>
111+
</QueryClientProvider>
112+
</QueryClientProviderV5>
104113
</Route>
105114
</MemoryRouter>
106115
)
@@ -112,18 +121,25 @@ const wrapper = alertOptionWrapperCreator(AlertOptions.SUCCESS)
112121
const noUpdatedPlanWrapper = alertOptionWrapperCreator('')
113122
const cancellationPlanWrapper = alertOptionWrapperCreator('', true)
114123

115-
beforeAll(() => server.listen())
124+
beforeAll(() => {
125+
server.listen()
126+
})
127+
116128
afterEach(() => {
117129
queryClient.clear()
130+
queryClientV5.clear()
118131
server.resetHandlers()
119132
})
120-
afterAll(() => server.close())
133+
134+
afterAll(() => {
135+
server.close()
136+
})
121137

122138
interface SetupArgs {
123139
accountDetails?: z.infer<typeof AccountDetailsSchema>
124-
enterpriseAccountDetails?: ReturnType<
125-
typeof useEnterpriseAccountDetails
126-
>['data']
140+
enterpriseAccountDetails?: z.infer<
141+
typeof EnterpriseAccountDetailsRequestSchema
142+
>
127143
}
128144

129145
describe('CurrentOrgPlan', () => {
@@ -132,12 +148,12 @@ describe('CurrentOrgPlan', () => {
132148
enterpriseAccountDetails = mockNoEnterpriseAccount,
133149
}: SetupArgs) {
134150
server.use(
135-
graphql.query('EnterpriseAccountDetails', () =>
136-
HttpResponse.json({ data: enterpriseAccountDetails })
137-
),
138-
http.get('/internal/:provider/:owner/account-details', () =>
139-
HttpResponse.json(accountDetails)
140-
)
151+
graphql.query('EnterpriseAccountDetails', () => {
152+
return HttpResponse.json({ data: enterpriseAccountDetails })
153+
}),
154+
http.get('/internal/:provider/:owner/account-details', () => {
155+
return HttpResponse.json(accountDetails)
156+
})
141157
)
142158
}
143159

@@ -402,8 +418,8 @@ describe('CurrentOrgPlan', () => {
402418
setup({
403419
enterpriseAccountDetails: mockEnterpriseAccountDetailsHundredPercent,
404420
})
405-
406421
render(<CurrentOrgPlan />, { wrapper })
422+
407423
const banner = await screen.findByText(
408424
/Your account is using 100% of its seats/
409425
)

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useSuspenseQuery as useSuspenseQueryV5 } from '@tanstack/react-queryV5'
12
import { useParams } from 'react-router-dom'
23

34
import { usePlanUpdatedNotification } from 'pages/PlanPage/context'
@@ -9,10 +10,10 @@ import { Alert } from 'ui/Alert'
910
import AccountOrgs from './AccountOrgs'
1011
import BillingDetails from './BillingDetails'
1112
import CurrentPlanCard from './CurrentPlanCard'
12-
import { useEnterpriseAccountDetails } from './hooks/useEnterpriseAccountDetails'
1313
import InfoAlertCancellation from './InfoAlertCancellation'
1414
import InfoMessageStripeCallback from './InfoMessageStripeCallback'
1515
import LatestInvoiceCard from './LatestInvoiceCard'
16+
import { EnterpriseAccountDetailsQueryOpts } from './queries/EnterpriseAccountDetailsQueryOpts'
1617

1718
interface URLParams {
1819
provider: string
@@ -25,10 +26,12 @@ function CurrentOrgPlan() {
2526
provider,
2627
owner,
2728
})
28-
const { data: enterpriseDetails } = useEnterpriseAccountDetails({
29-
provider,
30-
owner,
31-
})
29+
const { data: enterpriseDetails } = useSuspenseQueryV5(
30+
EnterpriseAccountDetailsQueryOpts({
31+
provider,
32+
owner,
33+
})
34+
)
3235

3336
const scheduledPhase = accountDetails?.scheduleDetail?.scheduledPhase
3437
const isDelinquent = accountDetails?.delinquent

src/pages/PlanPage/subRoutes/CurrentOrgPlan/hooks/useEnterpriseAccountDetails.test.tsx renamed to src/pages/PlanPage/subRoutes/CurrentOrgPlan/queries/EnterpriseAccountDetailsQueryOpts.test.tsx

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,48 @@
1-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
1+
import {
2+
QueryClientProvider as QueryClientProviderV5,
3+
QueryClient as QueryClientV5,
4+
useQuery as useQueryV5,
5+
} from '@tanstack/react-queryV5'
26
import { renderHook, waitFor } from '@testing-library/react'
37
import { graphql, HttpResponse } from 'msw'
48
import { setupServer } from 'msw/node'
59

6-
import { useEnterpriseAccountDetails } from './useEnterpriseAccountDetails'
10+
import { EnterpriseAccountDetailsQueryOpts } from './EnterpriseAccountDetailsQueryOpts'
711

812
const mockEnterpriseAccountDetails = {
913
owner: {
1014
account: {
1115
name: 'account-name',
1216
totalSeatCount: 10,
1317
activatedUserCount: 7,
14-
organizations: {
15-
totalCount: 3,
16-
},
18+
organizations: { totalCount: 3 },
1719
},
1820
},
1921
}
2022

21-
const queryClient = new QueryClient({
23+
const queryClientV5 = new QueryClientV5({
2224
defaultOptions: { queries: { retry: false } },
2325
})
2426
const server = setupServer()
2527

2628
const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
27-
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
29+
<QueryClientProviderV5 client={queryClientV5}>
30+
{children}
31+
</QueryClientProviderV5>
2832
)
2933

30-
beforeAll(() => server.listen())
34+
beforeAll(() => {
35+
server.listen()
36+
})
37+
3138
afterEach(() => {
32-
queryClient.clear()
39+
queryClientV5.clear()
3340
server.resetHandlers()
3441
})
35-
afterAll(() => server.close())
42+
43+
afterAll(() => {
44+
server.close()
45+
})
3646

3747
interface SetupArgs {
3848
badResponse?: boolean
@@ -54,7 +64,13 @@ describe('useEnterpriseAccountDetails', () => {
5464
setup({ badResponse: true })
5565
console.error = () => {}
5666
const { result } = renderHook(
57-
() => useEnterpriseAccountDetails({ provider: 'gh', owner: 'codecov' }),
67+
() =>
68+
useQueryV5(
69+
EnterpriseAccountDetailsQueryOpts({
70+
provider: 'gh',
71+
owner: 'codecov',
72+
})
73+
),
5874
{ wrapper }
5975
)
6076

@@ -73,10 +89,12 @@ describe('useEnterpriseAccountDetails', () => {
7389
setup({})
7490
const { result } = renderHook(
7591
() =>
76-
useEnterpriseAccountDetails({
77-
provider: 'gh',
78-
owner: 'codecov',
79-
}),
92+
useQueryV5(
93+
EnterpriseAccountDetailsQueryOpts({
94+
provider: 'gh',
95+
owner: 'codecov',
96+
})
97+
),
8098
{ wrapper }
8199
)
82100

src/pages/PlanPage/subRoutes/CurrentOrgPlan/hooks/useEnterpriseAccountDetails.ts renamed to src/pages/PlanPage/subRoutes/CurrentOrgPlan/queries/EnterpriseAccountDetailsQueryOpts.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { useQuery } from '@tanstack/react-query'
1+
import { queryOptions as queryOptionsV5 } from '@tanstack/react-queryV5'
22
import { z } from 'zod'
33

44
import Api from 'shared/api/api'
5-
import { NetworkErrorObject } from 'shared/api/helpers'
5+
import { rejectNetworkError } from 'shared/api/helpers'
66

77
const AccountSchema = z.object({
88
name: z.string(),
@@ -15,7 +15,7 @@ const AccountSchema = z.object({
1515

1616
export type Account = z.infer<typeof AccountSchema>
1717

18-
const RequestSchema = z.object({
18+
export const EnterpriseAccountDetailsRequestSchema = z.object({
1919
owner: z
2020
.object({
2121
account: AccountSchema.nullable(),
@@ -36,16 +36,16 @@ const query = `query EnterpriseAccountDetails($owner: String!) {
3636
}
3737
}`
3838

39-
interface UseEnterpriseAccountDetailsArgs {
39+
interface EnterpriseAccountDetailsQueryArgs {
4040
provider: string
4141
owner: string
4242
}
4343

44-
export function useEnterpriseAccountDetails({
44+
export function EnterpriseAccountDetailsQueryOpts({
4545
provider,
4646
owner,
47-
}: UseEnterpriseAccountDetailsArgs) {
48-
return useQuery({
47+
}: EnterpriseAccountDetailsQueryArgs) {
48+
return queryOptionsV5({
4949
queryKey: ['EnterpriseAccountDetails', provider, owner],
5050
queryFn: ({ signal }) =>
5151
Api.graphql({
@@ -56,14 +56,17 @@ export function useEnterpriseAccountDetails({
5656
owner,
5757
},
5858
}).then((res) => {
59-
const parsedRes = RequestSchema.safeParse(res?.data)
59+
const parsedRes = EnterpriseAccountDetailsRequestSchema.safeParse(
60+
res?.data
61+
)
6062

6163
if (!parsedRes.success) {
62-
return Promise.reject({
64+
return rejectNetworkError({
6365
status: 404,
6466
data: {},
6567
dev: 'useEnterpriseAccountDetails - 404 Failed to parse data',
66-
} satisfies NetworkErrorObject)
68+
error: parsedRes.error,
69+
})
6770
}
6871

6972
return parsedRes.data

0 commit comments

Comments
 (0)