Skip to content

Commit

Permalink
Merge branch 'main' into cy/non_gh_onboard_links
Browse files Browse the repository at this point in the history
  • Loading branch information
calvin-codecov authored Nov 25, 2024
2 parents f0e22e7 + cfffad4 commit 983db88
Show file tree
Hide file tree
Showing 12 changed files with 588 additions and 25 deletions.
56 changes: 36 additions & 20 deletions src/layouts/Header/Header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,19 @@ afterAll(() => {
server.close()
})

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

type SetupArgs = {
user?: User
Expand All @@ -125,7 +131,7 @@ describe('Header', () => {
it('shows impersonating banner', async () => {
setup({})
mockedUseImpersonate.mockReturnValue({ isImpersonating: true })
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const impersonatingBanner = await screen.findByText('Impersonating')
expect(impersonatingBanner).toBeInTheDocument()
Expand All @@ -134,23 +140,23 @@ describe('Header', () => {
describe('when are not logged in', () => {
it('shows guest header', async () => {
setup({ user: mockNullUser })
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const guestHeader = await screen.findByText('Why Test Code?')
expect(guestHeader).toBeInTheDocument()
})

it('shows navigator', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const navigator = await screen.findByText('Navigator')
expect(navigator).toBeInTheDocument()
})

it('does not show user/help dropdowns', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const userDropdown = screen.queryByText('User Dropdown')
expect(userDropdown).not.toBeInTheDocument()
Expand All @@ -162,31 +168,31 @@ describe('Header', () => {
describe('when logged in', () => {
it('shows navigator', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const navigator = await screen.findByText('Navigator')
expect(navigator).toBeInTheDocument()
})

it('shows help dropdown', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const helpDropdown = await screen.findByText(/Help Dropdown/)
expect(helpDropdown).toBeInTheDocument()
})

it('shows user dropdown', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const userDropdown = await screen.findByText(/User Dropdown/)
expect(userDropdown).toBeInTheDocument()
})

it('has toggle for light/dark mode', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const toggle = await screen.findByText(/Theme Toggle/)
expect(toggle).toBeInTheDocument()
Expand All @@ -198,23 +204,23 @@ describe('Header', () => {
it('shows guest header', async () => {
config.IS_SELF_HOSTED = true
setup({ user: mockNullUser })
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const guestHeader = await screen.findByText('Why Test Code?')
expect(guestHeader).toBeInTheDocument()
})

it('shows navigator', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const navigator = await screen.findByText('Navigator')
expect(navigator).toBeInTheDocument()
})

it('does not show user/help dropdowns', async () => {
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const userDropdown = screen.queryByText('User Dropdown')
expect(userDropdown).not.toBeInTheDocument()
Expand All @@ -227,7 +233,7 @@ describe('Header', () => {
it('shows seat details', async () => {
config.IS_SELF_HOSTED = true
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const text = await screen.findByText(/Seat Details/)
expect(text).toBeInTheDocument()
Expand All @@ -236,11 +242,21 @@ describe('Header', () => {
it('shows Admin link', async () => {
config.IS_SELF_HOSTED = true
setup({})
render(<Header />, { wrapper })
render(<Header />, { wrapper: wrapper() })

const text = await screen.findByText(/Admin Link/)
expect(text).toBeInTheDocument()
})
})
})

describe('when on sync page', () => {
it('does not show navigator', async () => {
setup({})
render(<Header />, { wrapper: wrapper('/sync') })

const navigator = screen.queryByText('Navigator')
expect(navigator).not.toBeInTheDocument()
})
})
})
10 changes: 7 additions & 3 deletions src/layouts/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Suspense } from 'react'
import { useRouteMatch } from 'react-router-dom'

import config from 'config'

Expand All @@ -16,6 +17,7 @@ import UserDropdown from './components/UserDropdown'
function Header() {
const { isImpersonating } = useImpersonate()
const { data: currentUser } = useUser()
const syncPageMatch = useRouteMatch('/sync')

return (
<header>
Expand All @@ -26,9 +28,11 @@ function Header() {
</div>
) : null}
<nav className="container flex h-14 min-h-14 w-full items-center">
<div className="flex-1">
<Navigator currentUser={currentUser} />
</div>
{!syncPageMatch?.isExact ? (
<div className="flex-1">
<Navigator currentUser={currentUser} />
</div>
) : null}
{!currentUser ? null : (
<div className="flex items-center justify-end gap-4">
{config.IS_SELF_HOSTED ? (
Expand Down
20 changes: 19 additions & 1 deletion src/pages/RepoPage/ActivationAlert/ActivationAlert.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { graphql, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { MemoryRouter, Route } from 'react-router-dom'

import config from 'config'

import { PlanName, Plans } from 'shared/utils/billing'

import ActivationAlert from './ActivationAlert'
Expand All @@ -20,6 +22,9 @@ vi.mock('./ActivationRequiredAlert', () => ({
vi.mock('./UnauthorizedRepoDisplay', () => ({
default: () => 'UnauthorizedRepoDisplay',
}))
vi.mock('./ActivationRequiredSelfHosted', () => ({
default: () => 'ActivationRequiredSelfHostedBanner',
}))

const queryClient = new QueryClient()

Expand Down Expand Up @@ -64,8 +69,11 @@ describe('ActivationAlert', () => {
function setup(
privateRepos = true,
value: PlanName = Plans.USERS_BASIC,
hasSeatsLeft = true
hasSeatsLeft = true,
isSelfHosted = false
) {
config.IS_SELF_HOSTED = isSelfHosted

server.use(
graphql.query('GetPlanData', (info) => {
return HttpResponse.json({
Expand Down Expand Up @@ -131,4 +139,14 @@ describe('ActivationAlert', () => {
)
expect(activationRequiredAlert).toBeInTheDocument()
})

it('renders ActivationRequiredSelfHosted when user is self hosted', async () => {
setup(false, Plans.USERS_BASIC, true, true)
render(<ActivationAlert />, { wrapper })

const activationRequiredSelfHostedBanner = await screen.findByText(
/ActivationRequiredSelfHostedBanner/
)
expect(activationRequiredSelfHostedBanner).toBeInTheDocument()
})
})
7 changes: 7 additions & 0 deletions src/pages/RepoPage/ActivationAlert/ActivationAlert.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { useParams } from 'react-router-dom'

import config from 'config'

import { usePlanData } from 'services/account'
import { isFreePlan } from 'shared/utils/billing'

import ActivationRequiredAlert from './ActivationRequiredAlert'
import ActivationRequiredSelfHosted from './ActivationRequiredSelfHosted'
import FreePlanSeatsTakenAlert from './FreePlanSeatsTakenAlert'
import PaidPlanSeatsTakenAlert from './PaidPlanSeatsTakenAlert'
import UnauthorizedRepoDisplay from './UnauthorizedRepoDisplay'
Expand All @@ -29,6 +32,10 @@ function ActivationAlert() {
const renderActivationRequiredAlert =
!isFreePlan(planData?.plan?.value) && planData?.plan?.hasSeatsLeft

if (config.IS_SELF_HOSTED) {
return <ActivationRequiredSelfHosted />
}

if (renderFreePlanSeatsTakenAlert) {
return <FreePlanSeatsTakenAlert />
}
Expand Down
Loading

0 comments on commit 983db88

Please sign in to comment.