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;
};
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(
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)
]);
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
}
}
-export default withRouter(withAppStateContext(withBranchStatusActions(ComponentContainer)));
+export default withRouter(withAvailableFeatures(withBranchStatusActions(ComponentContainer)));
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';
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
});
(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);
function shallowRender(props: Partial<ComponentContainer['props']> = {}) {
return shallow<ComponentContainer>(
<ComponentContainer
- appState={mockAppState()}
+ hasFeature={jest.fn().mockReturnValue(false)}
location={mockLocation({ query: { id: 'foo' } })}
updateBranchStatus={jest.fn()}
router={mockRouter()}
import { getBranchLikeQuery, isPullRequest } from '../../../../helpers/branch-like';
import { hasMessage, translate, translateWithParameters } from '../../../../helpers/l10n';
import { getPortfolioUrl, getProjectQueryUrl } from '../../../../helpers/urls';
-import { AppState } from '../../../../types/appstate';
import { BranchLike, BranchParameters } from '../../../../types/branch-like';
import { ComponentQualifier, isPortfolioLike } from '../../../../types/component';
+import { Feature } from '../../../../types/features';
import { Component, Dict, Extension } from '../../../../types/types';
-import withAppStateContext from '../../app-state/withAppStateContext';
+import withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../available-features/withAvailableFeatures';
import './Menu.css';
const SETTINGS_URLS = [
'/project/webhooks'
];
-interface Props {
- appState: AppState;
+interface Props extends WithAvailableFeaturesProps {
branchLike: BranchLike | undefined;
branchLikes: BranchLike[] | undefined;
component: Component;
renderBranchesLink = (query: Query, isProject: boolean) => {
if (
- !this.props.appState.branchesEnabled ||
+ !this.props.hasFeature(Feature.BranchSupport) ||
!isProject ||
!this.getConfiguration().showSettings
) {
}
}
-export default withAppStateContext(Menu);
+export default withAvailableFeatures(Menu);
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';
const mainBranch = mockMainBranch();
return renderComponent(
<Menu
- appState={mockAppState()}
+ hasFeature={jest.fn().mockReturnValue(false)}
branchLike={mainBranch}
branchLikes={[mainBranch]}
component={BASE_COMPONENT}
favorite={false}
qualifier="TRK"
/>
- <withAppStateContext(Component)
+ <withAvailableFeaturesContext(Component)
branchLikes={
Array [
Object {
import { ButtonPlain } from '../../../../../components/controls/buttons';
import Toggler from '../../../../../components/controls/Toggler';
import { ProjectAlmBindingResponse } from '../../../../../types/alm-settings';
-import { AppState } from '../../../../../types/appstate';
import { BranchLike } from '../../../../../types/branch-like';
+import { Feature } from '../../../../../types/features';
import { Component } from '../../../../../types/types';
-import withAppStateContext from '../../../app-state/withAppStateContext';
+import withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../../available-features/withAvailableFeatures';
import './BranchLikeNavigation.css';
import CurrentBranchLike from './CurrentBranchLike';
import Menu from './Menu';
-export interface BranchLikeNavigationProps {
- appState: AppState;
+export interface BranchLikeNavigationProps extends WithAvailableFeaturesProps {
branchLikes: BranchLike[];
component: Component;
currentBranchLike: BranchLike;
export function BranchLikeNavigation(props: BranchLikeNavigationProps) {
const {
- appState: { branchesEnabled },
branchLikes,
component,
component: { configuration },
} = props;
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
+ const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
const canAdminComponent = configuration && configuration.showSettings;
const hasManyBranches = branchLikes.length >= 2;
- const isMenuEnabled = branchesEnabled && hasManyBranches;
+ const isMenuEnabled = branchSupportEnabled && hasManyBranches;
const currentBranchLikeElement = (
<CurrentBranchLike
- branchesEnabled={Boolean(branchesEnabled)}
+ branchesEnabled={branchSupportEnabled}
component={component}
currentBranchLike={currentBranchLike}
hasManyBranches={hasManyBranches}
);
}
-export default withAppStateContext(React.memo(BranchLikeNavigation));
+export default withAvailableFeatures(React.memo(BranchLikeNavigation));
import Toggler from '../../../../../../components/controls/Toggler';
import { mockSetOfBranchAndPullRequest } from '../../../../../../helpers/mocks/branch-like';
import { mockComponent } from '../../../../../../helpers/mocks/component';
-import { mockAppState } from '../../../../../../helpers/testMocks';
import { click } from '../../../../../../helpers/testUtils';
import { BranchLikeNavigation, BranchLikeNavigationProps } from '../BranchLikeNavigation';
});
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));
});
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));
return shallow(
<BranchLikeNavigation
- appState={mockAppState()}
+ hasFeature={jest.fn().mockReturnValue(false)}
branchLikes={branchLikes}
component={mockComponent()}
currentBranchLike={branchLikes[0]}
*/
import * as React from 'react';
import { getFacet } from '../../../api/issues';
-import withAppStateContext from '../../../app/components/app-state/withAppStateContext';
+import withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../../app/components/available-features/withAvailableFeatures';
import Link from '../../../components/common/Link';
import Tooltip from '../../../components/controls/Tooltip';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { translate } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';
import { getIssuesUrl } from '../../../helpers/urls';
-import { AppState } from '../../../types/appstate';
+import { Feature } from '../../../types/features';
import { RuleDetails } from '../../../types/types';
-interface Props {
- appState: AppState;
+interface Props extends WithAvailableFeaturesProps {
ruleDetails: Pick<RuleDetails, 'key' | 'type'>;
}
</span>
);
- if (!this.props.appState.branchesEnabled) {
+ if (!this.props.hasFeature(Feature.BranchSupport)) {
return totalItem;
}
}
}
-export default withAppStateContext(RuleDetailsIssues);
+export default withAvailableFeatures(RuleDetailsIssues);
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';
function shallowRender(props: Partial<RuleDetailsIssues['props']> = {}) {
return shallow(
<RuleDetailsIssues
- appState={mockAppState({ branchesEnabled: false })}
+ hasFeature={jest.fn().mockReturnValue(false)}
ruleDetails={{ key: 'foo', type: 'BUG' }}
{...props}
/>
}
}
/>
- <withAppStateContext(RuleDetailsIssues)
+ <withAvailableFeaturesContext(RuleDetailsIssues)
ruleDetails={
Object {
"createdAt": "2014-12-16T17:26:54+0100",
import { Helmet } from 'react-helmet-async';
import { getAlmSettings } from '../../../api/alm-settings';
import withAppStateContext from '../../../app/components/app-state/withAppStateContext';
+import withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../../app/components/available-features/withAvailableFeatures';
import A11ySkipTarget from '../../../components/a11y/A11ySkipTarget';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
import { translate } from '../../../helpers/l10n';
import { getProjectUrl } from '../../../helpers/urls';
import { AlmKeys, AlmSettingsInstance } from '../../../types/alm-settings';
import { AppState } from '../../../types/appstate';
+import { Feature } from '../../../types/features';
import AlmBindingDefinitionForm from '../../settings/components/almIntegration/AlmBindingDefinitionForm';
import AzureProjectCreate from './AzureProjectCreate';
import BitbucketCloudProjectCreate from './BitbucketCloudProjectCreate';
import './style.css';
import { CreateProjectModes } from './types';
-interface Props {
+interface Props extends WithAvailableFeaturesProps {
appState: AppState;
location: Location;
router: Router;
renderProjectCreation(mode?: CreateProjectModes) {
const {
- appState: { canAdmin, branchesEnabled },
+ appState: { canAdmin },
location,
router
} = this.props;
gitlabSettings,
loading
} = this.state;
+ const branchSupportEnabled = this.props.hasFeature(Feature.BranchSupport);
switch (mode) {
case CreateProjectModes.AzureDevOps: {
case CreateProjectModes.Manual: {
return (
<ManualProjectCreate
- branchesEnabled={!!branchesEnabled}
+ branchesEnabled={branchSupportEnabled}
onProjectCreate={this.handleProjectCreate}
/>
);
}
}
-export default withRouter(withAppStateContext(CreateProjectPage));
+export default withRouter(withAvailableFeatures(withAppStateContext(CreateProjectPage)));
return shallow<CreateProjectPage>(
<CreateProjectPage
appState={mockAppState()}
+ hasFeature={jest.fn().mockReturnValue(false)}
location={mockLocation()}
router={mockRouter()}
{...props}
* 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 withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../../app/components/available-features/withAvailableFeatures';
import withComponentContext from '../../../app/components/componentContext/withComponentContext';
import Suggestions from '../../../components/embed-docs-modal/Suggestions';
import { isPullRequest } from '../../../helpers/branch-like';
import { ProjectAlmBindingResponse } from '../../../types/alm-settings';
-import { AppState } from '../../../types/appstate';
import { BranchLike } from '../../../types/branch-like';
import { isPortfolioLike } from '../../../types/component';
+import { Feature } from '../../../types/features';
import { Component } from '../../../types/types';
import BranchOverview from '../branches/BranchOverview';
import PullRequestOverview from '../pullRequests/PullRequestOverview';
import EmptyOverview from './EmptyOverview';
-interface Props {
- appState: AppState;
+interface Props extends WithAvailableFeaturesProps {
branchLike?: BranchLike;
branchLikes: BranchLike[];
component: Component;
};
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;
{component.analysisDate && (
<BranchOverview
branch={branchLike}
- branchesEnabled={branchesEnabled}
+ branchesEnabled={branchSupportEnabled}
component={component}
projectBinding={projectBinding}
/>
}
}
-export default withComponentContext(withAppStateContext(App));
+export default withComponentContext(withAvailableFeatures(App));
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockAppState } from '../../../../helpers/testMocks';
import BranchOverview from '../../branches/BranchOverview';
import { App } from '../App';
function getWrapper(props = {}) {
return shallow(
- <App appState={mockAppState()} branchLikes={[]} component={component} {...props} />
+ <App
+ hasFeature={jest.fn().mockReturnValue(false)}
+ branchLikes={[]}
+ component={component}
+ {...props}
+ />
);
}
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';
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,
import BranchList from './BranchList';
import ProjectBaselineSelector from './ProjectBaselineSelector';
-interface Props {
+interface Props extends WithAvailableFeaturesProps {
branchLike: Branch;
branchLikes: BranchLike[];
component: Component;
}
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(
selected,
success
} = this.state;
+ const branchSupportEnabled = this.props.hasFeature(Feature.BranchSupport);
return (
<>
<DeferredSpinner />
) : (
<div className="panel-white project-baseline">
- {appState.branchesEnabled && <h2>{translate('project_baseline.default_setting')}</h2>}
+ {branchSupportEnabled && <h2>{translate('project_baseline.default_setting')}</h2>}
{generalSetting && overrideGeneralSetting !== undefined && (
<ProjectBaselineSelector
analysis={analysis}
branch={branchLike}
branchList={branchList}
- branchesEnabled={appState.branchesEnabled}
+ branchesEnabled={branchSupportEnabled}
component={component.key}
currentSetting={currentSetting}
currentSettingValue={currentSettingValue}
{translate('settings.state.saved')}
</span>
</div>
- {generalSetting && appState.branchesEnabled && (
+ {generalSetting && branchSupportEnabled && (
<div className="huge-spacer-top branch-baseline-selector">
<hr />
<h2>{translate('project_baseline.configure_branches')}</h2>
}
}
-export default withComponentContext(withAppStateContext(App));
+export default withComponentContext(withAvailableFeatures(withAppStateContext(App)));
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');
});
<App
branchLike={mockBranch()}
branchLikes={[mockMainBranch()]}
- appState={mockAppState({ branchesEnabled: true, canAdmin: true })}
+ appState={mockAppState({ canAdmin: true })}
+ hasFeature={jest.fn().mockReturnValue(true)}
component={mockComponent()}
{...props}
/>
*/
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';
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<Metric>;
export class Conditions extends React.PureComponent<Props> {
renderConditionsTable = (conditions: ConditionType[], scope: 'new' | 'overall') => {
const {
- appState,
qualityGate,
metrics,
canEdit,
<caption>
<h4>{translate(captionTranslationId, 'long')}</h4>
- {appState.branchesEnabled && (
+ {this.props.hasFeature(Feature.BranchSupport) && (
<p className="spacer-top spacer-bottom">
{translate(captionTranslationId, 'description')}
</p>
}
}
-export default withMetricsContext(withAppStateContext(Conditions));
+export default withMetricsContext(withAvailableFeatures(Conditions));
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');
});
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')
});
});
-function renderQualityGateApp(appState?: AppState) {
- renderAppRoutes('quality_gates', routes, { appState });
+function renderQualityGateApp(context?: RenderContext) {
+ renderAppRoutes('quality_gates', routes, context);
}
key: string;
name: string;
renderComponent: (props: AdditionalCategoryComponentProps) => React.ReactNode;
- requiresBranchesEnabled?: boolean;
+ requiresBranchSupport?: boolean;
}
export const ADDITIONAL_CATEGORIES: AdditionalCategory[] = [
availableGlobally: false,
availableForProject: true,
displayTab: true,
- requiresBranchesEnabled: true
+ requiresBranchSupport: true
},
{
key: AUTHENTICATION_CATEGORY,
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;
}
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()])
: // 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());
);
}
-export default withAppStateContext(CategoriesList);
+export default withAvailableFeatures(CategoriesList);
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';
availableGlobally: true,
availableForProject: true,
displayTab: true,
- requiresBranchesEnabled: true
+ requiresBranchSupport: true
},
{
key: 'CAT_2',
});
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();
function renderCategoriesList(props?: Partial<CategoriesListProps>) {
return renderComponent(
<CategoriesList
- appState={mockAppState({ branchesEnabled: true })}
+ hasFeature={jest.fn().mockReturnValue(true)}
categories={['general']}
defaultCategory="general"
selectedCategory=""
`;
exports[`should render additional categories component correctly 4`] = `
-<withRouter(withAppStateContext(withAvailableFeaturesContext(AlmIntegration)))
+<withRouter(withAvailableFeaturesContext(AlmIntegration))
categories={Array []}
component={
Object {
className="big-padded"
key="almintegration"
>
- <withRouter(withAppStateContext(withAvailableFeaturesContext(AlmIntegration)))
+ <withRouter(withAvailableFeaturesContext(AlmIntegration))
categories={
Array [
"foo category",
<div
className="layout-page-side-inner"
>
- <withAppStateContext(CategoriesList)
+ <withAvailableFeaturesContext(CategoriesList)
categories={
Array [
"foo category",
getAlmDefinitions,
validateAlmSettings
} from '../../../../api/alm-settings';
-import withAppStateContext from '../../../../app/components/app-state/withAppStateContext';
-import withAvailableFeatures from '../../../../app/components/available-features/withAvailableFeatures';
+import withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../../../app/components/available-features/withAvailableFeatures';
import { Location, Router, withRouter } from '../../../../components/hoc/withRouter';
import {
AlmBindingDefinitionBase,
AlmSettingsBindingStatus,
AlmSettingsBindingStatusType
} from '../../../../types/alm-settings';
-import { AppState } from '../../../../types/appstate';
import { Feature } from '../../../../types/features';
import { Dict } from '../../../../types/types';
import AlmIntegrationRenderer from './AlmIntegrationRenderer';
-interface Props {
- appState: AppState;
+interface Props extends WithAvailableFeaturesProps {
hasFeature: (feature: Feature) => boolean;
location: Location;
router: Router;
};
render() {
- const {
- appState: { branchesEnabled },
- hasFeature
- } = this.props;
+ const { hasFeature } = this.props;
const {
currentAlmTab,
definitionKeyForDeletion,
return (
<AlmIntegrationRenderer
- branchesEnabled={Boolean(branchesEnabled)}
+ branchesEnabled={this.props.hasFeature(Feature.BranchSupport)}
multipleAlmEnabled={hasFeature(Feature.MultipleAlm)}
onCancelDelete={this.handleCancelDelete}
onConfirmDelete={this.handleConfirmDelete}
}
}
-export default withRouter(withAppStateContext(withAvailableFeatures(AlmIntegration)));
+export default withRouter(withAvailableFeatures(AlmIntegration));
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';
function shallowRender(props: Partial<AlmIntegration['props']> = {}) {
return shallow<AlmIntegration>(
<AlmIntegration
- appState={mockAppState({ branchesEnabled: true })}
+ hasFeature={jest.fn().mockReturnValue(true)}
location={mockLocation()}
- hasFeature={jest.fn()}
router={mockRouter()}
{...props}
/>
}
loadingAlmDefinitions={true}
loadingProjectCount={false}
+ multipleAlmEnabled={true}
onCancelDelete={[Function]}
onCheckConfiguration={[Function]}
onConfirmDelete={[Function]}
exports[`should render correctly: jenkins tutorial 1`] = `
<Fragment>
- <withAppStateContext(JenkinsTutorial)
+ <withAvailableFeaturesContext(JenkinsTutorial)
almBinding={
Object {
"alm": "github",
import * as React from 'react';
import UserTokensMock from '../../../../api/mocks/UserTokensMock';
import { mockComponent } from '../../../../helpers/mocks/component';
-import { mockAppState, mockLanguage, mockLoggedInUser } from '../../../../helpers/testMocks';
+import { mockLanguage, mockLoggedInUser } from '../../../../helpers/testMocks';
import { renderApp, RenderContext } from '../../../../helpers/testReactTestingUtils';
import { Permissions } from '../../../../types/permissions';
import { TokenType } from '../../../../types/token';
function renderAzurePipelinesTutorial(
props: Partial<AzurePipelinesTutorialProps> = {},
- {
- appState = mockAppState({ branchesEnabled: true }),
- languages = { c: mockLanguage({ key: 'c' }) }
- }: RenderContext = {}
+ { languages = { c: mockLanguage({ key: 'c' }) } }: RenderContext = {}
) {
return renderApp(
'/',
willRefreshAutomatically={true}
{...props}
/>,
- { appState, languages }
+ { languages }
);
}
*/
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 (
<>
<li>
<SentenceWithHighlights
translationKey={
- branchesEnabled
+ branchSupportEnabled
? 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration'
: 'onboarding.tutorial.with.azure_pipelines.BranchAnalysis.continous_integration.no_branches'
}
highlightKeys={['tab', 'continuous_integration']}
/>
</li>
- {branchesEnabled && (
+ {branchSupportEnabled && (
<>
<hr />
<FormattedMessage
);
}
-export default withAppStateContext(PublishSteps);
+export default withAvailableFeatures(PublishSteps);
*/
import { Dictionary } from 'lodash';
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 { CompilationInfo } from '../components/CompilationInfo';
import CreateYmlFile from '../components/CreateYmlFile';
import othersExample from './commands/Others';
import { PreambuleYaml } from './PreambuleYaml';
-export interface AnalysisCommandProps {
- appState: AppState;
+export interface AnalysisCommandProps extends WithAvailableFeaturesProps {
buildTool: BuildTools;
component: Component;
}
};
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;
}
- const yamlTemplate = YamlTemplate[buildTool](branchesEnabled, component.key);
+ const yamlTemplate = YamlTemplate[buildTool](branchSupportEnabled, component.key);
return (
<>
);
}
-export default withAppStateContext(AnalysisCommand);
+export default withAvailableFeatures(AnalysisCommand);
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';
[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<AnalysisCommandProps> = {}) {
return shallow<AnalysisCommandProps>(
<AnalysisCommand
- appState={mockAppState()}
+ hasFeature={jest.fn().mockReturnValue(false)}
buildTool={BuildTools.DotNet}
component={mockComponent()}
{...props}
* 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 withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../../app/components/available-features/withAvailableFeatures';
import { translate } from '../../../helpers/l10n';
import { getBaseUrl } from '../../../helpers/system';
import { AlmKeys } from '../../../types/alm-settings';
-import { AppState } from '../../../types/appstate';
+import { Feature } from '../../../types/features';
import SentenceWithHighlights from './SentenceWithHighlights';
-export interface AllSetProps {
+export interface AllSetProps extends WithAvailableFeaturesProps {
alm: AlmKeys;
- appState: AppState;
willRefreshAutomatically?: boolean;
}
export function AllSet(props: AllSetProps) {
- const {
- alm,
- appState: { branchesEnabled },
- willRefreshAutomatically
- } = props;
+ const { alm, willRefreshAutomatically } = props;
+ const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
return (
<>
<strong>{translate('onboarding.tutorial.ci_outro.commit')}</strong>
</p>
<p>
- {branchesEnabled
+ {branchSupportEnabled
? translate('onboarding.tutorial.ci_outro.commit.why', alm)
: translate('onboarding.tutorial.ci_outro.commit.why.no_branches')}
</p>
);
}
-export default withAppStateContext(AllSet);
+export default withAvailableFeatures(AllSet);
*/
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<AllSetProps> = {}) {
return shallow<AllSetProps>(
- <AllSet alm={AlmKeys.GitHub} appState={mockAppState({ branchesEnabled: true })} {...props} />
+ <AllSet alm={AlmKeys.GitHub} hasFeature={jest.fn().mockReturnValue(true)} {...props} />
);
}
* 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';
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;
switch (buildTool) {
case BuildTools.Maven:
return (
- <JavaMaven branchesEnabled={branchesEnabled} component={component} onDone={props.onDone} />
+ <JavaMaven
+ branchesEnabled={branchSupportEnabled}
+ component={component}
+ onDone={props.onDone}
+ />
);
case BuildTools.Gradle:
return (
- <Gradle branchesEnabled={branchesEnabled} component={component} onDone={props.onDone} />
+ <Gradle
+ branchesEnabled={branchSupportEnabled}
+ component={component}
+ onDone={props.onDone}
+ />
);
case BuildTools.DotNet:
return (
- <DotNet branchesEnabled={branchesEnabled} component={component} onDone={props.onDone} />
+ <DotNet
+ branchesEnabled={branchSupportEnabled}
+ component={component}
+ onDone={props.onDone}
+ />
);
case BuildTools.CFamily:
return (
- <CFamily branchesEnabled={branchesEnabled} component={component} onDone={props.onDone} />
+ <CFamily
+ branchesEnabled={branchSupportEnabled}
+ component={component}
+ onDone={props.onDone}
+ />
);
case BuildTools.Other:
return (
- <Others branchesEnabled={branchesEnabled} component={component} onDone={props.onDone} />
+ <Others
+ branchesEnabled={branchSupportEnabled}
+ component={component}
+ onDone={props.onDone}
+ />
);
}
return null;
}
-export default withAppStateContext(AnalysisCommand);
+export default withAvailableFeatures(AnalysisCommand);
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';
function shallowRender(props: Partial<AnalysisCommandProps> = {}) {
return shallow<AnalysisCommandProps>(
<AnalysisCommand
- appState={mockAppState()}
+ hasFeature={jest.fn().mockReturnValue(false)}
component={mockComponent()}
buildTool={BuildTools.DotNet}
onDone={jest.fn()}
exports[`should render correctly for "cfamily" 1`] = `
<CFamily
+ branchesEnabled={false}
component={
Object {
"breadcrumbs": Array [],
exports[`should render correctly for "dotnet" 1`] = `
<DotNet
+ branchesEnabled={false}
component={
Object {
"breadcrumbs": Array [],
exports[`should render correctly for "gradle" 1`] = `
<Gradle
+ branchesEnabled={false}
component={
Object {
"breadcrumbs": Array [],
exports[`should render correctly for "maven" 1`] = `
<JavaMaven
+ branchesEnabled={false}
component={
Object {
"breadcrumbs": Array [],
exports[`should render correctly for "other" 1`] = `
<Others
+ branchesEnabled={false}
component={
Object {
"breadcrumbs": Array [],
*/
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 { ClipboardIconButton } from '../../../components/controls/clipboard';
import { translate } from '../../../helpers/l10n';
-import { AppState } from '../../../types/appstate';
+import { Feature } from '../../../types/features';
import FinishButton from '../components/FinishButton';
import GithubCFamilyExampleRepositories from '../components/GithubCFamilyExampleRepositories';
import Step from '../components/Step';
import { BuildTools, TutorialModes } from '../types';
import PipeCommand from './commands/PipeCommand';
-export interface YmlFileStepProps {
- appState: AppState;
+export interface YmlFileStepProps extends WithAvailableFeaturesProps {
buildTool?: BuildTools;
finished: boolean;
onDone: () => void;
}
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 = () => (
<div className="boxed-group-inner">
<div className="big-spacer-bottom abs-width-600">
<PipeCommand
buildTool={buildTool}
- branchesEnabled={branchesEnabled}
+ branchesEnabled={branchSupportEnabled}
projectKey={projectKey}
/>
</div>
<p className="little-spacer-bottom">
- {branchesEnabled
+ {branchSupportEnabled
? translate('onboarding.tutorial.with.gitlab_ci.yml.baseconfig')
: translate('onboarding.tutorial.with.gitlab_ci.yml.baseconfig.no_branches')}
</p>
);
}
-export default withAppStateContext(YmlFileStep);
+export default withAvailableFeatures(YmlFileStep);
*/
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';
[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<YmlFileStepProps> = {}) {
return shallow<YmlFileStepProps>(
<YmlFileStep
- appState={mockAppState({ branchesEnabled: true })}
+ hasFeature={jest.fn().mockReturnValue(true)}
open={true}
projectKey="test"
finished={true}
onOpen={[Function]}
open={false}
/>
- <withAppStateContext(YmlFileStep)
+ <withAvailableFeaturesContext(YmlFileStep)
finished={false}
onDone={[Function]}
onOpen={[Function]}
* 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 withAvailableFeatures, {
+ WithAvailableFeaturesProps
+} from '../../../app/components/available-features/withAvailableFeatures';
import { translate } from '../../../helpers/l10n';
import {
AlmKeys,
AlmSettingsInstance,
ProjectAlmBindingResponse
} from '../../../types/alm-settings';
-import { AppState } from '../../../types/appstate';
+import { Feature } from '../../../types/features';
import { Component } from '../../../types/types';
import AllSetStep from '../components/AllSetStep';
import JenkinsfileStep from './JenkinsfileStep';
import SelectAlmStep from './SelectAlmStep';
import WebhookStep from './WebhookStep';
-export interface JenkinsTutorialProps {
+export interface JenkinsTutorialProps extends WithAvailableFeaturesProps {
almBinding?: AlmSettingsInstance;
baseUrl: string;
- appState: AppState;
component: Component;
projectBinding?: ProjectAlmBindingResponse;
willRefreshAutomatically?: boolean;
}
export function JenkinsTutorial(props: JenkinsTutorialProps) {
- const {
- almBinding,
- baseUrl,
- appState,
- component,
- projectBinding,
- willRefreshAutomatically
- } = props;
+ const { almBinding, baseUrl, component, projectBinding, willRefreshAutomatically } = props;
const hasSelectAlmStep = projectBinding?.alm === undefined;
+ const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
const [alm, setAlm] = React.useState<AlmKeys | undefined>(projectBinding?.alm);
const [step, setStep] = React.useState(alm ? Steps.PreRequisites : Steps.SelectAlm);
<>
<PreRequisitesStep
alm={alm}
- branchesEnabled={!!appState.branchesEnabled}
+ branchesEnabled={branchSupportEnabled}
finished={step > Steps.PreRequisites}
onDone={() => setStep(Steps.MultiBranchPipeline)}
onOpen={() => setStep(Steps.PreRequisites)}
open={step === Steps.PreRequisites}
/>
- {appState.branchesEnabled ? (
+ {branchSupportEnabled ? (
<MultiBranchPipelineStep
alm={alm}
almBinding={almBinding}
<WebhookStep
alm={alm}
almBinding={almBinding}
- branchesEnabled={!!appState.branchesEnabled}
+ branchesEnabled={branchSupportEnabled}
finished={step > Steps.Webhook}
onDone={() => setStep(Steps.Jenkinsfile)}
onOpen={() => setStep(Steps.Webhook)}
);
}
-export default withAppStateContext(JenkinsTutorial);
+export default withAvailableFeatures(JenkinsTutorial);
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';
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');
});
return shallow<JenkinsTutorialProps>(
<JenkinsTutorial
baseUrl=""
- appState={mockAppState({ branchesEnabled: true })}
+ hasFeature={jest.fn().mockReturnValue(true)}
component={mockComponent()}
projectBinding={mockProjectBitbucketBindingResponse()}
willRefreshAutomatically={true}
import { MemoryRouter, Outlet, parsePath, Route, Routes } from 'react-router-dom';
import AdminContext from '../app/components/AdminContext';
import AppStateContextProvider from '../app/components/app-state/AppStateContextProvider';
+import { AvailableFeaturesContext } from '../app/components/available-features/AvailableFeaturesContext';
import { ComponentContext } from '../app/components/componentContext/ComponentContext';
import CurrentUserContextProvider from '../app/components/current-user/CurrentUserContextProvider';
import GlobalMessagesContainer from '../app/components/GlobalMessagesContainer';
import { useLocation } from '../components/hoc/withRouter';
import { AppState } from '../types/appstate';
import { ComponentContextShape } from '../types/component';
+import { Feature } from '../types/features';
import { Dict, Extension, Languages, Metric, SysStatus } from '../types/types';
import { CurrentUser } from '../types/users';
import { DEFAULT_METRICS } from './mocks/metrics';
languages?: Languages;
currentUser?: CurrentUser;
navigateTo?: string;
+ featureList?: Feature[];
}
export function renderAppWithAdminContext(
navigateTo = indexPath,
metrics = DEFAULT_METRICS,
appState = mockAppState(),
+ featureList = [],
languages = {}
}: RenderContext = {}
): RenderResult {
<IntlProvider defaultLocale="en" locale="en">
<MetricsContext.Provider value={metrics}>
<LanguagesContext.Provider value={languages}>
- <CurrentUserContextProvider currentUser={currentUser}>
- <AppStateContextProvider appState={appState}>
- <IndexationContextProvider>
- <GlobalMessagesContainer />
- <MemoryRouter initialEntries={[path]}>
- <Routes>
- {children}
- <Route path="*" element={<CatchAll />} />
- </Routes>
- </MemoryRouter>
- </IndexationContextProvider>
- </AppStateContextProvider>
- </CurrentUserContextProvider>
+ <AvailableFeaturesContext.Provider value={featureList}>
+ <CurrentUserContextProvider currentUser={currentUser}>
+ <AppStateContextProvider appState={appState}>
+ <IndexationContextProvider>
+ <GlobalMessagesContainer />
+ <MemoryRouter initialEntries={[path]}>
+ <Routes>
+ {children}
+ <Route path="*" element={<CatchAll />} />
+ </Routes>
+ </MemoryRouter>
+ </IndexationContextProvider>
+ </AppStateContextProvider>
+ </CurrentUserContextProvider>
+ </AvailableFeaturesContext.Provider>
</LanguagesContext.Provider>
</MetricsContext.Provider>
</IntlProvider>
export interface AppState {
authenticationError?: boolean;
authorizationError?: boolean;
- branchesEnabled?: boolean;
canAdmin?: boolean;
edition?: EditionKey;
globalPages?: Extension[];
RegulatoryReport = 'regulatory-reports',
ProjectImport = 'project-import',
MultipleAlm = 'multiple-alm',
- Announcement = 'announcement'
+ Announcement = 'announcement',
+ BranchSupport = 'branch-support'
}
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 {
}
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;
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;
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;
this.server = server;
this.webServer = webServer;
this.dbClient = dbClient;
- this.branchFeature = branchFeature;
this.userSession = userSession;
this.editionProvider = editionProvider;
this.webAnalyticsLoader = webAnalyticsLoader;
writeQualifiers(json);
writeVersion(json);
writeDatabaseProduction(json);
- writeBranchSupport(json);
writeInstanceUsesDefaultAdminCredentials(json);
editionProvider.get().ifPresent(e -> json.prop("edition", e.name().toLowerCase(Locale.ENGLISH)));
writeNeedIssueSync(json);
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());
],
"version": "6.2",
"productionDatabase": true,
- "branchesEnabled": false,
"canAdmin": false,
"standalone": true,
"edition": "community"
"}");
}
- @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();
}});
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();