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: Add radio button navigation to repo onboarding #2839

Merged
merged 4 commits into from
May 9, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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()
})
})
})
})