aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/App.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx44
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap55
-rw-r--r--server/sonar-web/src/main/js/types/types.d.ts1
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties2
5 files changed, 118 insertions, 2 deletions
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx
index 7d1f7457ba7..931289e8965 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx
+++ b/server/sonar-web/src/main/js/apps/component-measures/components/App.tsx
@@ -27,8 +27,10 @@ import { getMeasuresWithPeriod } from '../../../api/measures';
import { getAllMetrics } from '../../../api/metrics';
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper';
+import HelpTooltip from '../../../components/controls/HelpTooltip';
import { enhanceMeasure } from '../../../components/measure/utils';
import '../../../components/search-navigator.css';
+import { Alert } from '../../../components/ui/Alert';
import { getBranchLikeQuery, isPullRequest, isSameBranchLike } from '../../../helpers/branch-like';
import {
getLocalizedMetricDomain,
@@ -43,7 +45,7 @@ import {
} from '../../../helpers/pages';
import { fetchBranchStatus } from '../../../store/rootActions';
import { BranchLike } from '../../../types/branch-like';
-import { ComponentQualifier } from '../../../types/component';
+import { ComponentQualifier, isPortfolioLike } from '../../../types/component';
import Sidebar from '../sidebar/Sidebar';
import '../style.css';
import {
@@ -286,6 +288,7 @@ export class App extends React.PureComponent<Props, State> {
const { branchLike } = this.props;
const { measures } = this.state;
+ const { canBrowseAllChildProjects, qualifier } = this.props.component;
const query = parseQuery(this.props.location.query);
const showFullMeasures = hasFullMeasures(branchLike);
const displayOverview = hasBubbleChart(query.metric);
@@ -295,13 +298,24 @@ export class App extends React.PureComponent<Props, State> {
<div id="component-measures">
<Suggestions suggestions="component_measures" />
<Helmet defer={false} title={this.getHelmetTitle(query, displayOverview, metric)} />
-
{measures.length > 0 ? (
<div className="layout-page">
<ScreenPositionHelper className="layout-page-side-outer">
{({ top }) => (
<div className="layout-page-side" style={{ top }}>
<div className="layout-page-side-inner">
+ {!canBrowseAllChildProjects && isPortfolioLike(qualifier) && (
+ <Alert className="big-spacer-top big-spacer-right" variant="warning">
+ {translate('component_measures.not_all_measures_are_shown')}
+ <HelpTooltip
+ className="spacer-left"
+ ariaLabel={translate(
+ 'component_measures.not_all_measures_are_shown.help'
+ )}
+ overlay={translate('component_measures.not_all_measures_are_shown.help')}
+ />
+ </Alert>
+ )}
<div className="layout-page-filters">
<Sidebar
measures={measures}
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx
index c805df0da81..f628d90f0af 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx
+++ b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/App-test.tsx
@@ -20,10 +20,13 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import { getMeasuresWithPeriod } from '../../../../api/measures';
+import ScreenPositionHelper from '../../../../components/common/ScreenPositionHelper';
+import { Alert } from '../../../../components/ui/Alert';
import { mockMainBranch, mockPullRequest } from '../../../../helpers/mocks/branch-like';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockIssue, mockLocation, mockRouter } from '../../../../helpers/testMocks';
import { waitAndUpdate } from '../../../../helpers/testUtils';
+import { ComponentQualifier } from '../../../../types/component';
import { App } from '../App';
jest.mock('../../../../api/metrics', () => ({
@@ -113,6 +116,47 @@ it('should refresh branch status if issues are updated', async () => {
expect(fetchBranchStatus).toBeCalledWith(branchLike, 'foo');
});
+it('should render a warning message when user does not have access to all projects whithin a Portfolio', async () => {
+ const wrapper = shallowRender({
+ component: mockComponent({
+ qualifier: ComponentQualifier.Portfolio,
+ canBrowseAllChildProjects: false
+ })
+ });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.find(ScreenPositionHelper).dive()).toMatchSnapshot(
+ 'Measure menu with warning (ScreenPositionHelper)'
+ );
+});
+
+it.each([
+ [ComponentQualifier.Portfolio, true, false],
+ [ComponentQualifier.Project, false, false],
+ [ComponentQualifier.Portfolio, false, true]
+])(
+ 'should not render a warning message',
+ async (
+ componentQualifier: ComponentQualifier,
+ canBrowseAllChildProjects: boolean,
+ alertIsVisible: boolean
+ ) => {
+ const wrapper = shallowRender({
+ component: mockComponent({
+ qualifier: componentQualifier,
+ canBrowseAllChildProjects
+ })
+ });
+ await waitAndUpdate(wrapper);
+ expect(
+ wrapper
+ .find(ScreenPositionHelper)
+ .dive()
+ .find(Alert)
+ .exists()
+ ).toBe(alertIsVisible);
+ }
+);
+
function shallowRender(props: Partial<App['props']> = {}) {
return shallow<App>(
<App
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap
index e71e4a4d989..a702f6768c7 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/App-test.tsx.snap
@@ -53,6 +53,61 @@ exports[`should render a message when there are no measures 1`] = `
</div>
`;
+exports[`should render a warning message when user does not have access to all projects whithin a Portfolio: Measure menu with warning (ScreenPositionHelper) 1`] = `
+<div
+ className="layout-page-side-outer"
+>
+ <div
+ className="layout-page-side"
+ style={
+ Object {
+ "top": 0,
+ }
+ }
+ >
+ <div
+ className="layout-page-side-inner"
+ >
+ <Alert
+ className="big-spacer-top big-spacer-right"
+ variant="warning"
+ >
+ component_measures.not_all_measures_are_shown
+ <HelpTooltip
+ ariaLabel="component_measures.not_all_measures_are_shown.help"
+ className="spacer-left"
+ overlay="component_measures.not_all_measures_are_shown.help"
+ />
+ </Alert>
+ <div
+ className="layout-page-filters"
+ >
+ <Sidebar
+ measures={
+ Array [
+ Object {
+ "leak": undefined,
+ "metric": Object {
+ "domain": "Coverage",
+ "id": "2",
+ "key": "coverage",
+ "name": "Coverage",
+ "type": "PERCENT",
+ },
+ "value": "80.0",
+ },
+ ]
+ }
+ selectedMetric="coverage"
+ showFullMeasures={true}
+ updateQuery={[Function]}
+ />
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
exports[`should render correctly 1`] = `
<div
id="component-measures"
diff --git a/server/sonar-web/src/main/js/types/types.d.ts b/server/sonar-web/src/main/js/types/types.d.ts
index 3caa2e0c535..b4700e156fb 100644
--- a/server/sonar-web/src/main/js/types/types.d.ts
+++ b/server/sonar-web/src/main/js/types/types.d.ts
@@ -173,6 +173,7 @@ declare namespace T {
description?: string;
isFavorite?: boolean;
isRecentlyBrowsed?: boolean;
+ canBrowseAllChildProjects?: boolean;
key: string;
match?: string;
name: string;
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index 265842054d1..ee23dc387ed 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -3280,6 +3280,8 @@ component_measures.facet_category.overall_category=Overall
component_measures.facet_category.overall_category.estimated=Estimated after merge
component_measures.facet_category.tests_category=Tests
component_measures.bubble_chart.zoom_level=Current zoom level. Scroll on the chart to zoom or unzoom, click here to reset.
+component_measures.not_all_measures_are_shown=Not all projects are included
+component_measures.not_all_measures_are_shown.help=You do not have access to all projects
#------------------------------------------------------------------------------
#