From 687e4c8d3830ff68fe39f60d8db18e9afe007bc6 Mon Sep 17 00:00:00 2001 From: Matteo Mara Date: Mon, 10 Oct 2022 16:07:02 +0200 Subject: [PATCH] SONAR-17118 migrate branch support flag to features/list API --- .../js/app/components/ComponentContainer.tsx | 20 ++++---- .../__tests__/ComponentContainer-test.tsx | 8 ++-- .../js/app/components/nav/component/Menu.tsx | 13 ++--- .../nav/component/__tests__/Menu-test.tsx | 3 +- .../__snapshots__/Header-test.tsx.snap | 2 +- .../branch-like/BranchLikeNavigation.tsx | 17 +++---- .../__tests__/BranchLikeNavigation-test.tsx | 9 ++-- .../components/RuleDetailsIssues.tsx | 13 ++--- .../__tests__/RuleDetailsIssues-test.tsx | 3 +- .../__snapshots__/RuleDetails-test.tsx.snap | 2 +- .../apps/create/project/CreateProjectPage.tsx | 13 +++-- .../__tests__/CreateProjectPage-test.tsx | 1 + .../main/js/apps/overview/components/App.tsx | 22 ++++----- .../components/__tests__/App-test.tsx | 8 +++- .../apps/projectBaseline/components/App.tsx | 19 +++++--- .../components/__tests__/App-test.tsx | 5 +- .../quality-gates/components/Conditions.tsx | 14 +++--- .../components/__tests__/App-it.tsx | 11 ++--- .../components/AdditionalCategories.tsx | 4 +- .../settings/components/AllCategoriesList.tsx | 15 +++--- .../__tests__/AllCategoriesList-test.tsx | 7 ++- .../AdditionalCategories-test.tsx.snap | 2 +- .../SettingsAppRenderer-test.tsx.snap | 4 +- .../almIntegration/AlmIntegration.tsx | 18 +++---- .../__tests__/AlmIntegration-test.tsx | 5 +- .../AlmIntegration-test.tsx.snap | 1 + .../TutorialSelectionRenderer-test.tsx.snap | 2 +- .../__tests__/AzurePipelinesTutorial-it.tsx | 9 ++-- .../azure-pipelines/commands/PublishSteps.tsx | 20 ++++---- .../bitbucket-pipelines/AnalysisCommand.tsx | 20 ++++---- .../__tests__/AnalysisCommand-test.tsx | 9 ++-- .../tutorials/components/AllSet.tsx | 20 ++++---- .../components/__tests__/AllSet-test.tsx | 7 +-- .../github-action/AnalysisCommand.tsx | 48 +++++++++++++------ .../__tests__/AnalysisCommand-test.tsx | 3 +- .../AnalysisCommand-test.tsx.snap | 5 ++ .../tutorials/gitlabci/YmlFileStep.tsx | 24 ++++------ .../gitlabci/__tests__/YmlFileStep-test.tsx | 11 ++--- .../GitLabCITutorial-test.tsx.snap | 2 +- .../tutorials/jenkins/JenkinsTutorial.tsx | 27 +++++------ .../__tests__/JenkinsTutorial-test.tsx | 7 +-- .../main/js/helpers/testReactTestingUtils.tsx | 32 ++++++++----- .../sonar-web/src/main/js/types/appstate.ts | 1 - .../sonar-web/src/main/js/types/features.ts | 3 +- .../server/branch/BranchFeatureExtension.java | 3 +- .../org/sonar/server/ui/ws/GlobalAction.java | 10 +--- .../sonar/server/ui/ws/global-example.json | 1 - .../sonar/server/ui/ws/GlobalActionTest.java | 12 +---- 48 files changed, 252 insertions(+), 263 deletions(-) diff --git a/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx index 1e788618770..f4dfc260e65 100644 --- a/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx @@ -38,21 +38,22 @@ import { ProjectAlmBindingConfigurationErrors, ProjectAlmBindingResponse } from '../../types/alm-settings'; -import { AppState } from '../../types/appstate'; import { BranchLike } from '../../types/branch-like'; import { ComponentQualifier, isPortfolioLike } from '../../types/component'; +import { Feature } from '../../types/features'; import { Task, TaskStatuses, TaskTypes, TaskWarning } from '../../types/tasks'; import { Component, Status } from '../../types/types'; import handleRequiredAuthorization from '../utils/handleRequiredAuthorization'; -import withAppStateContext from './app-state/withAppStateContext'; +import withAvailableFeatures, { + WithAvailableFeaturesProps +} from './available-features/withAvailableFeatures'; import withBranchStatusActions from './branch-status/withBranchStatusActions'; import ComponentContainerNotFound from './ComponentContainerNotFound'; import { ComponentContext } from './componentContext/ComponentContext'; import PageUnavailableDueToIndexation from './indexation/PageUnavailableDueToIndexation'; import ComponentNav from './nav/component/ComponentNav'; -interface Props { - appState: AppState; +interface Props extends WithAvailableFeaturesProps { location: Location; updateBranchStatus: (branchLike: BranchLike, component: string, status: Status) => void; router: Router; @@ -155,9 +156,7 @@ export class ComponentContainer extends React.PureComponent { }; fetchBranches = async (componentWithQualifier: Component) => { - const { - appState: { branchesEnabled } - } = this.props; + const { hasFeature } = this.props; const breadcrumb = componentWithQualifier.breadcrumbs.find(({ qualifier }) => { return ([ComponentQualifier.Application, ComponentQualifier.Project] as string[]).includes( @@ -172,7 +171,8 @@ export class ComponentContainer extends React.PureComponent { const { key } = breadcrumb; const [branches, pullRequests] = await Promise.all([ getBranches(key), - !branchesEnabled || breadcrumb.qualifier === ComponentQualifier.Application + !hasFeature(Feature.BranchSupport) || + breadcrumb.qualifier === ComponentQualifier.Application ? Promise.resolve([]) : getPullRequests(key) ]); @@ -251,7 +251,7 @@ export class ComponentContainer extends React.PureComponent { if ( component.qualifier === ComponentQualifier.Project && component.analysisDate === undefined && - this.props.appState.branchesEnabled + this.props.hasFeature(Feature.BranchSupport) ) { const projectBindingErrors = await validateProjectAlmBinding(component.key).catch( () => undefined @@ -471,4 +471,4 @@ export class ComponentContainer extends React.PureComponent { } } -export default withRouter(withAppStateContext(withBranchStatusActions(ComponentContainer))); +export default withRouter(withAvailableFeatures(withBranchStatusActions(ComponentContainer))); diff --git a/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx index 45c4bfe9c6e..9e571d079a1 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx +++ b/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx @@ -29,7 +29,7 @@ import { mockBranch, mockMainBranch, mockPullRequest } from '../../../helpers/mo import { mockComponent } from '../../../helpers/mocks/component'; import { mockTask } from '../../../helpers/mocks/tasks'; import { HttpStatus } from '../../../helpers/request'; -import { mockAppState, mockLocation, mockRouter } from '../../../helpers/testMocks'; +import { mockLocation, mockRouter } from '../../../helpers/testMocks'; import { waitAndUpdate } from '../../../helpers/testUtils'; import { AlmKeys } from '../../../types/alm-settings'; import { ComponentQualifier } from '../../../types/component'; @@ -141,7 +141,7 @@ it("doesn't load branches portfolio", async () => { it('updates branches on change', async () => { const updateBranchStatus = jest.fn(); const wrapper = shallowRender({ - appState: mockAppState({ branchesEnabled: true }), + hasFeature: () => true, location: mockLocation({ query: { id: 'portfolioKey' } }), updateBranchStatus }); @@ -403,7 +403,7 @@ describe('should correctly validate the project binding depending on the context (validateProjectAlmBinding as jest.Mock).mockResolvedValueOnce(projectBindingErrors); } - const wrapper = shallowRender({ appState: mockAppState({ branchesEnabled: true }) }); + const wrapper = shallowRender({ hasFeature: () => true }); await waitAndUpdate(wrapper); expect(wrapper.state().projectBindingErrors).toBe(projectBindingErrors); @@ -435,7 +435,7 @@ it.each([ function shallowRender(props: Partial = {}) { return shallow( { renderBranchesLink = (query: Query, isProject: boolean) => { if ( - !this.props.appState.branchesEnabled || + !this.props.hasFeature(Feature.BranchSupport) || !isProject || !this.getConfiguration().showSettings ) { @@ -641,4 +642,4 @@ export class Menu extends React.PureComponent { } } -export default withAppStateContext(Menu); +export default withAvailableFeatures(Menu); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/Menu-test.tsx b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/Menu-test.tsx index 1ffc075f483..fe446883e96 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/Menu-test.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/Menu-test.tsx @@ -25,7 +25,6 @@ import { mockPullRequest } from '../../../../../helpers/mocks/branch-like'; import { mockComponent } from '../../../../../helpers/mocks/component'; -import { mockAppState } from '../../../../../helpers/testMocks'; import { renderComponent } from '../../../../../helpers/testReactTestingUtils'; import { ComponentQualifier } from '../../../../../types/component'; import { Menu } from '../Menu'; @@ -139,7 +138,7 @@ function renderMenu(props: Partial = {}) { const mainBranch = mockMainBranch(); return renderComponent( - = 2; - const isMenuEnabled = branchesEnabled && hasManyBranches; + const isMenuEnabled = branchSupportEnabled && hasManyBranches; const currentBranchLikeElement = ( { }); it('should render the menu trigger if branches are enabled', () => { - const wrapper = shallowRender({ appState: mockAppState({ branchesEnabled: true }) }); + const wrapper = shallowRender({ hasFeature: () => true }); expect(wrapper).toMatchSnapshot(); }); it('should properly toggle menu opening when clicking the anchor', () => { - const wrapper = shallowRender({ appState: mockAppState({ branchesEnabled: true }) }); + const wrapper = shallowRender({ hasFeature: () => true }); expect(wrapper.find(Toggler).props().open).toBe(false); click(wrapper.find(ButtonPlain)); @@ -49,7 +48,7 @@ it('should properly toggle menu opening when clicking the anchor', () => { }); it('should properly close menu when toggler asks for', () => { - const wrapper = shallowRender({ appState: mockAppState({ branchesEnabled: true }) }); + const wrapper = shallowRender({ hasFeature: () => true }); expect(wrapper.find(Toggler).props().open).toBe(false); click(wrapper.find(ButtonPlain)); @@ -67,7 +66,7 @@ function shallowRender(props?: Partial) { return shallow( ; } @@ -118,7 +119,7 @@ export class RuleDetailsIssues extends React.PureComponent { ); - if (!this.props.appState.branchesEnabled) { + if (!this.props.hasFeature(Feature.BranchSupport)) { return totalItem; } @@ -176,4 +177,4 @@ export class RuleDetailsIssues extends React.PureComponent { } } -export default withAppStateContext(RuleDetailsIssues); +export default withAvailableFeatures(RuleDetailsIssues); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleDetailsIssues-test.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleDetailsIssues-test.tsx index 7aeb0542100..16865c5ea2e 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleDetailsIssues-test.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleDetailsIssues-test.tsx @@ -20,7 +20,6 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { getFacet } from '../../../../api/issues'; -import { mockAppState } from '../../../../helpers/testMocks'; import { waitAndUpdate } from '../../../../helpers/testUtils'; import { RuleDetailsIssues } from '../RuleDetailsIssues'; @@ -60,7 +59,7 @@ it('should fetch issues and render', async () => { function shallowRender(props: Partial = {}) { return shallow( diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetails-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetails-test.tsx.snap index 39780c67157..450d9d3ecc0 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetails-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetails-test.tsx.snap @@ -174,7 +174,7 @@ exports[`should render correctly: loaded 1`] = ` } } /> - { renderProjectCreation(mode?: CreateProjectModes) { const { - appState: { canAdmin, branchesEnabled }, + appState: { canAdmin }, location, router } = this.props; @@ -156,6 +160,7 @@ export class CreateProjectPage extends React.PureComponent { gitlabSettings, loading } = this.state; + const branchSupportEnabled = this.props.hasFeature(Feature.BranchSupport); switch (mode) { case CreateProjectModes.AzureDevOps: { @@ -221,7 +226,7 @@ export class CreateProjectPage extends React.PureComponent { case CreateProjectModes.Manual: { return ( ); @@ -272,4 +277,4 @@ export class CreateProjectPage extends React.PureComponent { } } -export default withRouter(withAppStateContext(CreateProjectPage)); +export default withRouter(withAvailableFeatures(withAppStateContext(CreateProjectPage))); diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPage-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPage-test.tsx index 31dd8c7ca2f..d508cda2e7a 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPage-test.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPage-test.tsx @@ -128,6 +128,7 @@ function shallowRender(props: Partial = {}) { return shallow( { }; render() { - const { - appState: { branchesEnabled }, - branchLike, - branchLikes, - component, - projectBinding - } = this.props; + const { branchLike, branchLikes, component, projectBinding } = this.props; + const branchSupportEnabled = this.props.hasFeature(Feature.BranchSupport); if (this.isPortfolio()) { return null; @@ -81,7 +77,7 @@ export class App extends React.PureComponent { {component.analysisDate && ( @@ -91,4 +87,4 @@ export class App extends React.PureComponent { } } -export default withComponentContext(withAppStateContext(App)); +export default withComponentContext(withAvailableFeatures(App)); diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.tsx index 505ed021c24..6d9959e0bf5 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.tsx @@ -19,7 +19,6 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { mockAppState } from '../../../../helpers/testMocks'; import BranchOverview from '../../branches/BranchOverview'; import { App } from '../App'; @@ -42,6 +41,11 @@ it('should render BranchOverview', () => { function getWrapper(props = {}) { return shallow( - + ); } diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/App.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/App.tsx index a9021768e71..a68bf11ed8f 100644 --- a/server/sonar-web/src/main/js/apps/projectBaseline/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/App.tsx @@ -22,6 +22,9 @@ import { debounce } from 'lodash'; import * as React from 'react'; import { getNewCodePeriod, resetNewCodePeriod, setNewCodePeriod } from '../../../api/newCodePeriod'; import withAppStateContext from '../../../app/components/app-state/withAppStateContext'; +import withAvailableFeatures, { + WithAvailableFeaturesProps +} from '../../../app/components/available-features/withAvailableFeatures'; import withComponentContext from '../../../app/components/componentContext/withComponentContext'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import AlertSuccessIcon from '../../../components/icons/AlertSuccessIcon'; @@ -30,6 +33,7 @@ import { isBranch, sortBranches } from '../../../helpers/branch-like'; import { translate } from '../../../helpers/l10n'; import { AppState } from '../../../types/appstate'; import { Branch, BranchLike } from '../../../types/branch-like'; +import { Feature } from '../../../types/features'; import { Component, NewCodePeriod, @@ -42,7 +46,7 @@ import AppHeader from './AppHeader'; import BranchList from './BranchList'; import ProjectBaselineSelector from './ProjectBaselineSelector'; -interface Props { +interface Props extends WithAvailableFeaturesProps { branchLike: Branch; branchLikes: BranchLike[]; component: Component; @@ -129,14 +133,14 @@ export class App extends React.PureComponent { } fetchLeakPeriodSetting() { - const { branchLike, appState, component } = this.props; + const { branchLike, component } = this.props; this.setState({ loading: true }); Promise.all([ getNewCodePeriod(), getNewCodePeriod({ - branch: appState.branchesEnabled ? undefined : branchLike.name, + branch: this.props.hasFeature(Feature.BranchSupport) ? undefined : branchLike.name, project: component.key }) ]).then( @@ -252,6 +256,7 @@ export class App extends React.PureComponent { selected, success } = this.state; + const branchSupportEnabled = this.props.hasFeature(Feature.BranchSupport); return ( <> @@ -262,14 +267,14 @@ export class App extends React.PureComponent { ) : (
- {appState.branchesEnabled &&

{translate('project_baseline.default_setting')}

} + {branchSupportEnabled &&

{translate('project_baseline.default_setting')}

} {generalSetting && overrideGeneralSetting !== undefined && ( { {translate('settings.state.saved')}
- {generalSetting && appState.branchesEnabled && ( + {generalSetting && branchSupportEnabled && (

{translate('project_baseline.configure_branches')}

@@ -321,4 +326,4 @@ export class App extends React.PureComponent { } } -export default withComponentContext(withAppStateContext(App)); +export default withComponentContext(withAvailableFeatures(withAppStateContext(App))); diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/App-test.tsx index 9ceb6e3b6e3..cbf4f74058f 100644 --- a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/App-test.tsx +++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/App-test.tsx @@ -41,7 +41,7 @@ it('should render correctly', async () => { await waitAndUpdate(wrapper); expect(wrapper).toMatchSnapshot(); - wrapper = shallowRender({ appState: mockAppState({ branchesEnabled: false, canAdmin: true }) }); + wrapper = shallowRender({ appState: mockAppState({ canAdmin: true }), hasFeature: () => false }); await waitAndUpdate(wrapper); expect(wrapper).toMatchSnapshot('without branch support'); }); @@ -109,7 +109,8 @@ function shallowRender(props: Partial = {}) { diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx index 14f98297bf7..1df8b307482 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx @@ -19,7 +19,9 @@ */ import { differenceWith, map, sortBy, uniqBy } from 'lodash'; import * as React from 'react'; -import withAppStateContext from '../../../app/components/app-state/withAppStateContext'; +import withAvailableFeatures, { + WithAvailableFeaturesProps +} from '../../../app/components/available-features/withAvailableFeatures'; import withMetricsContext from '../../../app/components/metrics/withMetricsContext'; import DocumentationTooltip from '../../../components/common/DocumentationTooltip'; import { Button } from '../../../components/controls/buttons'; @@ -27,14 +29,13 @@ import ModalButton from '../../../components/controls/ModalButton'; import { Alert } from '../../../components/ui/Alert'; import { getLocalizedMetricName, translate } from '../../../helpers/l10n'; import { isDiffMetric } from '../../../helpers/measures'; -import { AppState } from '../../../types/appstate'; +import { Feature } from '../../../types/features'; import { MetricKey } from '../../../types/metrics'; import { Condition as ConditionType, Dict, Metric, QualityGate } from '../../../types/types'; import Condition from './Condition'; import ConditionModal from './ConditionModal'; -interface Props { - appState: AppState; +interface Props extends WithAvailableFeaturesProps { canEdit: boolean; conditions: ConditionType[]; metrics: Dict; @@ -56,7 +57,6 @@ const FORBIDDEN_METRICS: string[] = [ export class Conditions extends React.PureComponent { renderConditionsTable = (conditions: ConditionType[], scope: 'new' | 'overall') => { const { - appState, qualityGate, metrics, canEdit, @@ -74,7 +74,7 @@ export class Conditions extends React.PureComponent {

{translate(captionTranslationId, 'long')}

- {appState.branchesEnabled && ( + {this.props.hasFeature(Feature.BranchSupport) && (

{translate(captionTranslationId, 'description')}

@@ -222,4 +222,4 @@ export class Conditions extends React.PureComponent { } } -export default withMetricsContext(withAppStateContext(Conditions)); +export default withMetricsContext(withAvailableFeatures(Conditions)); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/App-it.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/App-it.tsx index be1520ef628..a6aedcef3fb 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/App-it.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/App-it.tsx @@ -22,9 +22,8 @@ import userEvent from '@testing-library/user-event'; import selectEvent from 'react-select-event'; import { QualityGatesServiceMock } from '../../../../api/mocks/QualityGatesServiceMock'; import { searchProjects, searchUsers } from '../../../../api/quality-gates'; -import { mockAppState } from '../../../../helpers/testMocks'; -import { renderAppRoutes } from '../../../../helpers/testReactTestingUtils'; -import { AppState } from '../../../../types/appstate'; +import { renderAppRoutes, RenderContext } from '../../../../helpers/testReactTestingUtils'; +import { Feature } from '../../../../types/features'; import routes from '../../routes'; jest.mock('../../../../api/quality-gates'); @@ -266,7 +265,7 @@ it('should be able to handle delete condition', async () => { }); it('should explain condition on branch', async () => { - renderQualityGateApp(mockAppState({ branchesEnabled: true })); + renderQualityGateApp({ featureList: [Feature.BranchSupport] }); expect( await screen.findByText('quality_gates.conditions.new_code.description') @@ -487,6 +486,6 @@ describe('The Permissions section', () => { }); }); -function renderQualityGateApp(appState?: AppState) { - renderAppRoutes('quality_gates', routes, { appState }); +function renderQualityGateApp(context?: RenderContext) { + renderAppRoutes('quality_gates', routes, context); } diff --git a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx index 6476bb8f1bb..b536a500624 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/AdditionalCategories.tsx @@ -50,7 +50,7 @@ export interface AdditionalCategory { key: string; name: string; renderComponent: (props: AdditionalCategoryComponentProps) => React.ReactNode; - requiresBranchesEnabled?: boolean; + requiresBranchSupport?: boolean; } export const ADDITIONAL_CATEGORIES: AdditionalCategory[] = [ @@ -93,7 +93,7 @@ export const ADDITIONAL_CATEGORIES: AdditionalCategory[] = [ availableGlobally: false, availableForProject: true, displayTab: true, - requiresBranchesEnabled: true + requiresBranchSupport: true }, { key: AUTHENTICATION_CATEGORY, diff --git a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx index d0b0c01a8a7..cb32f4830db 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.tsx @@ -21,16 +21,17 @@ import classNames from 'classnames'; import { sortBy } from 'lodash'; import * as React from 'react'; import { NavLink } from 'react-router-dom'; -import withAppStateContext from '../../../app/components/app-state/withAppStateContext'; +import withAvailableFeatures, { + WithAvailableFeaturesProps +} from '../../../app/components/available-features/withAvailableFeatures'; import { getGlobalSettingsUrl, getProjectSettingsUrl } from '../../../helpers/urls'; -import { AppState } from '../../../types/appstate'; +import { Feature } from '../../../types/features'; import { Component } from '../../../types/types'; import { CATEGORY_OVERRIDES } from '../constants'; import { getCategoryName } from '../utils'; import { ADDITIONAL_CATEGORIES } from './AdditionalCategories'; -export interface CategoriesListProps { - appState: AppState; +export interface CategoriesListProps extends WithAvailableFeaturesProps { categories: string[]; component?: Component; defaultCategory: string; @@ -38,7 +39,7 @@ export interface CategoriesListProps { } export function CategoriesList(props: CategoriesListProps) { - const { appState, categories, component, defaultCategory, selectedCategory } = props; + const { categories, component, defaultCategory, selectedCategory } = props; const categoriesWithName = categories .filter(key => !CATEGORY_OVERRIDES[key.toLowerCase()]) @@ -55,7 +56,7 @@ export function CategoriesList(props: CategoriesListProps) { : // Global settings c.availableGlobally ) - .filter(c => appState.branchesEnabled || !c.requiresBranchesEnabled) + .filter(c => props.hasFeature(Feature.BranchSupport) || !c.requiresBranchSupport) ); const sortedCategories = sortBy(categoriesWithName, category => category.name.toLowerCase()); @@ -87,4 +88,4 @@ export function CategoriesList(props: CategoriesListProps) { ); } -export default withAppStateContext(CategoriesList); +export default withAvailableFeatures(CategoriesList); diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx index 94ff4c16fcc..a45a2368eca 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/AllCategoriesList-test.tsx @@ -20,7 +20,6 @@ import { screen } from '@testing-library/dom'; import * as React from 'react'; import { mockComponent } from '../../../../helpers/mocks/component'; -import { mockAppState } from '../../../../helpers/testMocks'; import { renderComponent } from '../../../../helpers/testReactTestingUtils'; import { AdditionalCategory } from '../AdditionalCategories'; import { CategoriesList, CategoriesListProps } from '../AllCategoriesList'; @@ -34,7 +33,7 @@ jest.mock('../AdditionalCategories', () => ({ availableGlobally: true, availableForProject: true, displayTab: true, - requiresBranchesEnabled: true + requiresBranchSupport: true }, { key: 'CAT_2', @@ -83,7 +82,7 @@ it('should correctly for project', () => { }); it('should render correctly when branches are disabled', () => { - renderCategoriesList({ appState: mockAppState({ branchesEnabled: false }) }); + renderCategoriesList({ hasFeature: () => false }); expect(screen.queryByText('CAT_1_NAME')).not.toBeInTheDocument(); expect(screen.getByText('CAT_2_NAME')).toBeInTheDocument(); @@ -93,7 +92,7 @@ it('should render correctly when branches are disabled', () => { function renderCategoriesList(props?: Partial) { return renderComponent( - - boolean; location: Location; router: Router; @@ -212,10 +211,7 @@ export class AlmIntegration extends React.PureComponent { }; render() { - const { - appState: { branchesEnabled }, - hasFeature - } = this.props; + const { hasFeature } = this.props; const { currentAlmTab, definitionKeyForDeletion, @@ -228,7 +224,7 @@ export class AlmIntegration extends React.PureComponent { return ( { } } -export default withRouter(withAppStateContext(withAvailableFeatures(AlmIntegration))); +export default withRouter(withAvailableFeatures(AlmIntegration)); diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx index e8ec58bb592..29f7f5b790d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx @@ -25,7 +25,7 @@ import { getAlmDefinitions, validateAlmSettings } from '../../../../../api/alm-settings'; -import { mockAppState, mockLocation, mockRouter } from '../../../../../helpers/testMocks'; +import { mockLocation, mockRouter } from '../../../../../helpers/testMocks'; import { waitAndUpdate } from '../../../../../helpers/testUtils'; import { AlmKeys, AlmSettingsBindingStatusType } from '../../../../../types/alm-settings'; import { AlmIntegration } from '../AlmIntegration'; @@ -189,9 +189,8 @@ it('should detect the current ALM from the query', () => { function shallowRender(props: Partial = {}) { return shallow( diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap index c84b2fc9fc2..116616c5808 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap @@ -16,6 +16,7 @@ exports[`should render correctly 1`] = ` } loadingAlmDefinitions={true} loadingProjectCount={false} + multipleAlmEnabled={true} onCancelDelete={[Function]} onCheckConfiguration={[Function]} onConfirmDelete={[Function]} diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap index 0b023b704df..93fcf70abe1 100644 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap @@ -496,7 +496,7 @@ exports[`should render correctly: gitlab tutorial 1`] = ` exports[`should render correctly: jenkins tutorial 1`] = ` - = {}, - { - appState = mockAppState({ branchesEnabled: true }), - languages = { c: mockLanguage({ key: 'c' }) } - }: RenderContext = {} + { languages = { c: mockLanguage({ key: 'c' }) } }: RenderContext = {} ) { return renderApp( '/', @@ -234,7 +231,7 @@ function renderAzurePipelinesTutorial( willRefreshAutomatically={true} {...props} />, - { appState, languages } + { languages } ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx index a259ac50553..ea1ed9c725f 100644 --- a/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/azure-pipelines/commands/PublishSteps.tsx @@ -19,22 +19,20 @@ */ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; -import withAppStateContext from '../../../../app/components/app-state/withAppStateContext'; +import withAvailableFeatures, { + WithAvailableFeaturesProps +} from '../../../../app/components/available-features/withAvailableFeatures'; import { Alert } from '../../../../components/ui/Alert'; import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants'; import { translate } from '../../../../helpers/l10n'; import { AlmKeys } from '../../../../types/alm-settings'; -import { AppState } from '../../../../types/appstate'; +import { Feature } from '../../../../types/features'; import Link from '../../../common/Link'; import SentenceWithHighlights from '../../components/SentenceWithHighlights'; -export interface PublishStepsProps { - appState: AppState; -} +export interface PublishStepsProps extends WithAvailableFeaturesProps {} export function PublishSteps(props: PublishStepsProps) { - const { - appState: { branchesEnabled } - } = props; + const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); return ( <> @@ -52,14 +50,14 @@ export function PublishSteps(props: PublishStepsProps) {
  • - {branchesEnabled && ( + {branchSupportEnabled && ( <>
    @@ -68,4 +66,4 @@ export function AnalysisCommand(props: AnalysisCommandProps) { ); } -export default withAppStateContext(AnalysisCommand); +export default withAvailableFeatures(AnalysisCommand); diff --git a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/AnalysisCommand-test.tsx b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/AnalysisCommand-test.tsx index be1f33ab227..a3f9602d9ff 100644 --- a/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/AnalysisCommand-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/bitbucket-pipelines/__tests__/AnalysisCommand-test.tsx @@ -20,7 +20,6 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { mockComponent } from '../../../../helpers/mocks/component'; -import { mockAppState } from '../../../../helpers/testMocks'; import { BuildTools } from '../../types'; import { AnalysisCommand, AnalysisCommandProps } from '../AnalysisCommand'; @@ -32,15 +31,15 @@ it.each([ [BuildTools.Other] ])('should render correctly for %s', buildTool => { expect(shallowRender({ buildTool })).toMatchSnapshot(); - expect( - shallowRender({ appState: mockAppState({ branchesEnabled: true }), buildTool }) - ).toMatchSnapshot('with branch enabled'); + expect(shallowRender({ hasFeature: () => true, buildTool })).toMatchSnapshot( + 'with branch enabled' + ); }); function shallowRender(props: Partial = {}) { return shallow( @@ -61,7 +59,7 @@ export function AllSet(props: AllSetProps) { {translate('onboarding.tutorial.ci_outro.commit')}

    - {branchesEnabled + {branchSupportEnabled ? translate('onboarding.tutorial.ci_outro.commit.why', alm) : translate('onboarding.tutorial.ci_outro.commit.why.no_branches')}

    @@ -96,4 +94,4 @@ export function AllSet(props: AllSetProps) { ); } -export default withAppStateContext(AllSet); +export default withAvailableFeatures(AllSet); diff --git a/server/sonar-web/src/main/js/components/tutorials/components/__tests__/AllSet-test.tsx b/server/sonar-web/src/main/js/components/tutorials/components/__tests__/AllSet-test.tsx index fde3b01442a..5c3720993ba 100644 --- a/server/sonar-web/src/main/js/components/tutorials/components/__tests__/AllSet-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/components/__tests__/AllSet-test.tsx @@ -19,20 +19,17 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { mockAppState } from '../../../../helpers/testMocks'; import { AlmKeys } from '../../../../types/alm-settings'; import { AllSet, AllSetProps } from '../AllSet'; it('should render correctly', () => { expect(shallowRender()).toMatchSnapshot(); - expect(shallowRender({ appState: mockAppState({ branchesEnabled: false }) })).toMatchSnapshot( - 'without branch' - ); + expect(shallowRender({ hasFeature: () => false })).toMatchSnapshot('without branch'); expect(shallowRender({ willRefreshAutomatically: true })).toMatchSnapshot('with auto refresh'); }); function shallowRender(props: Partial = {}) { return shallow( - + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx index d0bd6b5c0b2..256d7592b46 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx @@ -18,8 +18,10 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import withAppStateContext from '../../../app/components/app-state/withAppStateContext'; -import { AppState } from '../../../types/appstate'; +import withAvailableFeatures, { + WithAvailableFeaturesProps +} from '../../../app/components/available-features/withAvailableFeatures'; +import { Feature } from '../../../types/features'; import { Component } from '../../../types/types'; import { BuildTools } from '../types'; import CFamily from './commands/CFamily'; @@ -28,19 +30,15 @@ import Gradle from './commands/Gradle'; import JavaMaven from './commands/JavaMaven'; import Others from './commands/Others'; -export interface AnalysisCommandProps { - appState: AppState; +export interface AnalysisCommandProps extends WithAvailableFeaturesProps { buildTool: BuildTools; component: Component; onDone: () => void; } export function AnalysisCommand(props: AnalysisCommandProps) { - const { - buildTool, - component, - appState: { branchesEnabled } - } = props; + const { buildTool, component } = props; + const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); if (!buildTool) { return null; @@ -49,26 +47,46 @@ export function AnalysisCommand(props: AnalysisCommandProps) { switch (buildTool) { case BuildTools.Maven: return ( - + ); case BuildTools.Gradle: return ( - + ); case BuildTools.DotNet: return ( - + ); case BuildTools.CFamily: return ( - + ); case BuildTools.Other: return ( - + ); } return null; } -export default withAppStateContext(AnalysisCommand); +export default withAvailableFeatures(AnalysisCommand); diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx index 16f42fd1fb3..eeb4667d1f8 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx @@ -20,7 +20,6 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { mockComponent } from '../../../../helpers/mocks/component'; -import { mockAppState } from '../../../../helpers/testMocks'; import { BuildTools } from '../../types'; import { AnalysisCommand, AnalysisCommandProps } from '../AnalysisCommand'; @@ -38,7 +37,7 @@ it.each([ function shallowRender(props: Partial = {}) { return shallow( void; @@ -40,13 +41,8 @@ export interface YmlFileStepProps { } export function YmlFileStep(props: YmlFileStepProps) { - const { - appState: { branchesEnabled }, - buildTool, - open, - finished, - projectKey - } = props; + const { buildTool, open, finished, projectKey } = props; + const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); const renderForm = () => (
    @@ -82,12 +78,12 @@ export function YmlFileStep(props: YmlFileStepProps) {

    - {branchesEnabled + {branchSupportEnabled ? translate('onboarding.tutorial.with.gitlab_ci.yml.baseconfig') : translate('onboarding.tutorial.with.gitlab_ci.yml.baseconfig.no_branches')}

    @@ -112,4 +108,4 @@ export function YmlFileStep(props: YmlFileStepProps) { ); } -export default withAppStateContext(YmlFileStep); +export default withAvailableFeatures(YmlFileStep); diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx index 0bdce5f9b99..9c6b0614afa 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx @@ -19,7 +19,6 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; -import { mockAppState } from '../../../../helpers/testMocks'; import { renderStepContent } from '../../test-utils'; import { BuildTools } from '../../types'; import { YmlFileStep, YmlFileStepProps } from '../YmlFileStep'; @@ -38,17 +37,15 @@ it.each([ [BuildTools.Other] ])('should render correctly for build tool %s', buildTool => { expect(renderStepContent(shallowRender({ buildTool }))).toMatchSnapshot('with branch support'); - expect( - renderStepContent( - shallowRender({ appState: mockAppState({ branchesEnabled: false }), buildTool }) - ) - ).toMatchSnapshot('without branch support'); + expect(renderStepContent(shallowRender({ hasFeature: () => false, buildTool }))).toMatchSnapshot( + 'without branch support' + ); }); function shallowRender(props: Partial = {}) { return shallow( - (projectBinding?.alm); const [step, setStep] = React.useState(alm ? Steps.PreRequisites : Steps.SelectAlm); @@ -88,14 +83,14 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) { <> Steps.PreRequisites} onDone={() => setStep(Steps.MultiBranchPipeline)} onOpen={() => setStep(Steps.PreRequisites)} open={step === Steps.PreRequisites} /> - {appState.branchesEnabled ? ( + {branchSupportEnabled ? ( Steps.Webhook} onDone={() => setStep(Steps.Jenkinsfile)} onOpen={() => setStep(Steps.Webhook)} @@ -147,4 +142,4 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) { ); } -export default withAppStateContext(JenkinsTutorial); +export default withAvailableFeatures(JenkinsTutorial); diff --git a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-test.tsx b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-test.tsx index e4d121ac0fa..7075595e28f 100644 --- a/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/jenkins/__tests__/JenkinsTutorial-test.tsx @@ -21,7 +21,6 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { mockProjectBitbucketBindingResponse } from '../../../../helpers/mocks/alm-settings'; import { mockComponent } from '../../../../helpers/mocks/component'; -import { mockAppState } from '../../../../helpers/testMocks'; import { AlmKeys } from '../../../../types/alm-settings'; import JenkinsfileStep from '../JenkinsfileStep'; import { JenkinsTutorial, JenkinsTutorialProps } from '../JenkinsTutorial'; @@ -32,9 +31,7 @@ import WebhookStep from '../WebhookStep'; it('should render correctly', () => { expect(shallowRender()).toMatchSnapshot('default'); - expect(shallowRender({ appState: mockAppState({ branchesEnabled: false }) })).toMatchSnapshot( - 'branches not enabled' - ); + expect(shallowRender({ hasFeature: () => false })).toMatchSnapshot('branches not enabled'); expect(shallowRender({ projectBinding: undefined })).toMatchSnapshot('no project binding'); }); @@ -113,7 +110,7 @@ function shallowRender(props: Partial = {}) { return shallow( - - - - - - - {children} - } /> - - - - - + + + + + + + + {children} + } /> + + + + + + diff --git a/server/sonar-web/src/main/js/types/appstate.ts b/server/sonar-web/src/main/js/types/appstate.ts index d90558d0021..b424ad158ff 100644 --- a/server/sonar-web/src/main/js/types/appstate.ts +++ b/server/sonar-web/src/main/js/types/appstate.ts @@ -25,7 +25,6 @@ import { Extension } from './types'; export interface AppState { authenticationError?: boolean; authorizationError?: boolean; - branchesEnabled?: boolean; canAdmin?: boolean; edition?: EditionKey; globalPages?: Extension[]; diff --git a/server/sonar-web/src/main/js/types/features.ts b/server/sonar-web/src/main/js/types/features.ts index 10efdac37de..3309f8f8214 100644 --- a/server/sonar-web/src/main/js/types/features.ts +++ b/server/sonar-web/src/main/js/types/features.ts @@ -23,5 +23,6 @@ export enum Feature { RegulatoryReport = 'regulatory-reports', ProjectImport = 'project-import', MultipleAlm = 'multiple-alm', - Announcement = 'announcement' + Announcement = 'announcement', + BranchSupport = 'branch-support' } diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/branch/BranchFeatureExtension.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/branch/BranchFeatureExtension.java index b59831be338..305a806d80a 100644 --- a/server/sonar-webserver-api/src/main/java/org/sonar/server/branch/BranchFeatureExtension.java +++ b/server/sonar-webserver-api/src/main/java/org/sonar/server/branch/BranchFeatureExtension.java @@ -20,11 +20,12 @@ package org.sonar.server.branch; import org.sonar.api.server.ServerSide; +import org.sonar.server.feature.SonarQubeFeature; /** * The branch plugin needs to implement this in order to know that the branch feature is supported */ @ServerSide -public interface BranchFeatureExtension extends BranchFeature { +public interface BranchFeatureExtension extends SonarQubeFeature { } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/GlobalAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/GlobalAction.java index fa9bbb33670..fd59388942d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/GlobalAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/GlobalAction.java @@ -38,7 +38,6 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.dialect.H2; import org.sonar.server.authentication.DefaultAdminCredentialsVerifier; -import org.sonar.server.branch.BranchFeatureProxy; import org.sonar.server.issue.index.IssueIndexSyncProgressChecker; import org.sonar.server.platform.WebServer; import org.sonar.server.ui.PageRepository; @@ -72,7 +71,6 @@ public class GlobalAction implements NavigationWsAction, Startable { private final Server server; private final WebServer webServer; private final DbClient dbClient; - private final BranchFeatureProxy branchFeature; private final UserSession userSession; private final PlatformEditionProvider editionProvider; private final WebAnalyticsLoader webAnalyticsLoader; @@ -80,7 +78,7 @@ public class GlobalAction implements NavigationWsAction, Startable { private final DefaultAdminCredentialsVerifier defaultAdminCredentialsVerifier; public GlobalAction(PageRepository pageRepository, Configuration config, ResourceTypes resourceTypes, Server server, - WebServer webServer, DbClient dbClient, BranchFeatureProxy branchFeature, UserSession userSession, PlatformEditionProvider editionProvider, + WebServer webServer, DbClient dbClient, UserSession userSession, PlatformEditionProvider editionProvider, WebAnalyticsLoader webAnalyticsLoader, IssueIndexSyncProgressChecker issueIndexSyncChecker, DefaultAdminCredentialsVerifier defaultAdminCredentialsVerifier) { this.pageRepository = pageRepository; @@ -89,7 +87,6 @@ public class GlobalAction implements NavigationWsAction, Startable { this.server = server; this.webServer = webServer; this.dbClient = dbClient; - this.branchFeature = branchFeature; this.userSession = userSession; this.editionProvider = editionProvider; this.webAnalyticsLoader = webAnalyticsLoader; @@ -129,7 +126,6 @@ public class GlobalAction implements NavigationWsAction, Startable { writeQualifiers(json); writeVersion(json); writeDatabaseProduction(json); - writeBranchSupport(json); writeInstanceUsesDefaultAdminCredentials(json); editionProvider.get().ifPresent(e -> json.prop("edition", e.name().toLowerCase(Locale.ENGLISH))); writeNeedIssueSync(json); @@ -183,10 +179,6 @@ public class GlobalAction implements NavigationWsAction, Startable { json.prop("productionDatabase", !dbClient.getDatabase().getDialect().getId().equals(H2.ID)); } - private void writeBranchSupport(JsonWriter json) { - json.prop("branchesEnabled", branchFeature.isEnabled()); - } - private void writeInstanceUsesDefaultAdminCredentials(JsonWriter json) { if (userSession.isSystemAdministrator()) { json.prop("instanceUsesDefaultAdminCredentials", defaultAdminCredentialsVerifier.hasDefaultCredentialUser()); diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ui/ws/global-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ui/ws/global-example.json index 700eee264bc..a1619ee69fd 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ui/ws/global-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ui/ws/global-example.json @@ -25,7 +25,6 @@ ], "version": "6.2", "productionDatabase": true, - "branchesEnabled": false, "canAdmin": false, "standalone": true, "edition": "community" diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java index f23616f3b76..bdcb1b773b9 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java @@ -214,16 +214,6 @@ public class GlobalActionTest { "}"); } - @Test - public void branch_support() { - init(); - branchFeature.setEnabled(true); - assertJson(call()).isSimilarTo("{\"branchesEnabled\":true}"); - - branchFeature.setEnabled(false); - assertJson(call()).isSimilarTo("{\"branchesEnabled\":false}"); - } - @Test public void return_need_issue_sync() { init(); @@ -353,7 +343,7 @@ public class GlobalActionTest { }}); pageRepository.start(); GlobalAction wsAction = new GlobalAction(pageRepository, settings.asConfig(), new ResourceTypes(resourceTypeTrees), server, - webServer, dbClient, branchFeature, userSession, editionProvider, webAnalyticsLoader, + webServer, dbClient, userSession, editionProvider, webAnalyticsLoader, indexSyncProgressChecker, defaultAdminCredentialsVerifier); ws = new WsActionTester(wsAction); wsAction.start(); -- 2.39.5