Skip to content

Commit

Permalink
feat, ref: Disable Flag MultiSelect on Coverage Tab when on a Team Pl…
Browse files Browse the repository at this point in the history
…an (#2329)

Disable the flag multi-select on the coverage tab when users/orgs are on a team plan.

GH codecov/engineering-team#685
  • Loading branch information
nicholas-codecov authored and RulaKhaled committed Oct 31, 2023
1 parent 8f7f2dc commit e6349ec
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 24 deletions.
8 changes: 8 additions & 0 deletions src/pages/RepoPage/CoverageTab/CoverageTab.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { graphql, rest } from 'msw'
import { setupServer } from 'msw/node'
import { MemoryRouter, Route } from 'react-router-dom'

import { TierNames } from 'services/tier'

import CoverageTab from './CoverageTab'

const queryClient = new QueryClient({
Expand Down Expand Up @@ -207,6 +209,12 @@ describe('Coverage Tab', () => {
graphql.query('BackfillFlagMemberships', (req, res, ctx) =>
res(ctx.status(200), ctx.data({}))
),
graphql.query('OwnerTier', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.data({ owner: { plan: { tierName: TierNames.PRO } } })
)
}),
rest.get(
'/internal/:provider/:owner/:repo/coverage/tree',
(req, res, ctx) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import eq from 'lodash/eq'
import isUndefined from 'lodash/isUndefined'
import PropTypes from 'prop-types'
import { useState } from 'react'
import { useParams } from 'react-router-dom'

import { useLocationParams } from 'services/navigation'
import { useRepoBackfilled, useRepoFlagsSelect } from 'services/repo'
import { TierNames, useTier } from 'services/tier'
import { useFlags } from 'shared/featureFlags'
import Icon from 'ui/Icon'
import MultiSelect from 'ui/MultiSelect'
Expand All @@ -16,10 +18,12 @@ const defaultQueryParams = {
}

function FlagMultiSelect() {
const { provider, owner } = useParams()
const { params, updateParams } = useLocationParams(defaultQueryParams)
const [selectedFlags, setSelectedFlags] = useState(params?.flags)
const [flagSearch, setFlagSearch] = useState(null)

const { data: tierName } = useTier({ provider, owner })
const { data: repoBackfilledData } = useRepoBackfilled()

const isTimescaleEnabled = !!repoBackfilledData?.isTimescaleEnabled
Expand All @@ -45,7 +49,11 @@ function FlagMultiSelect() {
},
})

if (!coverageTabFlagMutliSelect || noFlagsPresent) {
if (
!coverageTabFlagMutliSelect ||
noFlagsPresent ||
tierName === TierNames.TEAM
) {
return null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { setupServer } from 'msw/node'
import { MemoryRouter, Route } from 'react-router-dom'
import useIntersection from 'react-use/lib/useIntersection'

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

import FlagMultiSelect from './FlagMultiSelect'
Expand Down Expand Up @@ -144,11 +145,13 @@ describe('FlagMultiSelect', () => {
isIntersecting = false,
noNextPage = false,
backfillData = mockBackfillHasFlagsAndActive,
tierValue = TierNames.PRO,
} = {
flagValue: false,
isIntersecting: false,
noNextPage: false,
mockBackfillHasFlagsAndActive: mockBackfillHasFlagsAndActive,
tierValue: TierNames.PRO,
}
) {
const user = userEvent.setup()
Expand All @@ -172,6 +175,18 @@ describe('FlagMultiSelect', () => {
}),
graphql.query('BackfillFlagMemberships', (req, res, ctx) => {
return res(ctx.status(200), ctx.data(backfillData))
}),
graphql.query('OwnerTier', (req, res, ctx) => {
if (tierValue === TierNames.TEAM) {
return res(
ctx.status(200),
ctx.data({ owner: { plan: { tierName: TierNames.TEAM } } })
)
}
return res(
ctx.status(200),
ctx.data({ owner: { plan: { tierName: TierNames.PRO } } })
)
})
)

Expand Down Expand Up @@ -294,6 +309,19 @@ describe('FlagMultiSelect', () => {
})
})

describe('when on team plan', () => {
it('does not show multi select', async () => {
setup({ flagValue: true, tierValue: TierNames.TEAM })

const { container } = render(<FlagMultiSelect />, { wrapper })

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

await waitFor(() => expect(container).toBeEmptyDOMElement())
})
})

describe('when timescale is disabled', () => {
it('renders disabled multi select', async () => {
setup({ flagValue: true, backfillData: mockBackfillTimeScaleDisabled })
Expand Down
15 changes: 13 additions & 2 deletions src/pages/RepoPage/CoverageTab/subroute/Fileviewer/Fileviewer.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import { useParams } from 'react-router-dom'

import { TierNames, useTier } from 'services/tier'
import { useFlags } from 'shared/featureFlags'
import RawFileviewer from 'shared/RawFileviewer'
import { useTreePaths } from 'shared/treePaths'
import Breadcrumb from 'ui/Breadcrumb'

function FileView() {
const { treePaths } = useTreePaths()
const { ref: commit } = useParams()
const { provider, owner, ref: commit } = useParams()

const { coverageTabFlagMutliSelect } = useFlags({
coverageTabFlagMutliSelect: false,
})

const { data: tierName } = useTier({ provider, owner })

const showFlagSelector =
coverageTabFlagMutliSelect && tierName !== TierNames.TEAM

return (
<RawFileviewer
Expand All @@ -18,7 +29,7 @@ function FileView() {
commit={commit}
sticky
stickyPadding={215}
showFlagsSelect={true}
showFlagsSelect={showFlagSelector}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render, screen } from '@testing-library/react'
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 { TierNames } from 'services/tier'
import { useFlags } from 'shared/featureFlags'
import { useScrollToLine } from 'ui/CodeRenderer/hooks/useScrollToLine'

import FileView from './Fileviewer'

jest.mock('shared/featureFlags')
jest.mock('ui/CodeRenderer/hooks/useScrollToLine')

const mockOwner = {
Expand Down Expand Up @@ -93,10 +96,10 @@ const mockBackfillResponse = {
},
}

const server = setupServer()
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
const server = setupServer()

const wrapper =
(
Expand Down Expand Up @@ -127,13 +130,17 @@ afterAll(() => {
})

describe('FileView', () => {
function setup() {
function setup({ tierName = TierNames.PRO } = { tierName: TierNames.PRO }) {
useScrollToLine.mockImplementation(() => ({
lineRef: () => {},
handleClick: jest.fn(),
targeted: false,
}))

useFlags.mockReturnValue({
coverageTabFlagMutliSelect: true,
})

server.use(
graphql.query('DetailOwner', (req, res, ctx) =>
res(ctx.status(200), ctx.data({ owner: mockOwner }))
Expand All @@ -149,15 +156,26 @@ describe('FileView', () => {
}),
graphql.query('FlagsSelect', (req, res, ctx) => {
return res(ctx.status(200), ctx.data(mockFlagResponse))
}),
graphql.query('OwnerTier', (req, res, ctx) => {
if (tierName === TierNames.TEAM) {
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('rendering component', () => {
beforeEach(() => setup())

describe('displaying the tree path', () => {
it('displays repo link', async () => {
setup()
render(<FileView />, { wrapper: wrapper() })

const repoName = await screen.findByRole('link', { name: 'mightynein' })
Expand All @@ -169,6 +187,7 @@ describe('FileView', () => {
})

it('displays directory link', async () => {
setup()
render(<FileView />, { wrapper: wrapper() })

const repoName = await screen.findByRole('link', { name: 'folder' })
Expand All @@ -180,6 +199,7 @@ describe('FileView', () => {
})

it('displays file name', async () => {
setup()
render(<FileView />, { wrapper: wrapper() })

const fileName = await screen.findByText('file.js')
Expand All @@ -189,6 +209,7 @@ describe('FileView', () => {

describe('displaying the file viewer', () => {
it('sets the correct url link', async () => {
setup()
render(<FileView />, { wrapper: wrapper() })

const copyLink = await screen.findByRole('link', {
Expand All @@ -198,5 +219,29 @@ describe('FileView', () => {
expect(copyLink).toHaveAttribute('href', '#folder/file.js')
})
})

describe('displaying the flag selector', () => {
it('renders the flag multi select', async () => {
setup()
render(<FileView />, { wrapper: wrapper() })

const select = await screen.findByText('All flags')
expect(select).toBeInTheDocument()
})

describe('on a team plan', () => {
it('does not render the flag multi select', async () => {
setup({ tierName: TierNames.TEAM })
render(<FileView />, { wrapper: wrapper() })

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

await waitFor(() =>
expect(screen.queryByText('All flags')).not.toBeInTheDocument()
)
})
})
})
})
})
11 changes: 2 additions & 9 deletions src/ui/FileViewer/ToggleHeader/Title/Title.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useState } from 'react'

import { useLocationParams } from 'services/navigation'
import { useRepoBackfilled, useRepoFlagsSelect } from 'services/repo'
import { useFlags } from 'shared/featureFlags'
import Icon from 'ui/Icon'
import MultiSelect from 'ui/MultiSelect'

Expand Down Expand Up @@ -56,10 +55,6 @@ export const TitleFlags = () => {
const flagsMeasurementsActive = !!repoBackfilledData?.flagsMeasurementsActive
const noFlagsPresent = eq(repoBackfilledData?.flagsCount, 0)

const { coverageTabFlagMutliSelect } = useFlags({
coverageTabFlagMutliSelect: false,
})

const {
data: flagsData,
isLoading: flagsIsLoading,
Expand All @@ -69,9 +64,7 @@ export const TitleFlags = () => {
filters: { term: flagSearch },
options: {
suspense: false,
enabled:
!!coverageTabFlagMutliSelect ||
(flagsMeasurementsActive && !noFlagsPresent && isTimescaleEnabled),
enabled: flagsMeasurementsActive && !noFlagsPresent && isTimescaleEnabled,
},
})

Expand All @@ -84,7 +77,7 @@ export const TitleFlags = () => {
}
}

if (!coverageTabFlagMutliSelect || noFlagsPresent) {
if (noFlagsPresent) {
return null
}

Expand Down
7 changes: 0 additions & 7 deletions src/ui/FileViewer/ToggleHeader/Title/Title.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { setupServer } from 'msw/node'
import { MemoryRouter, Route } from 'react-router-dom'
import useIntersection from 'react-use/lib/useIntersection'

import { useFlags } from 'shared/featureFlags'

import Title, { TitleFlags, TitleHitCount } from './Title'

jest.mock('shared/featureFlags')
Expand Down Expand Up @@ -176,7 +174,6 @@ describe('Title', () => {
describe('TitleFlags', () => {
function setup(
{
flagValue = true,
isIntersecting = false,
noNextPage = false,
backfillData = mockBackfillHasFlagsAndActive,
Expand All @@ -190,10 +187,6 @@ describe('TitleFlags', () => {
const user = userEvent.setup()
const mockApiVars = jest.fn()

useFlags.mockReturnValue({
coverageTabFlagMutliSelect: flagValue,
})

useIntersection.mockReturnValue({ isIntersecting: isIntersecting })

server.use(
Expand Down

0 comments on commit e6349ec

Please sign in to comment.