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: build OKTA form within OKTA access tab #2974

Merged
merged 7 commits into from
Jul 5, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe('OktaAccess', () => {
setup({ isAdmin: true })
render(<OktaAccess />, { wrapper })

const form = await screen.findByText(/Okta access form/)
const form = await screen.findByText(/Step 1: Enable Okta Sync/)
expect(form).toBeInTheDocument()
})

Expand Down
3 changes: 2 additions & 1 deletion src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom'
import { useIsCurrentUserAnAdmin } from 'services/user'

import { AdminAuthorizationBanner } from './AdminAuthorizationBanner'
import { OktaConfigForm } from './OktaConfigForm'

interface URLParams {
owner: string
Expand All @@ -22,7 +23,7 @@ function OktaAccess() {
</p>
</div>
<hr />
{isAdmin ? <>Okta access form</> : <AdminAuthorizationBanner />}
{isAdmin ? <OktaConfigForm /> : <AdminAuthorizationBanner />}
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Suspense } from 'react'
import { MemoryRouter, Route } from 'react-router-dom'

import { OktaConfigForm } from './OktaConfigForm'

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

describe('OktaConfigForm', () => {
function setup() {
const user = userEvent.setup()
return { user }
}

it('should render Okta Config form header', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const header = await screen.findByText(/Step 1: Enable Okta Sync/)
expect(header).toBeInTheDocument()
})

it('should render Okta Config form description', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const description = await screen.findByText(
/To connect Codecov with Okta, you need to enable the synchronization./
)
expect(description).toBeInTheDocument()
})

it('should display Client ID validation error when removing client id value', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const clientSecretInput = await screen.findByLabelText(/Client Secret/)
await userEvent.type(clientSecretInput, 'clientSecret')

const redirectUriInput = await screen.findByLabelText(/Redirect URI/)
await userEvent.type(redirectUriInput, 'http://localhost:3000')

const clientIdInput = await screen.findByLabelText(/Client ID/)
await userEvent.type(clientIdInput, 'clientId')
await userEvent.clear(clientIdInput)

const clientIdError = await screen.findByText(/Client ID is required/)
expect(clientIdError).toBeInTheDocument()
})

it('should display Client Secret validation error when removing client secret value', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const clientIdInput = await screen.findByLabelText(/Client ID/)
await userEvent.type(clientIdInput, 'clientId')

const redirectUriInput = await screen.findByLabelText(/Redirect URI/)
await userEvent.type(redirectUriInput, 'http://localhost:3000')

const clientSecretInput = await screen.findByLabelText(/Client Secret/)
await userEvent.type(clientSecretInput, 'clientSecret')
await userEvent.clear(clientSecretInput)

const clientSecretError = await screen.findByText(
/Client Secret is required/
)
expect(clientSecretError).toBeInTheDocument()
})

it('shows client secret when clicking on the eye icon', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const clientSecretInput = await screen.findByLabelText(/Client Secret/)
await userEvent.type(clientSecretInput, 'clientSecret')

const eyeIcon = await screen.findByRole('button', {
name: /eye/,
})
await userEvent.click(eyeIcon)

expect(clientSecretInput).toHaveAttribute('type', 'text')
})

it('hides client secret when clicking on the eye icon', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const clientSecretInput = await screen.findByLabelText(/Client Secret/)
await userEvent.type(clientSecretInput, 'clientSecret')

const eyeIcon = await screen.findByRole('button', {
name: /eye/,
})
await userEvent.click(eyeIcon)
await userEvent.click(eyeIcon)

expect(clientSecretInput).toHaveAttribute('type', 'password')
})

it('should display Redirect URI validation error when removing redirect uri value', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const clientIdInput = await screen.findByLabelText(/Client ID/)
await userEvent.type(clientIdInput, 'clientId')

const clientSecretInput = await screen.findByLabelText(/Client Secret/)
await userEvent.type(clientSecretInput, 'clientSecret')

const redirectUriInput = await screen.findByLabelText(/Redirect URI/)
await userEvent.type(redirectUriInput, 'http://localhost:3000')
await userEvent.clear(redirectUriInput)

const redirectUriError = await screen.findByText(
/Redirect URI must be a valid URL/
)
expect(redirectUriError).toBeInTheDocument()
})

it('should toggle Okta Sync Enabled on', async () => {
const { user } = setup()
render(<OktaConfigForm />, { wrapper })

const oktaSyncEnabledToggle = await screen.findByRole('button', {
name: /Okta Sync Enabled/,
})
expect(oktaSyncEnabledToggle).toBeInTheDocument()
expect(oktaSyncEnabledToggle).toHaveClass('bg-ds-gray-quinary')

await user.click(oktaSyncEnabledToggle)
expect(oktaSyncEnabledToggle).toHaveClass('bg-ds-primary-base')
})

it('should toggle Okta Login Enforce on', async () => {
const { user } = setup()
render(<OktaConfigForm />, { wrapper })

const oktaLoginEnforceToggle = await screen.findByRole('button', {
name: /Okta Login Enforced/,
})
expect(oktaLoginEnforceToggle).toBeInTheDocument()
expect(oktaLoginEnforceToggle).toHaveClass('bg-ds-gray-quinary')

await user.click(oktaLoginEnforceToggle)
expect(oktaLoginEnforceToggle).toHaveClass('bg-ds-primary-base')
})

it('toggles enabled on when enforced is on', async () => {
const { user } = setup()
render(<OktaConfigForm />, { wrapper })

const oktaLoginEnforceToggle = await screen.findByRole('button', {
name: /Okta Login Enforced/,
})
expect(oktaLoginEnforceToggle).toBeInTheDocument()
expect(oktaLoginEnforceToggle).toHaveClass('bg-ds-gray-quinary')

await user.click(oktaLoginEnforceToggle)
const oktaSyncEnabledToggle = await screen.findByRole('button', {
name: /Okta Sync Enabled/,
})
expect(oktaLoginEnforceToggle).toHaveClass('bg-ds-primary-base')
expect(oktaSyncEnabledToggle).toHaveClass('bg-ds-primary-base')
})

it('disables enforce toggle when enabled is off', async () => {
const { user } = setup()
render(<OktaConfigForm />, { wrapper })

const oktaSyncEnabledToggle = await screen.findByRole('button', {
name: /Okta Sync Enabled/,
})
expect(oktaSyncEnabledToggle).toBeInTheDocument()
expect(oktaSyncEnabledToggle).toHaveClass('bg-ds-gray-quinary')

const oktaLoginEnforceToggle = await screen.findByRole('button', {
name: /Okta Login Enforced/,
})
expect(oktaLoginEnforceToggle).toBeInTheDocument()
expect(oktaLoginEnforceToggle).toHaveClass('bg-ds-gray-quinary')

await user.click(oktaLoginEnforceToggle)
expect(oktaLoginEnforceToggle).toHaveClass('bg-ds-primary-base')

await user.click(oktaSyncEnabledToggle)
expect(oktaSyncEnabledToggle).toHaveClass('bg-ds-gray-quinary')
expect(oktaLoginEnforceToggle).toHaveClass('bg-ds-gray-quinary')
})

it('disables save button when form is in invalid state', async () => {
setup()
render(<OktaConfigForm />, { wrapper })

const saveButton = await screen.findByRole('button', {
name: /Save/,
})

expect(saveButton).toBeInTheDocument()
expect(saveButton).toBeDisabled()
})
})
Loading
Loading