Skip to content

Commit 173686a

Browse files
authored
feat: Allow build time configuration of sunburst (#3689)
1 parent 50da594 commit 173686a

File tree

4 files changed

+103
-46
lines changed

4 files changed

+103
-46
lines changed

src/config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const defaultConfig = {
1212
SENTRY_ERROR_SAMPLE_RATE: 1.0,
1313
GH_APP: DEFAULT_GH_APP,
1414
GH_APP_AI: 'codecov-ai',
15+
SUNBURST_ENABLED: true,
1516
}
1617

1718
export function removeReactAppPrefix(obj) {
@@ -33,6 +34,10 @@ export function removeReactAppPrefix(obj) {
3334
keys['HIDE_ACCESS_TAB'] = keys['HIDE_ACCESS_TAB'].toLowerCase() === 'true'
3435
}
3536

37+
if ('SUNBURST_ENABLED' in keys) {
38+
keys['SUNBURST_ENABLED'] = keys['SUNBURST_ENABLED'].toLowerCase() === 'true'
39+
}
40+
3641
if ('SENTRY_TRACING_SAMPLE_RATE' in keys) {
3742
keys['SENTRY_TRACING_SAMPLE_RATE'] = parseFloat(
3843
keys['SENTRY_TRACING_SAMPLE_RATE']

src/config.test.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,14 @@ import { removeReactAppPrefix } from 'config'
33
describe('config', () => {
44
describe('removeReactAppPrefix', () => {
55
it('removes REACT_APP prefix', () => {
6-
const obj = {
7-
REACT_APP_TEST_ENV: 'test env',
8-
}
6+
const obj = { REACT_APP_TEST_ENV: 'test env' }
97

108
expect(removeReactAppPrefix(obj)).toEqual({ TEST_ENV: 'test env' })
119
})
1210

1311
describe('sets IS_SELF_HOSTED to boolean', () => {
1412
it('sets to true', () => {
15-
const obj = {
16-
ENV: 'enterprise',
17-
}
13+
const obj = { ENV: 'enterprise' }
1814

1915
expect(removeReactAppPrefix(obj)).toEqual({
2016
ENV: 'enterprise',
@@ -23,9 +19,7 @@ describe('config', () => {
2319
})
2420

2521
it('sets to false', () => {
26-
const obj = {
27-
ENV: 'production',
28-
}
22+
const obj = { ENV: 'production' }
2923

3024
expect(removeReactAppPrefix(obj)).toEqual({
3125
ENV: 'production',
@@ -68,6 +62,14 @@ describe('config', () => {
6862
})
6963
})
7064

65+
describe('sets SUNBURST_ENABLED to boolean', () => {
66+
it('sets to true', () => {
67+
const obj = { SUNBURST_ENABLED: 'true' }
68+
69+
expect(removeReactAppPrefix(obj)).toEqual({ SUNBURST_ENABLED: true })
70+
})
71+
})
72+
7173
describe('sets IS_DEDICATED_NAMESPACE to boolean', () => {
7274
it('sets to true', () => {
7375
const obj = {

src/pages/RepoPage/CoverageTab/OverviewTab/OverviewTab.test.tsx

Lines changed: 83 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { setupServer } from 'msw/node'
99
import { Suspense } from 'react'
1010
import { MemoryRouter, Route } from 'react-router-dom'
1111

12+
import config from 'config'
13+
1214
import CoverageOverviewTab from './OverviewTab'
1315

1416
declare global {
@@ -17,6 +19,8 @@ declare global {
1719
}
1820
}
1921

22+
vi.mock('config')
23+
2024
vi.mock('recharts', async () => {
2125
const OriginalModule = await vi.importActual('recharts')
2226
return {
@@ -35,22 +39,6 @@ vi.mock('./SummaryTeamPlan', () => ({ default: () => 'SummaryTeamPlan' }))
3539
vi.mock('./subroute/Sunburst', () => ({ default: () => 'Sunburst' }))
3640
vi.mock('./subroute/Fileviewer', () => ({ default: () => 'FileViewer' }))
3741

38-
const mockRepoSettings = (isPrivate = false) => ({
39-
owner: {
40-
isCurrentUserPartOfOrg: true,
41-
repository: {
42-
defaultBranch: 'master',
43-
private: isPrivate,
44-
uploadToken: 'token',
45-
graphToken: 'token',
46-
yaml: 'yaml',
47-
bot: {
48-
username: 'test',
49-
},
50-
},
51-
},
52-
})
53-
5442
const mockRepo = (isPrivate = false, isFirstPullRequest = false) => ({
5543
owner: {
5644
isCurrentUserPartOfOrg: true,
@@ -268,6 +256,24 @@ const mockBackfillFlag = {
268256
},
269257
}
270258

259+
const mockRepoSettingsTeamData = (isPrivate = false) => ({
260+
owner: {
261+
isCurrentUserPartOfOrg: null,
262+
repository: {
263+
__typename: 'Repository',
264+
defaultBranch: 'master',
265+
private: isPrivate,
266+
uploadToken: 'token',
267+
graphToken: 'token',
268+
yaml: 'yaml',
269+
bot: {
270+
username: 'test',
271+
},
272+
activated: true,
273+
},
274+
},
275+
})
276+
271277
const server = setupServer()
272278
const queryClient = new QueryClient({
273279
defaultOptions: { queries: { retry: false } },
@@ -326,6 +332,7 @@ beforeEach(() => {
326332
})
327333

328334
afterEach(() => {
335+
vi.clearAllMocks()
329336
queryClient.clear()
330337
queryClientV5.clear()
331338
server.resetHandlers()
@@ -340,6 +347,7 @@ interface SetupArgs {
340347
isPrivate?: boolean
341348
isTeamPlan?: boolean
342349
fileCount?: number
350+
sunburstEnabled?: boolean
343351
}
344352

345353
describe('Coverage overview tab', () => {
@@ -348,7 +356,10 @@ describe('Coverage overview tab', () => {
348356
isPrivate = false,
349357
isTeamPlan = false,
350358
fileCount = 10,
359+
sunburstEnabled = true,
351360
}: SetupArgs) {
361+
config.SUNBURST_ENABLED = sunburstEnabled
362+
352363
server.use(
353364
graphql.query('GetRepo', () => {
354365
return HttpResponse.json({
@@ -389,7 +400,7 @@ describe('Coverage overview tab', () => {
389400
})
390401
}),
391402
graphql.query('GetRepoSettingsTeam', () => {
392-
return HttpResponse.json({ data: mockRepoSettings(isPrivate) })
403+
return HttpResponse.json({ data: mockRepoSettingsTeamData(isPrivate) })
393404
}),
394405
graphql.query('CoverageTabData', () => {
395406
return HttpResponse.json({ data: mockCoverageTabData(fileCount) })
@@ -426,33 +437,69 @@ describe('Coverage overview tab', () => {
426437
expect(summary).toBeInTheDocument()
427438
})
428439

429-
describe('file count is under 200_000', () => {
430-
it('renders the sunburst chart', async () => {
431-
setup({ fileCount: 100 })
432-
render(<CoverageOverviewTab />, {
433-
wrapper: wrapper(['/gh/test-org/repoName']),
440+
describe('rendering sunburst', () => {
441+
describe('file count is under 200_000', () => {
442+
describe('sunburst is enabled', () => {
443+
it('renders the sunburst chart', async () => {
444+
setup({ fileCount: 100, sunburstEnabled: true })
445+
render(<CoverageOverviewTab />, {
446+
wrapper: wrapper(['/gh/test-org/repoName']),
447+
})
448+
449+
const hideChart = await screen.findByText(/Hide charts/)
450+
expect(hideChart).toBeInTheDocument()
451+
452+
const sunburst = await screen.findByText('Sunburst')
453+
expect(sunburst).toBeInTheDocument()
454+
})
434455
})
435456

436-
const hideChart = await screen.findByText(/Hide charts/)
437-
expect(hideChart).toBeInTheDocument()
457+
describe('sunburst is disabled', () => {
458+
it('does not render the sunburst chart', async () => {
459+
setup({ fileCount: 100, sunburstEnabled: false })
460+
render(<CoverageOverviewTab />, {
461+
wrapper: wrapper(['/gh/test-org/repoName']),
462+
})
438463

439-
const sunburst = await screen.findByText('Sunburst')
440-
expect(sunburst).toBeInTheDocument()
464+
const hideChart = await screen.findByText(/Hide charts/)
465+
expect(hideChart).toBeInTheDocument()
466+
467+
const sunburst = screen.queryByText('Sunburst')
468+
await waitFor(() => expect(sunburst).not.toBeInTheDocument())
469+
})
470+
})
441471
})
442-
})
443472

444-
describe('file count is above 200_000', () => {
445-
it('does not render the sunburst chart', async () => {
446-
setup({ fileCount: 500_000 })
447-
render(<CoverageOverviewTab />, {
448-
wrapper: wrapper(['/gh/test-org/repoName']),
473+
describe('file count is above 200_000', () => {
474+
describe('sunburst is enabled', () => {
475+
it('does not render the sunburst chart', async () => {
476+
setup({ fileCount: 500_000, sunburstEnabled: true })
477+
render(<CoverageOverviewTab />, {
478+
wrapper: wrapper(['/gh/test-org/repoName']),
479+
})
480+
481+
const hideChart = await screen.findByText(/Hide charts/)
482+
expect(hideChart).toBeInTheDocument()
483+
484+
const sunburst = screen.queryByText('Sunburst')
485+
await waitFor(() => expect(sunburst).not.toBeInTheDocument())
486+
})
449487
})
450488

451-
const hideChart = await screen.findByText(/Hide charts/)
452-
expect(hideChart).toBeInTheDocument()
489+
describe('sunburst is disabled', () => {
490+
it('does not render the sunburst chart', async () => {
491+
setup({ fileCount: 500_000, sunburstEnabled: false })
492+
render(<CoverageOverviewTab />, {
493+
wrapper: wrapper(['/gh/test-org/repoName']),
494+
})
453495

454-
const sunburst = screen.queryByText('Sunburst')
455-
await waitFor(() => expect(sunburst).not.toBeInTheDocument())
496+
const hideChart = await screen.findByText(/Hide charts/)
497+
expect(hideChart).toBeInTheDocument()
498+
499+
const sunburst = screen.queryByText('Sunburst')
500+
await waitFor(() => expect(sunburst).not.toBeInTheDocument())
501+
})
502+
})
456503
})
457504
})
458505

src/pages/RepoPage/CoverageTab/OverviewTab/OverviewTab.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { useSuspenseQuery as useSuspenseQueryV5 } from '@tanstack/react-queryV5'
22
import { lazy, Suspense } from 'react'
33
import { Switch, useParams } from 'react-router-dom'
44

5+
import config from 'config'
6+
57
import { SentryRoute } from 'sentry'
68

79
import SilentNetworkErrorWrapper from 'layouts/shared/SilentNetworkErrorWrapper'
@@ -71,7 +73,8 @@ function CoverageOverviewTab() {
7173
typeof fileCount === 'number' && fileCount <= MAX_FILE_COUNT
7274

7375
let displaySunburst = false
74-
if (withinFileCount) {
76+
// only enable sunburst when both cases are met
77+
if (withinFileCount && config.SUNBURST_ENABLED) {
7578
displaySunburst = true
7679
}
7780

0 commit comments

Comments
 (0)