Skip to content

Commit

Permalink
fix: Replace processing status indicator (#2776)
Browse files Browse the repository at this point in the history
* update CIStatus to display No Status instead of processing

* update pull default header

* update team pull header
  • Loading branch information
nicholas-codecov authored Apr 15, 2024
1 parent 88faf5e commit 521a596
Show file tree
Hide file tree
Showing 13 changed files with 491 additions and 229 deletions.

This file was deleted.

208 changes: 208 additions & 0 deletions src/pages/PullRequestPage/Header/HeaderDefault/HeaderDefault.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render, screen, waitFor } from '@testing-library/react'
import { graphql } from 'msw'
import { setupServer } from 'msw/node'
import { MemoryRouter, Route } from 'react-router-dom'

import Header from './HeaderDefault'

const mockPullData = ({
pullState = 'OPEN',
ciStatus = true,
}: {
pullState: 'OPEN' | 'CLOSED' | 'MERGED' | undefined
ciStatus: boolean | null
}) => ({
owner: {
repository: {
__typename: 'Repository',
pull: {
pullId: 1,
title: 'Cool Pull Request',
state: pullState,
author: {
username: 'cool-user',
},
head: {
branchName: 'cool-branch',
ciPassed: ciStatus,
},
updatestamp: '2020-01-01T12:00:00.000000',
},
},
},
})

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 {
pullState?: 'OPEN' | 'CLOSED' | 'MERGED' | undefined
ciStatus?: boolean | null
nullPull?: boolean
}

describe('Header', () => {
function setup({
pullState = 'OPEN',
ciStatus = true,
nullPull = false,
}: SetupArgs) {
server.use(
graphql.query('PullHeadData', (req, res, ctx) => {
if (nullPull) {
return res(ctx.status(200), ctx.data({ owner: { repository: null } }))
}

return res(
ctx.status(200),
ctx.data(mockPullData({ pullState, ciStatus }))
)
})
)
}

describe('when rendered', () => {
it('renders PR title', async () => {
setup({})
render(<Header />, { wrapper })

const heading = await screen.findByRole('heading', {
name: /Cool Pull Request/,
})
expect(heading).toBeInTheDocument()
})

describe('rendering PR status', () => {
describe('when PR is open', () => {
it('renders open PR status', async () => {
setup({ pullState: 'OPEN' })
render(<Header />, { wrapper })

const open = await screen.findByText(/open/i)
expect(open).toBeInTheDocument()
expect(open).toHaveClass('bg-ds-primary-green')
})
})

describe('when PR is closed', () => {
it('renders closed PR status', async () => {
setup({ pullState: 'CLOSED' })
render(<Header />, { wrapper })

const closed = await screen.findByText(/closed/i)
expect(closed).toBeInTheDocument()
expect(closed).toHaveClass('bg-ds-primary-red')
})
})

describe('when PR is merged', () => {
it('renders merged PR status', async () => {
setup({ pullState: 'MERGED' })
render(<Header />, { wrapper })

const merged = await screen.findByText(/merged/i)
expect(merged).toBeInTheDocument()
expect(merged).toHaveClass('bg-ds-primary-purple')
})
})

describe('when PR status is undefined', () => {
it('does not render', async () => {
setup({ nullPull: true })
render(<Header />, { wrapper })

await waitFor(() => queryClient.isFetching)
await waitFor(() => !queryClient.isFetching)

const open = screen.queryByText(/open/i)
expect(open).not.toBeInTheDocument()

const closed = screen.queryByText(/closed/i)
expect(closed).not.toBeInTheDocument()

const merged = screen.queryByText(/merged/i)
expect(merged).not.toBeInTheDocument()
})
})
})

it('renders the author username', async () => {
setup({})
render(<Header />, { wrapper })

const author = await screen.findByText(/cool-user/i)
expect(author).toBeInTheDocument()
})

it('renders the pr id', async () => {
setup({})
render(<Header />, { wrapper })

const prNumber = await screen.findByText(/#1/i)
expect(prNumber).toBeInTheDocument()
})

describe('rendering CI status', () => {
describe('when CI status is true', () => {
it('renders CI passed status', async () => {
setup({ ciStatus: true })
render(<Header />, { wrapper })

const ciStatus = await screen.findByText(/CI Passed/i)
expect(ciStatus).toBeInTheDocument()
})
})

describe('when CI status is false', () => {
it('renders CI failed status', async () => {
setup({ ciStatus: false })
render(<Header />, { wrapper })

const ciStatus = await screen.findByText(/CI Failed/i)
expect(ciStatus).toBeInTheDocument()
})
})

describe('when CI status is null', () => {
it('renders no status', async () => {
setup({ ciStatus: null })
render(<Header />, { wrapper })

const ciStatus = await screen.findByText(/No Status/i)
expect(ciStatus).toBeInTheDocument()
})
})
})

it('renders the branch name', async () => {
setup({})
render(<Header />, { wrapper })

const branchName = await screen.findByText(/cool-branch/i)
expect(branchName).toBeInTheDocument()
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@ import { usePullHeadData } from './hooks'

import { pullStateToColor } from '../constants'

interface URLParams {
provider: string
owner: string
repo: string
pullId: string
}

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

const pull = data?.pull
Expand All @@ -23,20 +30,23 @@ function HeaderDefault() {
<div>
<h1 className="flex items-center gap-2 text-xl 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>
{pull?.state ? (
<span
className={cs(
'text-white font-bold px-3 py-0.5 text-xs rounded',
pullStateToColor[pull?.state]
)}
>
{capitalize(pull?.state)}
</span>
) : null}
</h1>
<p className="flex items-center gap-2">
<span>
{pull?.updatestamp && formatTimeToNow(pull?.updatestamp)}{' '}
<span className="bold">{pull?.author?.username}</span> authored{' '}
{pull?.pullId && (
// @ts-expect-error - A needs to be updated to TS
<A
href={getProviderPullURL({
provider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ const RepositorySchema = z.object({
.object({
pullId: z.number(),
title: z.string().nullable(),
state: z
.union([z.literal('OPEN'), z.literal('CLOSED'), z.literal('MERGED')])
.nullable(),
state: z.union([
z.literal('OPEN'),
z.literal('CLOSED'),
z.literal('MERGED'),
]),
author: z
.object({
username: z.string().nullable(),
Expand Down
Loading

0 comments on commit 521a596

Please sign in to comment.