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

chore: Migrate useSelfHostedHasAdmins to TS Query V5 #3579

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ describe('App', () => {
return HttpResponse.json({ data: {} })
}),
graphql.query('HasAdmins', () => {
return HttpResponse.json({ data: {} })
return HttpResponse.json({ data: { config: null } })
}),
graphql.query('owner', () => {
return HttpResponse.json({ data: { owner: { isAdmin: true } } })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,61 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import {
QueryClientProvider as QueryClientProviderV5,
QueryClient as QueryClientV5,
useQuery as useQueryV5,
} from '@tanstack/react-queryV5'
import { renderHook, waitFor } from '@testing-library/react'
import { graphql, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { PropsWithChildren } from 'react'
import { z } from 'zod'

import {
HasAdminsSchema,
useSelfHostedHasAdmins,
} from './useSelfHostedHasAdmins'
SelfHostedHasAdminsQueryOpts,
} from './SelfHostedHasAdminsQueryOpts'

const queryClient = new QueryClient({
const queryClientV5 = new QueryClientV5({
defaultOptions: { queries: { retry: false } },
})
const wrapper: React.FC<PropsWithChildren> = ({ children }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
<QueryClientProviderV5 client={queryClientV5}>
{children}
</QueryClientProviderV5>
)
const server = setupServer()
beforeAll(() => {
server.listen()
})

beforeEach(() => {
server.resetHandlers()
queryClient.clear()
queryClientV5.clear()
})

afterAll(() => {
server.close()
})

describe('useSelfHostedHasAdmins', () => {
function setup({ data }: { data: z.infer<typeof HasAdminsSchema> }) {
interface SetupArgs {
data: z.infer<typeof HasAdminsSchema>
}

describe('SelfHostedHasAdminsQueryOpts', () => {
function setup({ data }: SetupArgs) {
server.use(
graphql.query('HasAdmins', () => {
return HttpResponse.json({ data })
})
)
}

describe('when called', () => {
it('returns the user info', async () => {
setup({ data: { config: { hasAdmins: true } } })
const { result } = renderHook(
() => useSelfHostedHasAdmins({ provider: 'gl' }),
() => useQueryV5(SelfHostedHasAdminsQueryOpts({ provider: 'gl' })),
{ wrapper }
)

await waitFor(() => expect(result.current.data).toEqual(true))
})
})
Expand Down
50 changes: 50 additions & 0 deletions src/services/selfHosted/SelfHostedHasAdminsQueryOpts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
keepPreviousData,
queryOptions as queryOptionsV5,
} from '@tanstack/react-queryV5'
import { z } from 'zod'

import Api from 'shared/api'
import { rejectNetworkError } from 'shared/api/helpers'

export const HasAdminsSchema = z.object({
config: z
.object({
hasAdmins: z.boolean().nullable(),
})
.nullable(),
})

const query = `query HasAdmins { config { hasAdmins } }`

interface SelfHostedHasAdminsQueryArgs {
provider: string
}

export const SelfHostedHasAdminsQueryOpts = ({
provider,
}: SelfHostedHasAdminsQueryArgs) => {
return queryOptionsV5({
queryKey: ['HasAdmins', provider],
queryFn: () =>
Api.graphql({
provider,
query,
}).then((res) => {
const parsedRes = HasAdminsSchema.safeParse(res?.data)

if (!parsedRes.success) {
return rejectNetworkError({
status: 404,
data: {},
dev: 'SelfHostedHasAdminsQueryOpts - 404 schema parsing failed',
error: parsedRes.error,
})
}

return !!parsedRes?.data?.config?.hasAdmins
}),
// this is how TSQuery V5 handles keepPreviousData
Copy link
Contributor

Choose a reason for hiding this comment

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

nice, good to know!

placeholderData: keepPreviousData,
})
}
1 change: 0 additions & 1 deletion src/services/selfHosted/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './useSelfHostedCurrentUser'
export * from './useSelfHostedSeatsConfig'
export * from './useSelfHostedHasAdmins'
export * from './useSelfHostedSeatsAndLicense'
57 changes: 0 additions & 57 deletions src/services/selfHosted/useSelfHostedHasAdmins.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import {
QueryClientProvider as QueryClientProviderV5,
QueryClient as QueryClientV5,
} from '@tanstack/react-queryV5'
import { render, screen } from '@testing-library/react'
import { graphql, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { Suspense } from 'react'
import { MemoryRouter, Route } from 'react-router-dom'

import config from 'config'
Expand All @@ -17,6 +22,23 @@ const mockApiCloud = { config: undefined }
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
const queryClientV5 = new QueryClientV5({
defaultOptions: { queries: { retry: false } },
})

const wrapper =
(initialEntries = ['/gh/test-org/test-repo/pull/12']) =>
({ children }) => (
<QueryClientProviderV5 client={queryClientV5}>
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={initialEntries}>
<Route path="/:provider/:owner/:repo/pull/:pullId">
<Suspense fallback={<div>Loading</div>}>{children}</Suspense>
</Route>
</MemoryRouter>
</QueryClientProvider>
</QueryClientProviderV5>
)

const server = setupServer()
beforeAll(() => {
Expand All @@ -25,23 +47,14 @@ beforeAll(() => {

afterEach(() => {
queryClient.clear()
queryClientV5.clear()
server.resetHandlers()
})

afterAll(() => {
server.close()
})

const wrapper =
(initialEntries = ['/gh/test-org/test-repo/pull/12']) =>
({ children }) => (
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={initialEntries}>
<Route path="/:provider/:owner/:repo/pull/:pullId">{children}</Route>
</MemoryRouter>
</QueryClientProvider>
)

describe('MissingDesignatedAdmins', () => {
function setup(overrideData) {
server.use(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useSuspenseQuery as useSuspenseQueryV5 } from '@tanstack/react-queryV5'
import { useParams } from 'react-router-dom'

import config from 'config'

import { useSelfHostedHasAdmins } from 'services/selfHosted'
import { SelfHostedHasAdminsQueryOpts } from 'services/selfHosted/SelfHostedHasAdminsQueryOpts'
import { Provider } from 'shared/api/helpers'
import A from 'ui/A'
import Banner from 'ui/Banner'
Expand Down Expand Up @@ -33,9 +34,8 @@ interface URLParams {

const MissingDesignatedAdmins = () => {
const { provider } = useParams<URLParams>()
const { data: hasAdmins, isFetching } = useSelfHostedHasAdmins(
{ provider },
{ enabled: !!provider && !!config.IS_SELF_HOSTED }
const { data: hasAdmins, isFetching } = useSuspenseQueryV5(
SelfHostedHasAdminsQueryOpts({ provider })
)
// This hook is purely side stepping the complexity rule here.
const hideBanner = useHideBanner({
Expand Down
Loading