Skip to content

Commit

Permalink
Add configuration manager tab to repo settings
Browse files Browse the repository at this point in the history
  • Loading branch information
spalmurray-codecov committed Jul 19, 2024
1 parent d980d71 commit d4a4f83
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 83 deletions.
2 changes: 1 addition & 1 deletion src/layouts/SidebarLayout/SidebarLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PropType from 'prop-types'
import ErrorBoundary from '../shared/ErrorBoundary'
import NetworkErrorBoundary from '../shared/NetworkErrorBoundary'

function SidebarLayout({ sidebar, children, className }) {
function SidebarLayout({ sidebar, children, className = '' }) {
return (
<div className="container flex flex-col lg:flex-row">
<ErrorBoundary sentryScopes={[['layout', 'sidebar']]}>
Expand Down
59 changes: 0 additions & 59 deletions src/pages/RepoPage/SettingsTab/SettingsTab.spec.jsx

This file was deleted.

106 changes: 106 additions & 0 deletions src/pages/RepoPage/SettingsTab/SettingsTab.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { render, screen } from '@testing-library/react'
import { MemoryRouter, Route } from 'react-router-dom'

import { useOwner } from 'services/user'
import { useFlags } from 'shared/featureFlags'

import SettingsTab from './SettingsTab'

jest.mock('services/user')
const mockedUseOwner = useOwner as jest.Mock
jest.mock('shared/featureFlags')
const mockedUseFlags = useFlags as jest.Mock

jest.mock('./tabs/GeneralTab', () => () => 'General Tab')

const wrapper: (initialEntries?: string) => React.FC<React.PropsWithChildren> =
(initialEntries = '/gh/codecov/codecov-client/settings') =>
({ children }) =>
(
<MemoryRouter initialEntries={[initialEntries]}>
<Route path="/:provider/:owner/:repo/settings">{children}</Route>
</MemoryRouter>
)

interface SetupArgs {
isCurrentUserPartOfOrg?: boolean
}

describe('SettingsTab', () => {
function setup({ isCurrentUserPartOfOrg = true }: SetupArgs) {
mockedUseOwner.mockReturnValue({ data: { isCurrentUserPartOfOrg } })
mockedUseFlags.mockReturnValue({ inAppMarketingTab: true })
}

describe('Render for a repo', () => {
it('renders the right links', async () => {
setup({})
render(<SettingsTab />, { wrapper: wrapper() })

expect(
await screen.findByRole('link', { name: /General/ })
).toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Configuration Manager/ })
).toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Yaml/ })
).toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Badge/ })
).toBeInTheDocument()
})

describe('with feature flag false', () => {
it('does not render the Configuration Manager tab', async () => {
setup({})
mockedUseFlags.mockReturnValue({ inAppMarketingTab: false })
render(<SettingsTab />, { wrapper: wrapper() })

expect(
await screen.findByRole('link', { name: /General/ })
).toBeInTheDocument()
expect(
screen.queryByRole('link', { name: /Configuration Manager/ })
).not.toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Yaml/ })
).toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Badge/ })
).toBeInTheDocument()
})
})
})

describe('Render with an unknown path', () => {
it('renders the right links', async () => {
setup({})
render(<SettingsTab />, {
wrapper: wrapper('/gh/codecov/codecov-client/settings/random'),
})

expect(
await screen.findByRole('link', { name: /General/ })
).toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Configuration Manager/ })
).toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Yaml/ })
).toBeInTheDocument()
expect(
await screen.findByRole('link', { name: /Badge/ })
).toBeInTheDocument()
})
})

describe('Render with user not part of org', () => {
it('renders 404', async () => {
setup({ isCurrentUserPartOfOrg: false })
render(<SettingsTab />, { wrapper: wrapper() })

expect(await screen.findByText('Error 404')).toBeInTheDocument()
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { SentryRoute } from 'sentry'

import SidebarLayout from 'layouts/SidebarLayout'
import { useOwner } from 'services/user'
import { useFlags } from 'shared/featureFlags'
import LoadingLogo from 'ui/LoadingLogo'
import Sidemenu from 'ui/Sidemenu'

import SideMenuSettings from './SideMenuSettings'
import ConfigurationManager from './tabs/ConfigurationManager'

const NotFound = lazy(() => import('../../NotFound'))
const GeneralTab = lazy(() => import('./tabs/GeneralTab'))
Expand All @@ -20,20 +22,45 @@ const tabLoading = (
</div>
)

interface URLParams {
owner: string
}

function SettingsTab() {
const { owner } = useParams()
const { owner } = useParams<URLParams>()
const { data: currentOwner } = useOwner({ username: owner })
const { inAppMarketingTab } = useFlags({
inAppMarketingTab: false,
})

if (!currentOwner?.isCurrentUserPartOfOrg) return <NotFound />

const inAppMarketingLink = inAppMarketingTab
? [{ pageName: 'settingsConfiguration' }]
: []
const sideMenuLinks = [
{
pageName: 'settingsGeneral',
exact: true,
},
...inAppMarketingLink,
{ pageName: 'settingsYaml' },
{ pageName: 'settingsBadge' },
]

return (
<div className="mt-2">
<SidebarLayout sidebar={<SideMenuSettings />}>
<SidebarLayout sidebar={<Sidemenu links={sideMenuLinks} />}>
<Suspense fallback={tabLoading}>
<Switch>
<SentryRoute path="/:provider/:owner/:repo/settings" exact>
<GeneralTab />
</SentryRoute>
{inAppMarketingTab ? (
<SentryRoute path="/:provider/:owner/:repo/settings/config" exact>
<ConfigurationManager />
</SentryRoute>
) : null}
<SentryRoute path="/:provider/:owner/:repo/settings/yaml" exact>
<YamlTab />
</SentryRoute>
Expand Down
20 changes: 0 additions & 20 deletions src/pages/RepoPage/SettingsTab/SideMenuSettings.jsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { render, screen } from '@testing-library/react'

import ConfigurationManager from './ConfigurationManager'

describe('Configuration Manager', () => {
it('temp: renders Configuration Manager', async () => {
render(<ConfigurationManager />)

const text = await screen.findByText('Configuration Manager')
expect(text).toBeInTheDocument()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function ConfigurationManager() {
return <p>Configuration Manager</p>
}

export default ConfigurationManager
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ConfigurationManager'
10 changes: 10 additions & 0 deletions src/services/navigation/useNavLinks/useNavLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,16 @@ export function useNavLinks() {
) => `/${provider}/${owner}/${repo}/settings`,
text: 'General',
},
settingsConfiguration: {
path: (
{ provider = p, owner = o, repo = r } = {
provider: p,
owner: o,
repo: r,
}
) => `/${provider}/${owner}/${repo}/settings/config`,
text: 'Configuration Manager',
},
settingsYaml: {
path: (
{ provider = p, owner = o, repo = r } = {
Expand Down

0 comments on commit d4a4f83

Please sign in to comment.