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

ref: Migrate useOktaConfig to TSQ V5 #3683

Merged
merged 10 commits into from
Jan 28, 2025
23 changes: 16 additions & 7 deletions src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
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'
Expand All @@ -10,15 +14,20 @@ import OktaAccess from './OktaAccess'
const queryClient = new QueryClient({
defaultOptions: { queries: { suspense: true, retry: false } },
})
const queryClientV5 = new QueryClientV5({
defaultOptions: { queries: { retry: false } },
})

const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={['/account/gh/codecov/okta-access/']}>
<Route path="/account/:provider/:owner/okta-access/">
<Suspense fallback={null}>{children}</Suspense>
</Route>
</MemoryRouter>
</QueryClientProvider>
<QueryClientProviderV5 client={queryClientV5}>
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={['/account/gh/codecov/okta-access/']}>
<Route path="/account/:provider/:owner/okta-access/">
<Suspense fallback={null}>{children}</Suspense>
</Route>
</MemoryRouter>
</QueryClientProvider>
</QueryClientProviderV5>
)

const server = setupServer()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import {
QueryClientProvider as QueryClientProviderV5,
QueryClient as QueryClientV5,
} from '@tanstack/react-queryV5'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { graphql, HttpResponse } from 'msw'
Expand All @@ -8,11 +12,34 @@

import { OktaConfigForm } from './OktaConfigForm'

const oktaConfigMock = {
enabled: true,
enforced: true,
url: 'https://okta.com',
clientId: 'clientId',
clientSecret: 'clientSecret',
}

const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
const server = setupServer()
const queryClientV5 = new QueryClientV5({
defaultOptions: { queries: { retry: false } },
})

const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
<QueryClientProviderV5 client={queryClientV5}>
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={['/account/gh/codecov/okta-access/']}>
<Route path="/account/:provider/:owner/okta-access/">
<Suspense fallback={null}>{children}</Suspense>
</Route>
</MemoryRouter>
</QueryClientProvider>
</QueryClientProviderV5>
)

const server = setupServer()
beforeAll(() => {
server.listen()
})
Expand All @@ -26,24 +53,6 @@
server.close()
})

const oktaConfigMock = {
enabled: true,
enforced: true,
url: 'https://okta.com',
clientId: 'clientId',
clientSecret: 'clientSecret',
}

const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={['/account/gh/codecov/okta-access/']}>
<Route path="/account/:provider/:owner/okta-access/">
<Suspense fallback={null}>{children}</Suspense>
</Route>
</MemoryRouter>
</QueryClientProvider>
)

describe('OktaConfigForm', () => {
function setup() {
const user = userEvent.setup()
Expand Down Expand Up @@ -187,7 +196,7 @@
name: /Okta Sync Enabled/,
})
expect(oktaSyncEnabledToggle).toBeInTheDocument()
expect(oktaSyncEnabledToggle).toHaveClass('bg-toggle-inactive')

Check failure on line 199 in src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx

View workflow job for this annotation

GitHub Actions / Test Runner #0 - Vitest

src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx > OktaConfigForm > should toggle Okta Sync Enabled on

Error: expect(element).toHaveClass("bg-toggle-inactive") Expected the element to have class: bg-toggle-inactive Received: relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-50 focus:ring-offset-2 bg-toggle-active ❯ src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx:199:35

await user.click(oktaSyncEnabledToggle)
expect(oktaSyncEnabledToggle).toHaveClass('bg-toggle-active')
Expand All @@ -201,7 +210,7 @@
name: /Okta Login Enforced/,
})
expect(oktaLoginEnforceToggle).toBeInTheDocument()
expect(oktaLoginEnforceToggle).toHaveClass('bg-toggle-inactive')

Check failure on line 213 in src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx

View workflow job for this annotation

GitHub Actions / Test Runner #0 - Vitest

src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx > OktaConfigForm > should toggle Okta Login Enforce on

Error: expect(element).toHaveClass("bg-toggle-inactive") Expected the element to have class: bg-toggle-inactive Received: relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-50 focus:ring-offset-2 bg-toggle-active ❯ src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx:213:36

await user.click(oktaLoginEnforceToggle)
expect(oktaLoginEnforceToggle).toHaveClass('bg-toggle-active')
Expand All @@ -215,7 +224,7 @@
name: /Okta Login Enforced/,
})
expect(oktaLoginEnforceToggle).toBeInTheDocument()
expect(oktaLoginEnforceToggle).toHaveClass('bg-toggle-inactive')

Check failure on line 227 in src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx

View workflow job for this annotation

GitHub Actions / Test Runner #0 - Vitest

src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx > OktaConfigForm > toggles enabled on when enforced is on

Error: expect(element).toHaveClass("bg-toggle-inactive") Expected the element to have class: bg-toggle-inactive Received: relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-50 focus:ring-offset-2 bg-toggle-active ❯ src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx:227:36

await user.click(oktaLoginEnforceToggle)
const oktaSyncEnabledToggle = await screen.findByRole('button', {
Expand All @@ -233,7 +242,7 @@
name: /Okta Sync Enabled/,
})
expect(oktaSyncEnabledToggle).toBeInTheDocument()
expect(oktaSyncEnabledToggle).toHaveClass('bg-toggle-inactive')

Check failure on line 245 in src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx

View workflow job for this annotation

GitHub Actions / Test Runner #0 - Vitest

src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx > OktaConfigForm > disables enforce toggle when enabled is off

Error: expect(element).toHaveClass("bg-toggle-inactive") Expected the element to have class: bg-toggle-inactive Received: relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-50 focus:ring-offset-2 bg-toggle-active ❯ src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx:245:35

const oktaLoginEnforceToggle = await screen.findByRole('button', {
name: /Okta Login Enforced/,
Expand Down Expand Up @@ -300,7 +309,7 @@
name: /Okta Sync Enabled/,
})
await waitFor(() => {
expect(oktaSyncEnabledToggle).toHaveClass('bg-toggle-inactive')
expect(oktaSyncEnabledToggle).toHaveClass('bg-toggle-active')
})
})

Expand All @@ -312,7 +321,7 @@
name: /Okta Login Enforced/,
})
await waitFor(() => {
expect(oktaLoginEnforceToggle).toHaveClass('bg-toggle-inactive')
expect(oktaLoginEnforceToggle).toHaveClass('bg-toggle-active')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had to update these tests, because beforehand they weren't using the data from the API query, as suspense wasn't enabled on the queryClient, with it being controlled with which query hook you use now (i.e. useSuspenseQuery), these tests started failing, as in prod they would have suspended and used the values from the API.

})
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useSuspenseQuery as useSuspenseQueryV5 } from '@tanstack/react-queryV5'
import { useState } from 'react'
import { SubmitHandler, useForm } from 'react-hook-form'
import { useParams } from 'react-router-dom'
Expand All @@ -12,7 +13,8 @@ import Icon from 'ui/Icon'
import TextInput from 'ui/TextInput'
import Toggle from 'ui/Toggle'

import { useOktaConfig, useUpdateOktaConfig } from '../hooks'
import { useUpdateOktaConfig } from '../hooks'
import { OktaConfigQueryOpts } from '../queries/OktaConfigQueryOpts'

const FormSchema = z.object({
clientId: z.string().min(1, 'Client ID is required'),
Expand All @@ -29,10 +31,12 @@ interface URLParams {
export function OktaConfigForm() {
const { provider, owner } = useParams<URLParams>()

const { data } = useOktaConfig({
provider,
username: owner,
})
const { data } = useSuspenseQueryV5(
OktaConfigQueryOpts({
provider,
username: owner,
})
)
const oktaConfig = data?.owner?.account?.oktaConfig

const { register, handleSubmit, formState, reset } = useForm<FormValues>({
Expand All @@ -44,9 +48,8 @@ export function OktaConfigForm() {
redirectUri: oktaConfig?.url,
},
})
const { isDirty, isValid } = formState
const { mutate } = useUpdateOktaConfig({ provider, owner })

const { mutate } = useUpdateOktaConfig({ provider, owner })
const [oktaEnabled, setOktaEnabled] = useState(oktaConfig?.enabled)
const [oktaLoginEnforce, setOktaLoginEnforce] = useState(oktaConfig?.enforced)
const [showPassword, setShowPassword] = useState(false)
Expand Down Expand Up @@ -158,7 +161,9 @@ export function OktaConfigForm() {
<div>
<Button
type="submit"
disabled={!isValid || !isDirty || isSubmitting}
disabled={
!formState.isValid || !formState.isDirty || isSubmitting
}
to={undefined}
hook="save okta form changes"
>
Expand Down
1 change: 0 additions & 1 deletion src/pages/AccountSettings/tabs/OktaAccess/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { useOktaConfig } from './useOktaConfig'
export { useUpdateOktaConfig } from './useUpdateOktaConfig'
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import {
QueryClientProvider as QueryClientProviderV5,
QueryClient as QueryClientV5,
} from '@tanstack/react-queryV5'
import { render, renderHook, screen, waitFor } from '@testing-library/react'
import { graphql, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
Expand All @@ -18,15 +22,20 @@ const mockedToastNotification = useAddNotification as Mock
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
const queryClientV5 = new QueryClientV5({
defaultOptions: { queries: { retry: false } },
})

const wrapper =
(initialEntries = '/gh/codecov'): React.FC<React.PropsWithChildren> =>
({ children }) => (
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={[initialEntries]}>
<Route path="/:provider/:owner">{children}</Route>
</MemoryRouter>
</QueryClientProvider>
<QueryClientProviderV5 client={queryClientV5}>
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={[initialEntries]}>
<Route path="/:provider/:owner">{children}</Route>
</MemoryRouter>
</QueryClientProvider>
</QueryClientProviderV5>
)

const provider = 'gh'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useMutation } from '@tanstack/react-query'
import { useQueryClient as useQueryClientV5 } from '@tanstack/react-queryV5'
import z from 'zod'

import { useAddNotification } from 'services/toastNotification'
import Api from 'shared/api'
import { NetworkErrorObject } from 'shared/api/helpers'
import A from 'ui/A'

import { OktaConfigQueryOpts } from '../queries/OktaConfigQueryOpts'

const TOAST_DURATION = 10000

const query = `
Expand Down Expand Up @@ -78,7 +81,7 @@ type MutationFnParams = {

export const useUpdateOktaConfig = ({ provider, owner }: URLParams) => {
const addToast = useAddNotification()
const queryClient = useQueryClient()
const queryClientV5 = useQueryClientV5()

return useMutation({
mutationFn: ({
Expand Down Expand Up @@ -143,7 +146,9 @@ export const useUpdateOktaConfig = ({ provider, owner }: URLParams) => {
})
},
onSettled: () => {
queryClient.invalidateQueries(['GetOktaConfig'])
queryClientV5.invalidateQueries(
OktaConfigQueryOpts({ provider, username: owner })
)
},
retry: false,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
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 { useOktaConfig } from './useOktaConfig'
import { OktaConfigQueryOpts } from './OktaConfigQueryOpts'

const oktaConfigMock = {
enabled: true,
Expand All @@ -13,21 +17,23 @@ const oktaConfigMock = {
clientSecret: 'clientSecret',
}

const queryClient = new QueryClient({
const queryClientV5 = new QueryClientV5({
defaultOptions: { queries: { retry: false } },
})
const server = setupServer()

const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
<QueryClientProviderV5 client={queryClientV5}>
{children}
</QueryClientProviderV5>
)

beforeAll(() => {
server.listen()
})

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

Expand Down Expand Up @@ -58,10 +64,12 @@ describe('useOktaConfig', () => {

const { result } = renderHook(
() =>
useOktaConfig({
provider: 'gh',
username: 'codecov',
}),
useQueryV5(
OktaConfigQueryOpts({
provider: 'gh',
username: 'codecov',
})
),
{ wrapper }
)

Expand Down Expand Up @@ -90,10 +98,12 @@ describe('useOktaConfig', () => {

const { result } = renderHook(
() =>
useOktaConfig({
provider: 'gh',
username: 'codecov',
}),
useQueryV5(
OktaConfigQueryOpts({
provider: 'gh',
username: 'codecov',
})
),
{ wrapper }
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useQuery, type UseQueryOptions } from '@tanstack/react-query'
import { queryOptions as queryOptionsV5 } from '@tanstack/react-queryV5'
import { z } from 'zod'

import Api from 'shared/api'
Expand Down Expand Up @@ -26,30 +26,32 @@ const OktaConfigRequestSchema = z.object({
})

const oktaConfigQuery = `
query GetOktaConfig($username: String!) {
owner(username: $username) {
isUserOktaAuthenticated
account {
oktaConfig {
enabled
enforced
url
clientId
clientSecret
}
query GetOktaConfig($username: String!) {
owner(username: $username) {
isUserOktaAuthenticated
account {
oktaConfig {
enabled
enforced
url
clientId
clientSecret
}
}
}
}
`

interface UseOktaConfigArgs {
interface OktaConfigQueryArgs {
provider: string
username: string
opts?: UseQueryOptions<z.infer<typeof OktaConfigRequestSchema>>
}

export function useOktaConfig({ provider, username, opts }: UseOktaConfigArgs) {
return useQuery({
export function OktaConfigQueryOpts({
provider,
username,
}: OktaConfigQueryArgs) {
return queryOptionsV5({
queryKey: ['GetOktaConfig', provider, username, oktaConfigQuery],
queryFn: ({ signal }) => {
return Api.graphql({
Expand All @@ -73,6 +75,5 @@ export function useOktaConfig({ provider, username, opts }: UseOktaConfigArgs) {
return parsedRes.data
})
},
...(!!opts && opts),
})
}
Loading
Loading