Skip to content

Commit

Permalink
Merge branch 'main' into fix-filter-out-bytespider-entries-from-sentry
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholas-codecov authored Oct 23, 2023
2 parents 277436c + bc8fb16 commit dcb6a1a
Show file tree
Hide file tree
Showing 20 changed files with 841 additions and 29 deletions.
99 changes: 99 additions & 0 deletions src/pages/PullRequestPage/Header/Header.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render, screen } from '@testing-library/react'
import { graphql } from 'msw'
import { setupServer } from 'msw/node'
import { MemoryRouter, Route } from 'react-router-dom'

import { TierNames } from 'services/tier'
import { useFlags } from 'shared/featureFlags'

import Header from './Header'

jest.mock('./HeaderDefault', () => () => 'Default Header')
jest.mock('./HeaderTeam', () => () => 'Team Header')
jest.mock('shared/featureFlags')
const mockedUseFlags = useFlags as jest.Mock<{ multipleTiers: boolean }>

const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
const server = setupServer()
const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={['/gh/test-org/test-repo/pull/12']}>
<Route path="/:provider/:owner/:repo/pull/:pullId">{children}</Route>
</MemoryRouter>
</QueryClientProvider>
)

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

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

afterAll(() => {
server.close()
})

interface SetupArgs {
multipleTiers: boolean
}

describe('Header', () => {
function setup({ multipleTiers = false }: SetupArgs) {
mockedUseFlags.mockReturnValue({
multipleTiers,
})

server.use(
graphql.query('OwnerTier', (req, res, ctx) => {
if (multipleTiers) {
return res(
ctx.status(200),
ctx.data({ owner: { plan: { tierName: TierNames.TEAM } } })
)
}
return res(
ctx.status(200),
ctx.data({ owner: { plan: { tierName: TierNames.PRO } } })
)
})
)
}

describe('when rendered and customer is not team tier', () => {
beforeEach(() => {
setup({ multipleTiers: false })
})

it('renders the default header component', async () => {
render(<Header />, { wrapper })

const defaultHeader = await screen.findByText(/Default Header/)
expect(defaultHeader).toBeInTheDocument()

const teamHeader = screen.queryByText(/Team Header/)
expect(teamHeader).not.toBeInTheDocument()
})
})

describe('when rendered and customer has team tier', () => {
beforeEach(() => {
setup({ multipleTiers: true })
})

it('renders the team header component', async () => {
render(<Header />, { wrapper })

const teamHeader = await screen.findByText(/Team Header/)
expect(teamHeader).toBeInTheDocument()

const defaultHeader = screen.queryByText(/Default Header/)
expect(defaultHeader).not.toBeInTheDocument()
})
})
})
28 changes: 28 additions & 0 deletions src/pages/PullRequestPage/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useParams } from 'react-router-dom'

import { TierNames, useTier } from 'services/tier'
import { useFlags } from 'shared/featureFlags'

import HeaderDefault from './HeaderDefault'
import HeaderTeam from './HeaderTeam'

interface URLParams {
provider: string
owner: string
}

function Header() {
const { provider, owner } = useParams<URLParams>()
const { data: tierData } = useTier({ provider, owner })
const { multipleTiers } = useFlags({
multipleTiers: false,
})

if (multipleTiers && tierData === TierNames.TEAM) {
return <HeaderTeam />
}

return <HeaderDefault />
}

export default Header
Original file line number Diff line number Diff line change
Expand Up @@ -9,63 +9,58 @@ import CIStatusLabel from 'ui/CIStatus'
import Icon from 'ui/Icon'

import { usePullHeadData } from './hooks'
import PendoLink from './PendoLink'

const pullStateToColor = {
OPEN: 'bg-ds-primary-green',
CLOSED: 'bg-ds-primary-red',
MERGED: 'bg-ds-primary-purple',
}
import { pullStateToColor } from '../constants'
import PendoLink from '../PendoLink'

function Header() {
function HeaderDefault() {
const { provider, owner, repo, pullId } = useParams()
const { data } = usePullHeadData({ provider, owner, repo, pullId })

const pull = data?.pull

return (
<div className="flex flex-col justify-between gap-2 border-b border-ds-gray-secondary pb-2 text-xs md:flex-row">
<div>
<h1 className="flex items-center gap-2 text-lg font-semibold">
{data?.pull?.title}
{pull?.title}
<span
className={cs(
'text-white font-bold px-3 py-0.5 text-xs rounded',
pullStateToColor[data?.pull?.state]
pullStateToColor[pull?.state]
)}
>
{capitalize(data?.pull?.state)}
{capitalize(pull?.state)}
</span>
</h1>
<p className="flex items-center gap-2">
<span>
{data?.pull?.updatestamp &&
formatTimeToNow(data?.pull?.updatestamp)}{' '}
<span className="bold">{data?.pull?.author?.username}</span>{' '}
authored{' '}
{data?.pull?.pullId && (
{pull?.updatestamp && formatTimeToNow(pull?.updatestamp)}{' '}
<span className="bold">{pull?.author?.username}</span> authored{' '}
{pull?.pullId && (
<A
href={getProviderPullURL({
provider,
owner,
repo,
pullId: data?.pull?.pullId,
pullId: pull?.pullId,
})}
hook="provider-pr-link"
isExternal={true}
>
#{data?.pull?.pullId}
#{pull?.pullId}
</A>
)}
</span>
<CIStatusLabel ciPassed={data?.pull?.head?.ciPassed} />
<CIStatusLabel ciPassed={pull?.head?.ciPassed} />
<span className="flex items-center">
<Icon name="branch" variant="developer" size="sm" />
{data?.pull?.head?.branchName}
{pull?.head?.branchName}
</span>
</p>
</div>
<PendoLink />
</div>
)
}

export default Header
export default HeaderDefault
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { graphql } from 'msw'
import { setupServer } from 'msw/node'
import { MemoryRouter, Route } from 'react-router-dom'

import Header from './Header'

jest.mock('shared/featureFlags')
import Header from './HeaderDefault'

const mockPullData = {
owner: {
Expand Down
1 change: 1 addition & 0 deletions src/pages/PullRequestPage/Header/HeaderDefault/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './HeaderDefault'
79 changes: 79 additions & 0 deletions src/pages/PullRequestPage/Header/HeaderTeam/HeaderTeam.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import cs from 'classnames'
import capitalize from 'lodash/capitalize'
import { useParams } from 'react-router-dom'

import { formatTimeToNow } from 'shared/utils/dates'
import { getProviderPullURL } from 'shared/utils/provider'
import A from 'ui/A'
import CIStatusLabel from 'ui/CIStatus'
import Icon from 'ui/Icon'
import TotalsNumber from 'ui/TotalsNumber'

import { usePullHeadDataTeam } from './hooks'

import { pullStateToColor } from '../constants'
import PendoLink from '../PendoLink'

function HeaderTeam() {
const { provider, owner, repo, pullId } = useParams()
const { data } = usePullHeadDataTeam({ provider, owner, repo, pullId })

const pull = data?.pull

return (
<div className="flex flex-col justify-between gap-2 border-b border-ds-gray-secondary pb-2 text-xs md:flex-row">
<div className="flex flex-row flex-wrap items-center gap-6 divide-x divide-ds-gray-secondary">
<div>
<h1 className="flex items-center gap-2 text-lg font-semibold">
{pull?.title}
<span
className={cs(
'text-white font-bold px-3 py-0.5 text-xs rounded',
pullStateToColor[pull?.state]
)}
>
{capitalize(pull?.state)}
</span>
</h1>
<p className="flex flex-row items-center gap-2">
<span>
{pull?.updatestamp && formatTimeToNow(pull?.updatestamp)}{' '}
<span className="bold">{pull?.author?.username}</span> authored{' '}
{pull?.pullId && (
<A
href={getProviderPullURL({
provider,
owner,
repo,
pullId: pull?.pullId,
})}
hook="provider-pr-link"
isExternal={true}
>
#{pull?.pullId}
</A>
)}
</span>
<CIStatusLabel ciPassed={pull?.head?.ciPassed} />
<span className="flex items-center">
<Icon name="branch" variant="developer" size="sm" />
{pull?.head?.branchName}
</span>
</p>
</div>
<div className="flex flex-col justify-center gap-2 px-6">
<h4 className="gap-2 font-mono text-xs text-ds-gray-quinary">
Patch Coverage
</h4>
<TotalsNumber
value={pull?.compareWithBase?.patchTotals?.percentCovered}
plain
large
/>
</div>
</div>
<PendoLink />
</div>
)
}
export default HeaderTeam
Loading

0 comments on commit dcb6a1a

Please sign in to comment.