Skip to content

Commit

Permalink
feat: Add radio button navigation to repo onboarding (#2839)
Browse files Browse the repository at this point in the history
* Use RadioTileGroup for navigation on the repo onboarding page

* Pull getInitalProvider out of component

* Fix tests

* Remove unnecessary div
  • Loading branch information
spalmurray-codecov authored and RulaKhaled committed May 13, 2024
1 parent 832a683 commit 7f0acc2
Show file tree
Hide file tree
Showing 2 changed files with 289 additions and 165 deletions.
298 changes: 188 additions & 110 deletions src/pages/RepoPage/CoverageOnboarding/NewRepoTab.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import NewRepoTab from './NewRepoTab'
jest.mock('shared/useRedirect')
const mockedUseRedirect = useRedirect as jest.Mock
jest.mock('./GitHubActions', () => () => 'GitHubActions')
jest.mock('./CircleCI', () => () => 'CircleCI')
jest.mock('./OtherCI', () => () => 'OtherCI')
jest.mock('./ActivationBanner', () => () => 'ActivationBanner')

Expand Down Expand Up @@ -69,12 +70,12 @@ const wrapper: (initialEntries?: string) => React.FC<PropsWithChildren> =
<Route
path={[
'/:provider/:owner/:repo/new',
'/:provider/:owner/:repo/new/circle-ci',
'/:provider/:owner/:repo/new/other-ci',
]}
>
<Suspense fallback={null}>{children}</Suspense>
</Route>

<Route
path="*"
render={({ location }) => {
Expand All @@ -87,7 +88,7 @@ const wrapper: (initialEntries?: string) => React.FC<PropsWithChildren> =
)

beforeAll(() => {
// console.error = () => {}
console.error = () => {}
server.listen()
})
afterEach(() => {
Expand Down Expand Up @@ -138,90 +139,186 @@ describe('NewRepoTab', () => {
return { hardRedirect, user }
}

describe('intro blurb', () => {
it('renders intro blurb', async () => {
setup({})
render(<NewRepoTab />, { wrapper: wrapper() })

const intro = await screen.findByTestId('intro-blurb')
expect(intro).toBeInTheDocument()
})

describe('CISelector', () => {
it('renders', async () => {
setup({})
render(<NewRepoTab />, { wrapper: wrapper() })

const intro = await screen.findByTestId('intro-blurb')
expect(intro).toBeInTheDocument()
const selectorHeader = await screen.findByText('Select your CI')
expect(selectorHeader).toBeInTheDocument()

const githubActions = await screen.findByText('Using GitHub Actions')
const circleCI = await screen.findByText('Using Circle CI')
const otherCI = await screen.findByText('Other')
expect(githubActions).toBeInTheDocument()
expect(circleCI).toBeInTheDocument()
expect(otherCI).toBeInTheDocument()
})
})

describe('rendering component', () => {
beforeEach(() =>
setup({
isPrivate: true,
describe('initial selection', () => {
describe('when on GH provider and /new path', () => {
it('selects GitHub Actions as default', async () => {
setup({})
render(<NewRepoTab />, { wrapper: wrapper() })

const githubActions = await screen.findByTestId(
'github-actions-radio'
)
expect(githubActions).toBeInTheDocument()
expect(githubActions.hasAttribute('data-state')).toBeTruthy()
expect(githubActions.getAttribute('data-state')).toBe('checked')
})
})
)

it('renders header', async () => {
render(<NewRepoTab />, { wrapper: wrapper() })
describe('when on non GH provider and /new path', () => {
it('selects Other CI as default', async () => {
setup({})
render(<NewRepoTab />, {
wrapper: wrapper('/gl/codecov/cool-repo/new'),
})

const header = await screen.findByRole('heading', {
name: /Let's get your repo covered/,
const otherCI = await screen.findByTestId('other-ci-radio')
expect(otherCI).toBeInTheDocument()
expect(otherCI.hasAttribute('data-state')).toBeTruthy()
expect(otherCI.getAttribute('data-state')).toBe('checked')
})
})
expect(header).toBeInTheDocument()
})

it('renders ActivationBanner', async () => {
render(<NewRepoTab />, { wrapper: wrapper() })
describe('when on /new/circle-ci', () => {
it('selects Circle CI as default', async () => {
setup({})
render(<NewRepoTab />, {
wrapper: wrapper('/gl/codecov/cool-repo/new/circle-ci'),
})

const circleCI = await screen.findByTestId('circle-ci-radio')
expect(circleCI).toBeInTheDocument()
expect(circleCI.hasAttribute('data-state')).toBeTruthy()
expect(circleCI.getAttribute('data-state')).toBe('checked')
})
})

const banner = await screen.findByText('ActivationBanner')
expect(banner).toBeInTheDocument()
describe('when on /new/other-ci', () => {
it('selects Other CI as default', async () => {
setup({})
render(<NewRepoTab />, {
wrapper: wrapper('/gl/codecov/cool-repo/new/other-ci'),
})

const otherCI = await screen.findByTestId('other-ci-radio')
expect(otherCI).toBeInTheDocument()
expect(otherCI.hasAttribute('data-state')).toBeTruthy()
expect(otherCI.getAttribute('data-state')).toBe('checked')
})
})
})

describe('users provider is github', () => {
it('renders github actions tab', async () => {
render(<NewRepoTab />, { wrapper: wrapper() })
describe('navigation', () => {
describe('when GitHub Actions is selected', () => {
it('should navigate to /new', async () => {
const { user } = setup({})
render(<NewRepoTab />, {
wrapper: wrapper('/gh/codecov/cool-repo/new/other-ci'),
})

const githubActions = await screen.findByTestId(
'github-actions-radio'
)
expect(githubActions).toBeInTheDocument()
expect(githubActions.hasAttribute('data-state')).toBeTruthy()
expect(githubActions.getAttribute('data-state')).toBe('unchecked')

await user.click(githubActions)

const content = await screen.findByText('GitHubActions')
expect(content).toBeInTheDocument()
expect(githubActions).toBeInTheDocument()
expect(githubActions.hasAttribute('data-state')).toBeTruthy()
expect(githubActions.getAttribute('data-state')).toBe('checked')

const tab = await screen.findByRole('link', { name: 'GitHub Actions' })
expect(tab).toBeInTheDocument()
expect(tab).toHaveAttribute('href', '/gh/codecov/cool-repo/new')
expect(testLocation.pathname).toBe('/gh/codecov/cool-repo/new')
})
})

it('renders other ci tab', async () => {
render(<NewRepoTab />, { wrapper: wrapper() })
describe('when Circle CI is selected', () => {
it('should navigate to /new/circle-ci', async () => {
const { user } = setup({})
render(<NewRepoTab />, { wrapper: wrapper() })

const content = await screen.findByText('GitHubActions')
expect(content).toBeInTheDocument()
const circleCI = await screen.findByTestId('circle-ci-radio')
expect(circleCI).toBeInTheDocument()
expect(circleCI.hasAttribute('data-state')).toBeTruthy()
expect(circleCI.getAttribute('data-state')).toBe('unchecked')

const tab = await screen.findByRole('link', { name: 'Other CI' })
expect(tab).toBeInTheDocument()
expect(tab).toHaveAttribute(
'href',
'/gh/codecov/cool-repo/new/other-ci'
)
})
})
await user.click(circleCI)

describe('users provider is not github', () => {
it('does not render github actions tab', async () => {
render(<NewRepoTab />, {
wrapper: wrapper('/gl/codecov/cool-repo/new'),
expect(circleCI).toBeInTheDocument()
expect(circleCI.hasAttribute('data-state')).toBeTruthy()
expect(circleCI.getAttribute('data-state')).toBe('checked')

expect(testLocation.pathname).toBe(
'/gh/codecov/cool-repo/new/circle-ci'
)
})
})

describe('when Other CI is selected', () => {
it('should navigate to /new/other-ci', async () => {
const { user } = setup({})
render(<NewRepoTab />, { wrapper: wrapper() })

const content = await screen.findByText('OtherCI')
expect(content).toBeInTheDocument()
const otherCI = await screen.findByTestId('other-ci-radio')
expect(otherCI).toBeInTheDocument()
expect(otherCI.hasAttribute('data-state')).toBeTruthy()
expect(otherCI.getAttribute('data-state')).toBe('unchecked')

const tab = screen.queryByRole('link', { name: 'GitHub Actions' })
expect(tab).not.toBeInTheDocument()
})
await user.click(otherCI)

it('does not render other ci tab', async () => {
render(<NewRepoTab />, {
wrapper: wrapper('/gl/codecov/cool-repo/new'),
expect(otherCI).toBeInTheDocument()
expect(otherCI.hasAttribute('data-state')).toBeTruthy()
expect(otherCI.getAttribute('data-state')).toBe('checked')

expect(testLocation.pathname).toBe(
'/gh/codecov/cool-repo/new/other-ci'
)
})
})
})
})

const content = await screen.findByText('OtherCI')
expect(content).toBeInTheDocument()
describe('rendering component', () => {
beforeEach(() =>
setup({
isPrivate: true,
})
)

it('renders github actions', async () => {
render(<NewRepoTab />, { wrapper: wrapper() })
const content = await screen.findByText(/GitHubActions/)
expect(content).toBeInTheDocument()
})

it('renders circle ci', async () => {
render(<NewRepoTab />, {
wrapper: wrapper('/gh/codecov/cool-repo/new/circle-ci'),
})
const content = await screen.findByText(/CircleCI/)
expect(content).toBeInTheDocument()
})

const tab = screen.queryByRole('link', { name: 'Other CI' })
expect(tab).not.toBeInTheDocument()
it('renders other ci', async () => {
render(<NewRepoTab />, {
wrapper: wrapper('/gh/codecov/cool-repo/new/other-ci'),
})
const content = await screen.findByText(/OtherCI/)
expect(content).toBeInTheDocument()
})
})

Expand All @@ -244,69 +341,50 @@ describe('NewRepoTab', () => {
})
})

describe('users provider is github', () => {
describe('testing tab navigation', () => {
describe('clicking on other ci', () => {
it('navigates to /other-ci', async () => {
const { user } = setup({
isPrivate: true,
})
render(<NewRepoTab />, { wrapper: wrapper() })

const tab = await screen.findByRole('link', { name: 'Other CI' })
expect(tab).toBeInTheDocument()
expect(tab).toHaveAttribute(
'href',
'/gh/codecov/cool-repo/new/other-ci'
)

await user.click(tab)

expect(testLocation.pathname).toBe(
'/gh/codecov/cool-repo/new/other-ci'
)

const content = await screen.findByText('OtherCI')
expect(content).toBeInTheDocument()
describe('ActivationBanner', () => {
describe('when user is activated', () => {
it('does not render ActivationBanner', async () => {
setup({
isCurrentUserActivated: true,
isPrivate: true,
})
})
render(<NewRepoTab />, { wrapper: wrapper() })

describe('clicking on github actions', () => {
it('navigates to /new', async () => {
const { user } = setup({})
render(<NewRepoTab />, {
wrapper: wrapper('/gh/codecov/cool-repo/new/other-ci'),
})
// Wait for full render
expect(await screen.findByText(/GitHubActions/)).toBeInTheDocument()

const tab = await screen.findByRole('link', {
name: 'GitHub Actions',
})
expect(tab).toBeInTheDocument()
expect(tab).toHaveAttribute('href', '/gh/codecov/cool-repo/new')
const banner = screen.queryByText(/ActivationBanner/)
expect(banner).not.toBeInTheDocument()
})
})

await user.click(tab)
describe('when user is not activated but public repo', () => {
it('does not render ActivationBanner', async () => {
setup({
isCurrentUserActivated: false,
isPrivate: false,
})
render(<NewRepoTab />, { wrapper: wrapper() })

expect(testLocation.pathname).toBe('/gh/codecov/cool-repo/new')
// Wait for full render
expect(await screen.findByText(/GitHubActions/)).toBeInTheDocument()

const content = await screen.findByText('GitHubActions')
expect(content).toBeInTheDocument()
})
const banner = screen.queryByText(/ActivationBanner/)
expect(banner).not.toBeInTheDocument()
})
})
})

describe('user is activated', () => {
it('does not render ActivationBanner', async () => {
setup({
isCurrentUserActivated: true,
})
render(<NewRepoTab />, { wrapper: wrapper() })

await waitFor(() => queryClient.isFetching)
await waitFor(() => !queryClient.isFetching)
describe('when user is not activated and is private repo', () => {
it('renders ActivationBanner', async () => {
setup({
isCurrentUserActivated: false,
isPrivate: true,
})
render(<NewRepoTab />, { wrapper: wrapper() })

const banner = screen.queryByText('ActivationBanner')
expect(banner).not.toBeInTheDocument()
const banner = await screen.findByText(/ActivationBanner/)
expect(banner).toBeInTheDocument()
})
})
})
})

0 comments on commit 7f0acc2

Please sign in to comment.