Skip to content

Commit 20a2fa3

Browse files
feat: Hide Codecov AI from the UI
Remove Codecov AI tab and route from the UI as the first step in deprecating the feature. This hides the feature from users while keeping the underlying code intact for a follow-up cleanup PR. Changes: - Remove CodecovAIPage route from App.tsx - Remove Codecov AI tab from all navigation tabs - Remove codecovAI nav link from useNavLinks.ts - Update tests to remove AI feature flag checks Note: Nav links used by internal page components (codecovAIDocs, codecovAIAppInstallation) are preserved to avoid breaking tests for the still-existing (but inaccessible) CodecovAIPage. Closes CCMRG-2033
1 parent 537d8dc commit 20a2fa3

File tree

12 files changed

+0
-272
lines changed

12 files changed

+0
-272
lines changed

src/App.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { ThemeContextProvider } from 'shared/ThemeContext'
2121
import AccountSettings from './pages/AccountSettings'
2222
import AdminSettings from './pages/AdminSettings'
2323
const AnalyticsPage = lazy(() => import('./pages/AnalyticsPage'))
24-
const CodecovAIPage = lazy(() => import('./pages/CodecovAIPage'))
2524
const CommitDetailPage = lazy(() => import('./pages/CommitDetailPage'))
2625
const EnterpriseLandingPage = lazy(() => import('pages/EnterpriseLandingPage'))
2726
const LoginPage = lazy(() => import('./pages/LoginPage'))
@@ -118,11 +117,6 @@ const MainAppRoutes = () => (
118117
<AnalyticsPage />
119118
</BaseLayout>
120119
</SentryRoute>
121-
<SentryRoute path="/codecovai/:provider/:owner" exact>
122-
<BaseLayout>
123-
<CodecovAIPage />
124-
</BaseLayout>
125-
</SentryRoute>
126120
<SentryRoute path="/:provider" exact>
127121
<BaseLayout>
128122
<HomePageRedirect />

src/pages/AccountSettings/shared/Header/Header.test.tsx

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,8 @@ import config from 'config'
66

77
import Header from './Header'
88

9-
const mocks = vi.hoisted(() => ({
10-
useFlags: vi.fn(),
11-
}))
12-
139
vi.mock('config')
1410
vi.mock('layouts/MyContextSwitcher', () => () => 'MyContextSwitcher')
15-
vi.mock('shared/featureFlags', () => ({
16-
useFlags: mocks.useFlags,
17-
}))
1811

1912
const queryClient = new QueryClient()
2013

@@ -36,7 +29,6 @@ beforeEach(() => {
3629
describe('Header', () => {
3730
function setup(isSelfHosted: boolean = false) {
3831
config.IS_SELF_HOSTED = isSelfHosted
39-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: true })
4032
}
4133

4234
describe('when users is part of the org', () => {
@@ -119,28 +111,4 @@ describe('Header', () => {
119111
).not.toBeInTheDocument()
120112
})
121113
})
122-
123-
describe('ai features tab', () => {
124-
it('does not render tab when flag is off', () => {
125-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: false })
126-
render(<Header />, { wrapper })
127-
128-
expect(
129-
screen.queryByRole('link', {
130-
name: /Codecov AI beta/i,
131-
})
132-
).not.toBeInTheDocument()
133-
})
134-
135-
it('renders tab when flag is on', () => {
136-
setup()
137-
render(<Header />, { wrapper })
138-
139-
expect(
140-
screen.getByRole('link', {
141-
name: /Codecov AI beta/i,
142-
})
143-
).toBeInTheDocument()
144-
})
145-
})
146114
})

src/pages/AccountSettings/shared/Header/Header.tsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
import config from 'config'
22

3-
import { useFlags } from 'shared/featureFlags'
4-
import Badge from 'ui/Badge'
53
import TabNavigation from 'ui/TabNavigation'
64

75
function Header() {
8-
const { codecovAiFeaturesTab } = useFlags({
9-
codecovAiFeaturesTab: false,
10-
})
11-
126
return (
137
<TabNavigation
148
tabs={[
159
{ pageName: 'owner', children: 'Repos' },
1610
{ pageName: 'analytics', children: 'Analytics' },
17-
...(codecovAiFeaturesTab
18-
? [
19-
{
20-
pageName: 'codecovAI',
21-
children: (
22-
<>
23-
Codecov AI <Badge>beta</Badge>{' '}
24-
</>
25-
),
26-
},
27-
]
28-
: []),
2911
...(config.IS_SELF_HOSTED
3012
? []
3113
: [{ pageName: 'membersTab' }, { pageName: 'planTab' }]),

src/pages/AnalyticsPage/Tabs/Tabs.test.tsx

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,8 @@ import config from 'config'
66

77
import Tabs from './Tabs'
88

9-
const mocks = vi.hoisted(() => ({
10-
useFlags: vi.fn(),
11-
}))
12-
139
vi.mock('config')
1410

15-
vi.mock('shared/featureFlags', async () => {
16-
const actual = await vi.importActual('shared/featureFlags')
17-
return {
18-
...actual,
19-
useFlags: mocks.useFlags,
20-
}
21-
})
22-
2311
const queryClient = new QueryClient()
2412

2513
const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
@@ -37,7 +25,6 @@ beforeEach(() => {
3725
describe('Tabs', () => {
3826
function setup(isSelfHosted: boolean = false) {
3927
config.IS_SELF_HOSTED = isSelfHosted
40-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: true })
4128
}
4229

4330
describe('when user is part of the org', () => {
@@ -102,22 +89,4 @@ describe('Tabs', () => {
10289
expect(link).not.toBeInTheDocument()
10390
})
10491
})
105-
106-
describe('ai features tab', () => {
107-
it('does not render tab when flag is off', () => {
108-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: false })
109-
render(<Tabs />, { wrapper })
110-
111-
const link = screen.queryByRole('link', { name: /Codecov AI beta/i })
112-
expect(link).not.toBeInTheDocument()
113-
})
114-
115-
it('renders tab when flag is on', () => {
116-
setup()
117-
render(<Tabs />, { wrapper })
118-
119-
const link = screen.getByRole('link', { name: /Codecov AI beta/i })
120-
expect(link).toBeInTheDocument()
121-
})
122-
})
12392
})

src/pages/AnalyticsPage/Tabs/Tabs.tsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
import config from 'config'
22

3-
import { useFlags } from 'shared/featureFlags'
4-
import Badge from 'ui/Badge'
53
import TabNavigation from 'ui/TabNavigation'
64

75
function Tabs() {
8-
const { codecovAiFeaturesTab } = useFlags({
9-
codecovAiFeaturesTab: false,
10-
})
11-
126
return (
137
<TabNavigation
148
tabs={[
159
{ pageName: 'owner', children: 'Repos' },
1610
{ pageName: 'analytics', children: 'Analytics' },
17-
...(codecovAiFeaturesTab
18-
? [
19-
{
20-
pageName: 'codecovAI',
21-
children: (
22-
<>
23-
Codecov AI <Badge>beta</Badge>{' '}
24-
</>
25-
),
26-
},
27-
]
28-
: []),
2911
...(config.IS_SELF_HOSTED
3012
? []
3113
: [{ pageName: 'membersTab' }, { pageName: 'planTab' }]),

src/pages/MembersPage/Tabs/Tabs.test.tsx

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,8 @@ import config from 'config'
55

66
import Tabs from './Tabs'
77

8-
const mocks = vi.hoisted(() => ({
9-
useFlags: vi.fn(),
10-
}))
11-
128
vi.mock('config')
139

14-
vi.mock('shared/featureFlags', async () => {
15-
const actual = await vi.importActual('shared/featureFlags')
16-
return {
17-
...actual,
18-
useFlags: mocks.useFlags,
19-
}
20-
})
21-
2210
const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
2311
<MemoryRouter initialEntries={['/analytics/gh/codecov']}>
2412
<Route path="/analytics/:provider/:owner">{children}</Route>
@@ -28,7 +16,6 @@ const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
2816
describe('Tabs', () => {
2917
function setup(isSelfHosted: boolean = false) {
3018
config.IS_SELF_HOSTED = isSelfHosted
31-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: true })
3219
}
3320

3421
describe('when user is part of the org', () => {
@@ -111,28 +98,4 @@ describe('Tabs', () => {
11198
).not.toBeInTheDocument()
11299
})
113100
})
114-
115-
describe('ai features tab', () => {
116-
it('does not render tab when flag is off', () => {
117-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: false })
118-
render(<Tabs />, { wrapper })
119-
120-
expect(
121-
screen.queryByRole('link', {
122-
name: /Codecov AI beta/i,
123-
})
124-
).not.toBeInTheDocument()
125-
})
126-
127-
it('renders tab when flag is on', () => {
128-
setup()
129-
render(<Tabs />, { wrapper })
130-
131-
expect(
132-
screen.getByRole('link', {
133-
name: /Codecov AI beta/i,
134-
})
135-
).toBeInTheDocument()
136-
})
137-
})
138101
})

src/pages/MembersPage/Tabs/Tabs.tsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
import config from 'config'
22

3-
import { useFlags } from 'shared/featureFlags'
4-
import Badge from 'ui/Badge'
53
import TabNavigation from 'ui/TabNavigation'
64

75
function Tabs() {
8-
const { codecovAiFeaturesTab } = useFlags({
9-
codecovAiFeaturesTab: false,
10-
})
11-
126
return (
137
<TabNavigation
148
tabs={[
159
{ pageName: 'owner', children: 'Repos' },
1610
{ pageName: 'analytics', children: 'Analytics' },
17-
...(codecovAiFeaturesTab
18-
? [
19-
{
20-
pageName: 'codecovAI',
21-
children: (
22-
<>
23-
Codecov AI <Badge>beta</Badge>{' '}
24-
</>
25-
),
26-
},
27-
]
28-
: []),
2911
...(config.IS_SELF_HOSTED
3012
? []
3113
: [{ pageName: 'membersTab' }, { pageName: 'planTab' }]),

src/pages/OwnerPage/Tabs/Tabs.test.tsx

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,6 @@ import config from 'config'
66

77
import Tabs from './Tabs'
88

9-
const mocks = vi.hoisted(() => ({
10-
useFlags: vi.fn(),
11-
}))
12-
vi.mock('shared/featureFlags', async () => {
13-
const actual = await vi.importActual('shared/featureFlags')
14-
return {
15-
...actual,
16-
useFlags: mocks.useFlags,
17-
}
18-
})
199
vi.mock('config')
2010
vi.mock('./TrialReminder', () => ({ default: () => 'TrialReminder' }))
2111

@@ -39,7 +29,6 @@ beforeEach(() => {
3929
describe('Tabs', () => {
4030
function setup(isSelfHosted: boolean = false) {
4131
config.IS_SELF_HOSTED = isSelfHosted
42-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: true })
4332
}
4433

4534
describe('when user is part of the org', () => {
@@ -114,28 +103,4 @@ describe('Tabs', () => {
114103
expect(trialReminder).toBeInTheDocument()
115104
})
116105
})
117-
118-
describe('ai features tab', () => {
119-
it('does not render tab when flag is off', () => {
120-
mocks.useFlags.mockReturnValue({ codecovAiFeaturesTab: false })
121-
render(<Tabs />, { wrapper })
122-
123-
expect(
124-
screen.queryByRole('link', {
125-
name: /Codecov AI beta/i,
126-
})
127-
).not.toBeInTheDocument()
128-
})
129-
130-
it('renders tab when flag is on', () => {
131-
setup()
132-
render(<Tabs />, { wrapper })
133-
134-
expect(
135-
screen.getByRole('link', {
136-
name: /Codecov AI beta/i,
137-
})
138-
).toBeInTheDocument()
139-
})
140-
})
141106
})

src/pages/OwnerPage/Tabs/Tabs.tsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,11 @@ import { Suspense } from 'react'
33

44
import config from 'config'
55

6-
import { useFlags } from 'shared/featureFlags'
7-
import Badge from 'ui/Badge'
86
import TabNavigation from 'ui/TabNavigation'
97

108
import TrialReminder from './TrialReminder'
119

1210
function Tabs() {
13-
const { codecovAiFeaturesTab } = useFlags({
14-
codecovAiFeaturesTab: false,
15-
})
16-
1711
return (
1812
<TabNavigation
1913
tabs={[
@@ -25,18 +19,6 @@ function Tabs() {
2519
pageName: 'analytics',
2620
children: 'Analytics',
2721
},
28-
...(codecovAiFeaturesTab
29-
? [
30-
{
31-
pageName: 'codecovAI',
32-
children: (
33-
<>
34-
Codecov AI <Badge>beta</Badge>{' '}
35-
</>
36-
),
37-
},
38-
]
39-
: []),
4022
...(config.IS_SELF_HOSTED
4123
? []
4224
: [{ pageName: 'membersTab' }, { pageName: 'planTab' }]),

0 commit comments

Comments
 (0)