aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/components/activity-graph
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2022-11-24 10:01:37 +0100
committersonartech <sonartech@sonarsource.com>2022-11-28 11:29:35 +0000
commita8a5d01b4ada4c4be6a56325f3951fca1bbc3f85 (patch)
treee50df5d7790d21d8136b4d34e979f69ce48df373 /server/sonar-web/src/main/js/components/activity-graph
parent92ce215524cf11c0dee49d2f4b6981497f197020 (diff)
downloadsonarqube-a8a5d01b4ada4c4be6a56325f3951fca1bbc3f85.tar.gz
sonarqube-a8a5d01b4ada4c4be6a56325f3951fca1bbc3f85.zip
SONAR-17667 Finish migration of Activity Graph tests to RTL
Diffstat (limited to 'server/sonar-web/src/main/js/components/activity-graph')
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/DataTableModal.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx56
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsLegendNewCode.tsx35
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsLegendStatic.tsx19
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsTooltips.tsx51
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentCoverage.tsx12
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentDuplication.tsx12
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentIssues.tsx24
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/ActivityGraph-it.tsx322
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/DataTableModal-it.tsx (renamed from server/sonar-web/src/main/js/components/activity-graph/__tests__/DataTableModal-test.tsx)25
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/DefinitionChangeEventInner-test.tsx88
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/EventInner-it.tsx165
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendCustom-test.tsx56
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendItem-test.tsx51
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendNewCode-test.tsx30
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendStatic-test.tsx38
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-it.tsx127
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-test.tsx111
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContent-test.tsx33
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentCoverage-test.tsx64
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentDuplication-test.tsx51
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentEvents-test.tsx33
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentIssues-test.tsx59
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/RichQualityGateEventInner-test.tsx60
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/DefinitionChangeEventInner-test.tsx.snap248
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendCustom-test.tsx.snap52
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap58
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendNewCode-test.tsx.snap14
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendStatic-test.tsx.snap22
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltips-test.tsx.snap226
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContent-test.tsx.snap25
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentCoverage-test.tsx.snap71
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentDuplication-test.tsx.snap45
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentEvents-test.tsx.snap60
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentIssues-test.tsx.snap34
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/RichQualityGateEventInner-test.tsx.snap139
-rw-r--r--server/sonar-web/src/main/js/components/activity-graph/styles.css4
37 files changed, 578 insertions, 1944 deletions
diff --git a/server/sonar-web/src/main/js/components/activity-graph/DataTableModal.tsx b/server/sonar-web/src/main/js/components/activity-graph/DataTableModal.tsx
index 0b0fabb17e4..05ff2dd5420 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/DataTableModal.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/DataTableModal.tsx
@@ -41,7 +41,7 @@ export interface DataTableModalProps {
type DataTableEntry = { date: Date } & { [x: string]: string | undefined };
-const MAX_DATA_TABLE_ROWS = 100;
+export const MAX_DATA_TABLE_ROWS = 100;
export default function DataTableModal(props: DataTableModalProps) {
const { analyses, series, graphEndDate, graphStartDate } = props;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx
index a8f54da826a..bf223af2c87 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx
@@ -32,36 +32,34 @@ export interface GraphsLegendCustomProps {
export default function GraphsLegendCustom(props: GraphsLegendCustomProps) {
const { series } = props;
return (
- <div className="activity-graph-legends display-flex-center">
- <div className="flex-1">
- {series.map((serie, idx) => {
- const hasData = hasDataValues(serie);
- const legendItem = (
- <GraphsLegendItem
- index={idx}
- metric={serie.name}
- name={serie.translatedName}
- removeMetric={props.removeMetric}
- showWarning={!hasData}
- />
- );
- if (!hasData) {
- return (
- <Tooltip
- key={serie.name}
- overlay={translate('project_activity.graphs.custom.metric_no_history')}
- >
- <span className="spacer-left spacer-right">{legendItem}</span>
- </Tooltip>
- );
- }
+ <ul className="activity-graph-legends">
+ {series.map((serie, idx) => {
+ const hasData = hasDataValues(serie);
+ const legendItem = (
+ <GraphsLegendItem
+ index={idx}
+ metric={serie.name}
+ name={serie.translatedName}
+ removeMetric={props.removeMetric}
+ showWarning={!hasData}
+ />
+ );
+ if (!hasData) {
return (
- <span className="spacer-left spacer-right" key={serie.name}>
- {legendItem}
- </span>
+ <Tooltip
+ key={serie.name}
+ overlay={translate('project_activity.graphs.custom.metric_no_history')}
+ >
+ <li className="spacer-left spacer-right">{legendItem}</li>
+ </Tooltip>
);
- })}
- </div>
- </div>
+ }
+ return (
+ <li className="spacer-left spacer-right" key={serie.name}>
+ {legendItem}
+ </li>
+ );
+ })}
+ </ul>
);
}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendNewCode.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendNewCode.tsx
deleted file mode 100644
index 06e81da93e4..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendNewCode.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import Tooltip from '../../components/controls/Tooltip';
-import { translate } from '../../helpers/l10n';
-
-export default function GraphsLegendNewCode() {
- return (
- <Tooltip overlay={translate('project_activity.graphs.new_code_long')}>
- <span
- aria-label={translate('project_activity.graphs.new_code_long')}
- className="activity-graph-new-code-legend display-flex-center pull-right note"
- >
- {translate('project_activity.graphs.new_code')}
- </span>
- </Tooltip>
- );
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendStatic.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendStatic.tsx
index 386fd4b59fe..e72d08b008c 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendStatic.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendStatic.tsx
@@ -27,16 +27,17 @@ export interface GraphsLegendStaticProps {
export default function GraphsLegendStatic({ series }: GraphsLegendStaticProps) {
return (
- <div className="activity-graph-legends">
+ <ul className="activity-graph-legends">
{series.map((serie, idx) => (
- <GraphsLegendItem
- className="big-spacer-left big-spacer-right"
- index={idx}
- key={serie.name}
- metric={serie.name}
- name={serie.translatedName}
- />
+ <li key={serie.name}>
+ <GraphsLegendItem
+ className="big-spacer-left big-spacer-right"
+ index={idx}
+ metric={serie.name}
+ name={serie.translatedName}
+ />
+ </li>
))}
- </div>
+ </ul>
);
}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltips.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltips.tsx
index 9950dc79b32..13ee1ad4961 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltips.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltips.tsx
@@ -20,7 +20,7 @@
import * as React from 'react';
import { Popup, PopupPlacement } from '../../components/ui/popups';
import { isDefined } from '../../helpers/types';
-import { AnalysisEvent, MeasureHistory, Serie } from '../../types/project-activity';
+import { AnalysisEvent, GraphType, MeasureHistory, Serie } from '../../types/project-activity';
import DateTimeFormatter from '../intl/DateTimeFormatter';
import GraphsTooltipsContent from './GraphsTooltipsContent';
import GraphsTooltipsContentCoverage from './GraphsTooltipsContentCoverage';
@@ -42,53 +42,60 @@ interface Props {
}
const TOOLTIP_WIDTH = 250;
+const TOOLTIP_LEFT_MARGIN = 60;
+const TOOLTIP_LEFT_FLIP_THRESHOLD = 50;
export default class GraphsTooltips extends React.PureComponent<Props> {
renderContent() {
- const { tooltipIdx } = this.props;
+ const { tooltipIdx, series, graph, measuresHistory } = this.props;
- return this.props.series.map((serie, idx) => {
+ return series.map((serie, idx) => {
const point = serie.data[tooltipIdx];
if (!point || (!point.y && point.y !== 0)) {
return null;
}
- if (this.props.graph === DEFAULT_GRAPH) {
+
+ if (graph === DEFAULT_GRAPH) {
return (
<GraphsTooltipsContentIssues
index={idx}
key={serie.name}
- measuresHistory={this.props.measuresHistory}
+ measuresHistory={measuresHistory}
name={serie.name}
tooltipIdx={tooltipIdx}
translatedName={serie.translatedName}
value={this.props.formatValue(point.y)}
/>
);
- } else {
- return (
- <GraphsTooltipsContent
- index={idx}
- key={serie.name}
- name={serie.name}
- translatedName={serie.translatedName}
- value={this.props.formatValue(point.y)}
- />
- );
}
+
+ return (
+ <GraphsTooltipsContent
+ index={idx}
+ key={serie.name}
+ name={serie.name}
+ translatedName={serie.translatedName}
+ value={this.props.formatValue(point.y)}
+ />
+ );
});
}
render() {
- const { events, measuresHistory, tooltipIdx } = this.props;
+ const { events, measuresHistory, tooltipIdx, tooltipPos, graph, graphWidth, selectedDate } =
+ this.props;
+
const top = 30;
- let left = this.props.tooltipPos + 60;
+ let left = tooltipPos + TOOLTIP_LEFT_MARGIN;
let placement = PopupPlacement.RightTop;
- if (left > this.props.graphWidth - TOOLTIP_WIDTH - 50) {
+ if (left > graphWidth - TOOLTIP_WIDTH - TOOLTIP_LEFT_FLIP_THRESHOLD) {
left -= TOOLTIP_WIDTH;
placement = PopupPlacement.LeftTop;
}
+
const tooltipContent = this.renderContent().filter(isDefined);
const addSeparator = tooltipContent.length > 0;
+
return (
<Popup
className="disabled-pointer-events"
@@ -97,21 +104,21 @@ export default class GraphsTooltips extends React.PureComponent<Props> {
>
<div className="activity-graph-tooltip">
<div className="activity-graph-tooltip-title spacer-bottom">
- <DateTimeFormatter date={this.props.selectedDate} />
+ <DateTimeFormatter date={selectedDate} />
</div>
<table className="width-100">
- {events && events.length > 0 && (
+ {events?.length > 0 && (
<GraphsTooltipsContentEvents addSeparator={addSeparator} events={events} />
)}
<tbody>{tooltipContent}</tbody>
- {this.props.graph === 'coverage' && (
+ {graph === GraphType.coverage && (
<GraphsTooltipsContentCoverage
addSeparator={addSeparator}
measuresHistory={measuresHistory}
tooltipIdx={tooltipIdx}
/>
)}
- {this.props.graph === 'duplications' && (
+ {graph === GraphType.duplications && (
<GraphsTooltipsContentDuplication
addSeparator={addSeparator}
measuresHistory={measuresHistory}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentCoverage.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentCoverage.tsx
index 6021f6e382c..faec9a9c928 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentCoverage.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentCoverage.tsx
@@ -20,6 +20,7 @@
import * as React from 'react';
import { translate } from '../../helpers/l10n';
import { formatMeasure } from '../../helpers/measures';
+import { MetricKey } from '../../types/metrics';
import { MeasureHistory } from '../../types/project-activity';
export interface GraphsTooltipsContentCoverageProps {
@@ -28,13 +29,10 @@ export interface GraphsTooltipsContentCoverageProps {
tooltipIdx: number;
}
-export default function GraphsTooltipsContentCoverage({
- addSeparator,
- measuresHistory,
- tooltipIdx,
-}: GraphsTooltipsContentCoverageProps) {
- const uncovered = measuresHistory.find((measure) => measure.metric === 'uncovered_lines');
- const coverage = measuresHistory.find((measure) => measure.metric === 'coverage');
+export default function GraphsTooltipsContentCoverage(props: GraphsTooltipsContentCoverageProps) {
+ const { addSeparator, measuresHistory, tooltipIdx } = props;
+ const uncovered = measuresHistory.find((measure) => measure.metric === MetricKey.uncovered_lines);
+ const coverage = measuresHistory.find((measure) => measure.metric === MetricKey.coverage);
if (!uncovered || !uncovered.history[tooltipIdx] || !coverage || !coverage.history[tooltipIdx]) {
return null;
}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentDuplication.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentDuplication.tsx
index e97d87d4f09..c134d96acfa 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentDuplication.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentDuplication.tsx
@@ -20,6 +20,7 @@
import * as React from 'react';
import { translate } from '../../helpers/l10n';
import { formatMeasure } from '../../helpers/measures';
+import { MetricKey } from '../../types/metrics';
import { MeasureHistory } from '../../types/project-activity';
export interface GraphsTooltipsContentDuplicationProps {
@@ -28,13 +29,12 @@ export interface GraphsTooltipsContentDuplicationProps {
tooltipIdx: number;
}
-export default function GraphsTooltipsContentDuplication({
- addSeparator,
- measuresHistory,
- tooltipIdx,
-}: GraphsTooltipsContentDuplicationProps) {
+export default function GraphsTooltipsContentDuplication(
+ props: GraphsTooltipsContentDuplicationProps
+) {
+ const { addSeparator, measuresHistory, tooltipIdx } = props;
const duplicationDensity = measuresHistory.find(
- (measure) => measure.metric === 'duplicated_lines_density'
+ (measure) => measure.metric === MetricKey.duplicated_lines_density
);
if (!duplicationDensity || !duplicationDensity.history[tooltipIdx]) {
return null;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentIssues.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentIssues.tsx
index 3ca06bd94ba..134e9a6635e 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentIssues.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsTooltipsContentIssues.tsx
@@ -20,6 +20,7 @@
import * as React from 'react';
import ChartLegendIcon from '../../components/icons/ChartLegendIcon';
import Rating from '../../components/ui/Rating';
+import { MetricKey } from '../../types/metrics';
import { MeasureHistory } from '../../types/project-activity';
import { Dict } from '../../types/types';
@@ -33,29 +34,28 @@ export interface GraphsTooltipsContentIssuesProps {
}
const METRIC_RATING: Dict<string> = {
- bugs: 'reliability_rating',
- vulnerabilities: 'security_rating',
- code_smells: 'sqale_rating',
+ [MetricKey.bugs]: MetricKey.reliability_rating,
+ [MetricKey.vulnerabilities]: MetricKey.security_rating,
+ [MetricKey.code_smells]: MetricKey.sqale_rating,
};
export default function GraphsTooltipsContentIssues(props: GraphsTooltipsContentIssuesProps) {
- const rating = props.measuresHistory.find(
- (measure) => measure.metric === METRIC_RATING[props.name]
- );
- if (!rating || !rating.history[props.tooltipIdx]) {
+ const { index, measuresHistory, name, tooltipIdx, translatedName, value } = props;
+ const rating = measuresHistory.find((measure) => measure.metric === METRIC_RATING[name]);
+ if (!rating || !rating.history[tooltipIdx]) {
return null;
}
- const ratingValue = rating.history[props.tooltipIdx].value;
+ const ratingValue = rating.history[tooltipIdx].value;
return (
- <tr className="activity-graph-tooltip-issues-line" key={props.name}>
+ <tr className="activity-graph-tooltip-issues-line" key={name}>
<td className="thin">
- <ChartLegendIcon className="spacer-right" index={props.index} />
+ <ChartLegendIcon className="spacer-right" index={index} />
</td>
<td className="text-right spacer-right">
- <span className="activity-graph-tooltip-value">{props.value}</span>
+ <span className="activity-graph-tooltip-value">{value}</span>
{ratingValue && <Rating className="spacer-left" small={true} value={ratingValue} />}
</td>
- <td>{props.translatedName}</td>
+ <td>{translatedName}</td>
</tr>
);
}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/ActivityGraph-it.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/ActivityGraph-it.tsx
index 42d90877818..684a1968baf 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/ActivityGraph-it.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/__tests__/ActivityGraph-it.tsx
@@ -26,12 +26,7 @@ import * as React from 'react';
import selectEvent from 'react-select-event';
import { byLabelText, byPlaceholderText, byRole, byText } from 'testing-library-selector';
import { parseDate } from '../../../helpers/dates';
-import {
- mockAnalysisEvent,
- mockHistoryItem,
- mockMeasureHistory,
- mockParsedAnalysis,
-} from '../../../helpers/mocks/project-activity';
+import { mockHistoryItem, mockMeasureHistory } from '../../../helpers/mocks/project-activity';
import { mockMetric } from '../../../helpers/testMocks';
import { renderComponent } from '../../../helpers/testReactTestingUtils';
import { MetricKey } from '../../../types/metrics';
@@ -41,63 +36,65 @@ import GraphsHeader from '../GraphsHeader';
import GraphsHistory from '../GraphsHistory';
import { generateSeries, getDisplayedHistoryMetrics, splitSeriesInGraphs } from '../utils';
-const ui = {
- // Graph types.
- graphTypeSelect: byLabelText('project_activity.graphs.choose_type'),
-
- // Add metrics.
- addMetricBtn: byRole('button', { name: 'project_activity.graphs.custom.add' }),
- bugsCheckbox: byRole('checkbox', { name: MetricKey.bugs }),
- newBugsCheckbox: byRole('checkbox', { name: MetricKey.new_bugs }),
- burnedBudgetCheckbox: byRole('checkbox', { name: MetricKey.burned_budget }),
- vulnerabilityCheckbox: byRole('checkbox', { name: MetricKey.vulnerabilities }),
- hiddenOptionsAlert: byText('project_activity.graphs.custom.type_x_message', {
- exact: false,
- }),
- maxOptionsAlert: byText('project_activity.graphs.custom.add_metric_info'),
- filterMetrics: byPlaceholderText('search.search_for_metrics'),
-
- // Graphs.
- graphs: byLabelText('project_activity.graphs.explanation_x', { exact: false }),
- noDataText: byText('project_activity.graphs.custom.no_history'),
-
- // Date filters.
- fromDateInput: byLabelText('from_date'),
- toDateInput: byLabelText('to_date'),
- submitDatesBtn: byRole('button', { name: 'Submit dates' }),
-
- // Data in table.
- openInTableBtn: byRole('button', { name: 'project_activity.graphs.open_in_table' }),
- closeDataTableBtn: byRole('button', { name: 'close' }),
- dataTable: byRole('table'),
- dataTableRows: byRole('row'),
- dataTableColHeaders: byRole('columnheader'),
- onlyFirst100Text: byText('project_activity.graphs.data_table.max_lines_warning.100'),
- noDataTableText: byText('project_activity.graphs.data_table.no_data_warning_check_dates_x', {
- exact: false,
- }),
-};
+const MAX_GRAPHS = 2;
+const MAX_SERIES_PER_GRAPH = 3;
+const HISTORY_COUNT = 10;
+const START_DATE = '2016-01-01T00:00:00+0200';
-it('should correctly handle adding/removing custom metrics', async () => {
+it('should render correctly when loading', async () => {
+ renderActivityGraph({ loading: true });
+ expect(await screen.findByLabelText('loading')).toBeInTheDocument();
+});
+
+it('should show the correct legend items', async () => {
const user = userEvent.setup();
+ const ui = getPageObject(user);
+ renderActivityGraph();
+
+ // Static legend items, which aren't interactive.
+ expect(ui.legendRemoveMetricBtn(MetricKey.bugs).query()).not.toBeInTheDocument();
+ expect(ui.getLegendItem(MetricKey.bugs)).toBeInTheDocument();
+
+ // Switch to custom graph.
+ await ui.changeGraphType(GraphType.custom);
+ await ui.openAddMetrics();
+ await ui.clickOnMetric(MetricKey.bugs);
+ await ui.clickOnMetric(MetricKey.test_failures);
+ await user.keyboard('{Escape}');
+
+ // These legend items are interactive (interaction tested below).
+ expect(ui.legendRemoveMetricBtn(MetricKey.bugs).get()).toBeInTheDocument();
+ expect(ui.legendRemoveMetricBtn(MetricKey.test_failures).get()).toBeInTheDocument();
+
+ // Shows warning for metrics with no data.
+ const li = ui.getLegendItem(MetricKey.test_failures);
+ // eslint-disable-next-line jest/no-conditional-in-test
+ if (li) {
+ li.focus();
+ }
+ expect(ui.noDataWarningTooltip.get()).toBeInTheDocument();
+});
+
+it('should correctly handle adding/removing custom metrics', async () => {
+ const ui = getPageObject(userEvent.setup());
renderActivityGraph();
// Change graph type to "Custom".
- await changeGraphType(GraphType.custom);
+ await ui.changeGraphType(GraphType.custom);
// Open the "Add metrics" dropdown button; select some metrics.
- await toggleAddMetrics(user);
+ await ui.openAddMetrics();
// We should not see DATA type or New Code metrics.
expect(ui.newBugsCheckbox.query()).not.toBeInTheDocument();
expect(ui.burnedBudgetCheckbox.query()).not.toBeInTheDocument();
// Select 3 Int types.
- await clickOnMetric(user, MetricKey.bugs);
- await clickOnMetric(user, MetricKey.code_smells);
- await clickOnMetric(user, MetricKey.confirmed_issues);
+ await ui.clickOnMetric(MetricKey.bugs);
+ await ui.clickOnMetric(MetricKey.code_smells);
+ await ui.clickOnMetric(MetricKey.confirmed_issues);
// Select 1 Percent type.
- await clickOnMetric(user, MetricKey.coverage);
+ await ui.clickOnMetric(MetricKey.coverage);
// We should see 2 graphs, correctly labelled.
expect(ui.graphs.getAll()).toHaveLength(2);
@@ -107,8 +104,8 @@ it('should correctly handle adding/removing custom metrics', async () => {
expect(ui.hiddenOptionsAlert.get()).toBeInTheDocument();
// Select 2 more Percent types.
- await clickOnMetric(user, MetricKey.duplicated_lines_density);
- await clickOnMetric(user, MetricKey.test_success_density);
+ await ui.clickOnMetric(MetricKey.duplicated_lines_density);
+ await ui.clickOnMetric(MetricKey.test_success_density);
// We cannot select anymore options. It should disable all remaining options, and
// show a different alert.
@@ -118,103 +115,139 @@ it('should correctly handle adding/removing custom metrics', async () => {
expect(ui.vulnerabilityCheckbox.get()).toHaveAttribute('aria-disabled', 'true');
// Disable a few options.
- await clickOnMetric(user, MetricKey.bugs);
- await clickOnMetric(user, MetricKey.code_smells);
- await clickOnMetric(user, MetricKey.coverage);
+ await ui.clickOnMetric(MetricKey.bugs);
+ await ui.clickOnMetric(MetricKey.code_smells);
+ await ui.clickOnMetric(MetricKey.coverage);
// Search for option.
- await searchForMetric(user, 'bug');
+ await ui.searchForMetric('bug');
expect(ui.bugsCheckbox.get()).toBeInTheDocument();
expect(ui.vulnerabilityCheckbox.query()).not.toBeInTheDocument();
- toggleAddMetrics(user);
// Disable final metrics by clicking on the legend items.
- await removeMetric(user, MetricKey.confirmed_issues);
- await removeMetric(user, MetricKey.duplicated_lines_density);
- await removeMetric(user, MetricKey.test_success_density);
+ await ui.removeMetric(MetricKey.confirmed_issues);
+ await ui.removeMetric(MetricKey.duplicated_lines_density);
+ await ui.removeMetric(MetricKey.test_success_density);
// Should show message that there's no data to be rendered.
expect(ui.noDataText.get()).toBeInTheDocument();
});
-it('should render correctly when loading', async () => {
- renderActivityGraph({ loading: true });
- expect(await screen.findByLabelText('loading')).toBeInTheDocument();
-});
+describe('data table modal', () => {
+ it('shows the same data in a table', async () => {
+ const ui = getPageObject(userEvent.setup());
+ renderActivityGraph();
-it('shows the same data in a table', async () => {
- const user = userEvent.setup();
- renderActivityGraph();
+ await ui.openDataTable();
+ expect(ui.dataTable.get()).toBeInTheDocument();
+ expect(ui.dataTableColHeaders.getAll()).toHaveLength(5);
+ expect(ui.dataTableRows.getAll()).toHaveLength(HISTORY_COUNT + 1);
- await user.click(ui.openInTableBtn.get());
- expect(ui.dataTable.get()).toBeInTheDocument();
- expect(ui.dataTableColHeaders.getAll()).toHaveLength(5);
- expect(ui.dataTableRows.getAll()).toHaveLength(101);
- expect(screen.getByText('event.category.QUALITY_GATE', { exact: false })).toBeInTheDocument();
- expect(screen.getByText('event.category.VERSION', { exact: false })).toBeInTheDocument();
- expect(
- screen.getByText('event.category.DEFINITION_CHANGE', { exact: false })
- ).toBeInTheDocument();
- expect(ui.onlyFirst100Text.get()).toBeInTheDocument();
-
- // Change graph type and dates, check table updates correctly.
- await user.click(ui.closeDataTableBtn.get());
- await changeGraphType(GraphType.coverage);
-
- await user.click(ui.openInTableBtn.get());
- expect(ui.dataTable.get()).toBeInTheDocument();
- expect(ui.dataTableColHeaders.getAll()).toHaveLength(4);
- expect(ui.dataTableRows.getAll()).toHaveLength(101);
-});
+ // Change graph type and dates, check table updates correctly.
+ await ui.closeDataTable();
+ await ui.changeGraphType(GraphType.coverage);
-it('shows the same data in a table when filtered by date', async () => {
- const user = userEvent.setup();
- renderActivityGraph({
- graphStartDate: parseDate('2017-01-01'),
- graphEndDate: parseDate('2019-01-01'),
+ await ui.openDataTable();
+ expect(ui.dataTable.get()).toBeInTheDocument();
+ expect(ui.dataTableColHeaders.getAll()).toHaveLength(4);
+ expect(ui.dataTableRows.getAll()).toHaveLength(HISTORY_COUNT + 1);
});
- await user.click(ui.openInTableBtn.get());
- expect(ui.dataTable.get()).toBeInTheDocument();
- expect(ui.dataTableColHeaders.getAll()).toHaveLength(5);
- expect(ui.dataTableRows.getAll()).toHaveLength(2);
- expect(ui.onlyFirst100Text.query()).not.toBeInTheDocument();
-});
-
-async function changeGraphType(type: GraphType) {
- await selectEvent.select(ui.graphTypeSelect.get(), [`project_activity.graphs.${type}`]);
-}
-
-async function toggleAddMetrics(user: UserEvent) {
- await user.click(ui.addMetricBtn.get());
-}
-
-async function clickOnMetric(user: UserEvent, name: MetricKey) {
- await user.click(screen.getByRole('checkbox', { name }));
-}
+ it('shows the same data in a table when filtered by date', async () => {
+ const ui = getPageObject(userEvent.setup());
+ renderActivityGraph({
+ graphStartDate: parseDate('2017-01-01'),
+ graphEndDate: parseDate('2019-01-01'),
+ });
-async function searchForMetric(user: UserEvent, text: string) {
- await user.type(ui.filterMetrics.get(), text);
-}
+ await ui.openDataTable();
+ expect(ui.dataTable.get()).toBeInTheDocument();
+ expect(ui.dataTableColHeaders.getAll()).toHaveLength(5);
+ expect(ui.dataTableRows.getAll()).toHaveLength(2);
+ });
+});
-async function removeMetric(user: UserEvent, metric: MetricKey) {
- await user.click(
- screen.getByRole('button', { name: `project_activity.graphs.custom.remove_metric.${metric}` })
- );
+function getPageObject(user: UserEvent) {
+ const ui = {
+ // Graph types.
+ graphTypeSelect: byLabelText('project_activity.graphs.choose_type'),
+
+ // Add/remove metrics.
+ addMetricBtn: byRole('button', { name: 'project_activity.graphs.custom.add' }),
+ bugsCheckbox: byRole('checkbox', { name: MetricKey.bugs }),
+ newBugsCheckbox: byRole('checkbox', { name: MetricKey.new_bugs }),
+ burnedBudgetCheckbox: byRole('checkbox', { name: MetricKey.burned_budget }),
+ vulnerabilityCheckbox: byRole('checkbox', { name: MetricKey.vulnerabilities }),
+ hiddenOptionsAlert: byText('project_activity.graphs.custom.type_x_message', {
+ exact: false,
+ }),
+ maxOptionsAlert: byText('project_activity.graphs.custom.add_metric_info'),
+ filterMetrics: byPlaceholderText('search.search_for_metrics'),
+ legendRemoveMetricBtn: (key: string) =>
+ byRole('button', { name: `project_activity.graphs.custom.remove_metric.${key}` }),
+ getLegendItem: (name: string) => {
+ // This is due to a limitation in testing library, where we cannot get a listitem
+ // role element by name.
+ return screen.getAllByRole('listitem').find((item) => item.textContent === name);
+ },
+ noDataWarningTooltip: byLabelText('project_activity.graphs.custom.metric_no_history'),
+
+ // Graphs.
+ graphs: byLabelText('project_activity.graphs.explanation_x', { exact: false }),
+ noDataText: byText('project_activity.graphs.custom.no_history'),
+
+ // Date filters.
+ fromDateInput: byLabelText('from_date'),
+ toDateInput: byLabelText('to_date'),
+ submitDatesBtn: byRole('button', { name: 'Submit dates' }),
+
+ // Data in table.
+ openInTableBtn: byRole('button', { name: 'project_activity.graphs.open_in_table' }),
+ closeDataTableBtn: byRole('button', { name: 'close' }),
+ dataTable: byRole('table'),
+ dataTableRows: byRole('row'),
+ dataTableColHeaders: byRole('columnheader'),
+ noDataTableText: byText('project_activity.graphs.data_table.no_data_warning_check_dates_x', {
+ exact: false,
+ }),
+ };
+
+ return {
+ ...ui,
+ async changeGraphType(type: GraphType) {
+ await selectEvent.select(ui.graphTypeSelect.get(), [`project_activity.graphs.${type}`]);
+ },
+ async openAddMetrics() {
+ await user.click(ui.addMetricBtn.get());
+ },
+ async searchForMetric(text: string) {
+ await user.type(ui.filterMetrics.get(), text);
+ },
+ async clickOnMetric(name: MetricKey) {
+ await user.click(screen.getByRole('checkbox', { name }));
+ },
+ async removeMetric(metric: MetricKey) {
+ await user.click(ui.legendRemoveMetricBtn(metric).get());
+ },
+ async openDataTable() {
+ await user.click(ui.openInTableBtn.get());
+ },
+ async closeDataTable() {
+ await user.click(ui.closeDataTableBtn.get());
+ },
+ };
}
function renderActivityGraph(
graphsHistoryProps: Partial<GraphsHistory['props']> = {},
graphsHeaderProps: Partial<GraphsHeader['props']> = {}
) {
- const MAX_GRAPHS = 2;
- const MAX_SERIES_PER_GRAPH = 3;
- const HISTORY_COUNT = 100;
-
function ActivityGraph() {
const [selectedMetrics, setSelectedMetrics] = React.useState<string[]>([]);
- const [graph, setGraph] = React.useState(GraphType.issues);
- const [selectedDate, setSelectedDate] = React.useState<Date | undefined>(undefined);
+ const [graph, setGraph] = React.useState(graphsHistoryProps.graph || GraphType.issues);
+ const [selectedDate, setSelectedDate] = React.useState<Date | undefined>(
+ graphsHistoryProps.selectedDate
+ );
const [fromDate, setFromDate] = React.useState<Date | undefined>(undefined);
const [toDate, setToDate] = React.useState<Date | undefined>(undefined);
@@ -232,8 +265,8 @@ function renderActivityGraph(
MetricKey.duplicated_lines_density,
MetricKey.test_success_density,
].forEach((metric) => {
- const history = times(HISTORY_COUNT, (i) => {
- const date = parseDate('2016-01-01T00:00:00+0200');
+ const history = times(HISTORY_COUNT - 2, (i) => {
+ const date = parseDate(START_DATE);
date.setDate(date.getDate() + i);
return mockHistoryItem({ date, value: i.toString() });
});
@@ -245,7 +278,6 @@ function renderActivityGraph(
metrics.push(
mockMetric({
key: metric,
- name: metric,
type: metric.includes('_density') || metric === MetricKey.coverage ? 'PERCENT' : 'INT',
})
);
@@ -253,8 +285,21 @@ function renderActivityGraph(
// The following should be filtered out, and not be suggested as options.
metrics.push(
- mockMetric({ key: MetricKey.new_bugs, name: MetricKey.new_bugs, type: 'INT' }),
- mockMetric({ key: MetricKey.burned_budget, name: MetricKey.burned_budget, type: 'DATA' })
+ mockMetric({ key: MetricKey.new_bugs, type: 'INT' }),
+ mockMetric({ key: MetricKey.burned_budget, type: 'DATA' })
+ );
+
+ // The following will not be filtered out, but has no values.
+ metrics.push(mockMetric({ key: MetricKey.test_failures, type: 'INT' }));
+ measuresHistory.push(
+ mockMeasureHistory({
+ metric: MetricKey.test_failures,
+ history: times(HISTORY_COUNT, (i) => {
+ const date = parseDate(START_DATE);
+ date.setDate(date.getDate() + i);
+ return mockHistoryItem({ date, value: undefined });
+ }),
+ })
);
const series = generateSeries(
@@ -305,28 +350,7 @@ function renderActivityGraph(
{...graphsHeaderProps}
/>
<GraphsHistory
- analyses={[
- mockParsedAnalysis({
- date: parseDate('2018-10-27T12:21:15+0200'),
- events: [
- mockAnalysisEvent({ key: '1' }),
- mockAnalysisEvent({
- key: '2',
- category: 'VERSION',
- description: undefined,
- qualityGate: undefined,
- }),
- mockAnalysisEvent({
- key: '3',
- category: 'DEFINITION_CHANGE',
- definitionChange: {
- projects: [{ changeType: 'ADDED', key: 'foo', name: 'Foo' }],
- },
- qualityGate: undefined,
- }),
- ],
- }),
- ]}
+ analyses={[]}
graph={graph}
graphEndDate={toDate}
graphStartDate={fromDate}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/DataTableModal-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/DataTableModal-it.tsx
index b4d16fb678e..fb5dd3a5184 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/DataTableModal-test.tsx
+++ b/server/sonar-web/src/main/js/components/activity-graph/__tests__/DataTableModal-it.tsx
@@ -22,13 +22,18 @@ import { screen } from '@testing-library/react';
import { times } from 'lodash';
import * as React from 'react';
import { parseDate } from '../../../helpers/dates';
-import { mockHistoryItem, mockMeasureHistory } from '../../../helpers/mocks/project-activity';
+import {
+ mockAnalysisEvent,
+ mockHistoryItem,
+ mockMeasureHistory,
+ mockParsedAnalysis,
+} from '../../../helpers/mocks/project-activity';
import { mockMetric } from '../../../helpers/testMocks';
import { renderComponent } from '../../../helpers/testReactTestingUtils';
import { MetricKey } from '../../../types/metrics';
import { GraphType, MeasureHistory } from '../../../types/project-activity';
import { Metric } from '../../../types/types';
-import DataTableModal, { DataTableModalProps } from '../DataTableModal';
+import DataTableModal, { DataTableModalProps, MAX_DATA_TABLE_ROWS } from '../DataTableModal';
import { generateSeries, getDisplayedHistoryMetrics } from '../utils';
it('should render correctly if there are no series', () => {
@@ -38,10 +43,22 @@ it('should render correctly if there are no series', () => {
).toBeInTheDocument();
});
+it('should render correctly if there are events', () => {
+ renderDataTableModal({
+ analyses: [
+ mockParsedAnalysis({
+ date: parseDate('2016-01-01T00:00:00+0200'),
+ events: [mockAnalysisEvent({ key: '1', category: 'QUALITY_GATE' })],
+ }),
+ ],
+ });
+ expect(screen.getByText('event.category.QUALITY_GATE', { exact: false })).toBeInTheDocument();
+});
+
it('should render correctly if there is too much data', () => {
- renderDataTableModal({ series: mockSeries(101) });
+ renderDataTableModal({ series: mockSeries(MAX_DATA_TABLE_ROWS + 1) });
expect(
- screen.getByText('project_activity.graphs.data_table.max_lines_warning.100')
+ screen.getByText(`project_activity.graphs.data_table.max_lines_warning.${MAX_DATA_TABLE_ROWS}`)
).toBeInTheDocument();
});
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/DefinitionChangeEventInner-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/DefinitionChangeEventInner-test.tsx
deleted file mode 100644
index cd609cbfeca..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/DefinitionChangeEventInner-test.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockBranch } from '../../../helpers/mocks/branch-like';
-import { click } from '../../../helpers/testUtils';
-import { DefinitionChangeEvent, DefinitionChangeEventInner } from '../DefinitionChangeEventInner';
-
-it('should render', () => {
- const event: DefinitionChangeEvent = {
- category: 'DEFINITION_CHANGE',
- key: 'foo1234',
- name: '',
- definitionChange: {
- projects: [
- { changeType: 'ADDED', key: 'foo', name: 'Foo', branch: 'master' },
- { changeType: 'REMOVED', key: 'bar', name: 'Bar', branch: 'master' },
- ],
- },
- };
- const wrapper = shallow(<DefinitionChangeEventInner branchLike={undefined} event={event} />);
- expect(wrapper).toMatchSnapshot();
-
- click(wrapper.find('.project-activity-event-inner-more-link'));
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
-
-it('should render for a branch', () => {
- const branch = mockBranch({ name: 'feature-x' });
- const event: DefinitionChangeEvent = {
- category: 'DEFINITION_CHANGE',
- key: 'foo1234',
- name: '',
- definitionChange: {
- projects: [
- { changeType: 'ADDED', key: 'foo', name: 'Foo', branch: 'feature-x' },
- {
- changeType: 'BRANCH_CHANGED',
- key: 'bar',
- name: 'Bar',
- oldBranch: 'master',
- newBranch: 'feature-y',
- },
- ],
- },
- };
- const wrapper = shallow(<DefinitionChangeEventInner branchLike={branch} event={event} />);
- click(wrapper.find('.project-activity-event-inner-more-link'));
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
-
-it('should render when readonly', () => {
- const event: DefinitionChangeEvent = {
- category: 'DEFINITION_CHANGE',
- key: 'foo1234',
- name: '',
- definitionChange: {
- projects: [
- { changeType: 'ADDED', key: 'foo', name: 'Foo', branch: 'master' },
- { changeType: 'REMOVED', key: 'bar', name: 'Bar', branch: 'master' },
- ],
- },
- };
- const wrapper = shallow(
- <DefinitionChangeEventInner branchLike={undefined} event={event} readonly={true} />
- );
- expect(wrapper).toMatchSnapshot();
- expect(wrapper.find('.project-activity-event-inner-more-link').exists()).toBe(false);
-});
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/EventInner-it.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/EventInner-it.tsx
new file mode 100644
index 00000000000..ef0f1179e33
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/activity-graph/__tests__/EventInner-it.tsx
@@ -0,0 +1,165 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import * as React from 'react';
+import { byRole, byText } from 'testing-library-selector';
+import { mockAnalysisEvent } from '../../../helpers/mocks/project-activity';
+import { renderComponent } from '../../../helpers/testReactTestingUtils';
+import EventInner, { EventInnerProps } from '../EventInner';
+
+const ui = {
+ showMoreBtn: byRole('button', { name: 'more' }),
+ showLessBtn: byRole('button', { name: 'hide' }),
+ projectLink: (name: string) => byRole('link', { name }),
+
+ definitionChangeLabel: byText('event.category.DEFINITION_CHANGE', { exact: false }),
+ projectAddedTxt: byText('event.definition_change.added'),
+ projectRemovedTxt: byText('event.definition_change.removed'),
+ branchReplacedTxt: byText('event.definition_change.branch_replaced'),
+
+ qualityGateLabel: byText('event.category.QUALITY_GATE', { exact: false }),
+ stillFailingTxt: byText('event.quality_gate.still_x'),
+
+ versionLabel: byText('event.category.VERSION', { exact: false }),
+};
+
+describe('DEFINITION_CHANGE events', () => {
+ it('should render correctly for "DEFINITION_CHANGE" events', async () => {
+ const user = userEvent.setup();
+ renderEventInner({
+ event: mockAnalysisEvent({
+ category: 'DEFINITION_CHANGE',
+ definitionChange: {
+ projects: [
+ { changeType: 'ADDED', key: 'foo', name: 'Foo', branch: 'master-foo' },
+ { changeType: 'REMOVED', key: 'bar', name: 'Bar', branch: 'master-bar' },
+ {
+ changeType: 'BRANCH_CHANGED',
+ key: 'baz',
+ name: 'Baz',
+ oldBranch: 'old-branch',
+ newBranch: 'new-branch',
+ },
+ ],
+ },
+ }),
+ });
+
+ expect(ui.definitionChangeLabel.get()).toBeInTheDocument();
+
+ await user.click(ui.showMoreBtn.get());
+
+ // ADDED.
+ expect(ui.projectAddedTxt.get()).toBeInTheDocument();
+ expect(ui.projectLink('Foo').get()).toBeInTheDocument();
+ expect(screen.getByText('master-foo')).toBeInTheDocument();
+
+ // REMOVED.
+ expect(ui.projectRemovedTxt.get()).toBeInTheDocument();
+ expect(ui.projectLink('Bar').get()).toBeInTheDocument();
+ expect(screen.getByText('master-bar')).toBeInTheDocument();
+
+ // BRANCH_CHANGED
+ expect(ui.branchReplacedTxt.get()).toBeInTheDocument();
+ expect(ui.projectLink('Baz').get()).toBeInTheDocument();
+ expect(screen.getByText('old-branch')).toBeInTheDocument();
+ expect(screen.getByText('new-branch')).toBeInTheDocument();
+ });
+});
+
+describe('QUALITY_GATE events', () => {
+ it('should render correctly for simple "QUALITY_GATE" events', () => {
+ renderEventInner({
+ event: mockAnalysisEvent({
+ category: 'QUALITY_GATE',
+ qualityGate: { status: 'ERROR', stillFailing: false, failing: [] },
+ }),
+ });
+
+ expect(ui.qualityGateLabel.get()).toBeInTheDocument();
+ });
+
+ it('should render correctly for "still failing" "QUALITY_GATE" events', () => {
+ renderEventInner({
+ event: mockAnalysisEvent({
+ category: 'QUALITY_GATE',
+ qualityGate: { status: 'ERROR', stillFailing: true, failing: [] },
+ }),
+ });
+
+ expect(ui.qualityGateLabel.get()).toBeInTheDocument();
+ expect(ui.stillFailingTxt.get()).toBeInTheDocument();
+ });
+
+ it('should render correctly for application "QUALITY_GATE" events', async () => {
+ const user = userEvent.setup();
+ renderEventInner({
+ event: mockAnalysisEvent({
+ category: 'QUALITY_GATE',
+ qualityGate: {
+ status: 'ERROR',
+ stillFailing: true,
+ failing: [
+ {
+ key: 'foo',
+ name: 'Foo',
+ branch: 'master',
+ },
+ {
+ key: 'bar',
+ name: 'Bar',
+ branch: 'feature/bar',
+ },
+ ],
+ },
+ }),
+ });
+
+ expect(ui.qualityGateLabel.get()).toBeInTheDocument();
+
+ await user.click(ui.showMoreBtn.get());
+ expect(ui.projectLink('Foo').get()).toBeInTheDocument();
+ expect(ui.projectLink('Bar').get()).toBeInTheDocument();
+
+ await user.click(ui.showLessBtn.get());
+ expect(ui.projectLink('Foo').query()).not.toBeInTheDocument();
+ expect(ui.projectLink('Bar').query()).not.toBeInTheDocument();
+ });
+});
+
+describe('VERSION events', () => {
+ it('should render correctly', () => {
+ renderEventInner({
+ event: mockAnalysisEvent({
+ category: 'VERSION',
+ name: '1.0',
+ }),
+ });
+
+ expect(ui.versionLabel.get()).toBeInTheDocument();
+ expect(screen.getByText('1.0')).toBeInTheDocument();
+ });
+});
+
+function renderEventInner(props: Partial<EventInnerProps> = {}) {
+ return renderComponent(<EventInner event={mockAnalysisEvent()} {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendCustom-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendCustom-test.tsx
deleted file mode 100644
index c54700cf5ea..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendCustom-test.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { parseDate } from '../../../helpers/dates';
-import GraphsLegendCustom, { GraphsLegendCustomProps } from '../GraphsLegendCustom';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
-});
-
-function shallowRender(props: Partial<GraphsLegendCustomProps> = {}) {
- return shallow<GraphsLegendCustomProps>(
- <GraphsLegendCustom
- removeMetric={jest.fn()}
- series={[
- {
- name: 'bugs',
- translatedName: 'Bugs',
- data: [{ x: parseDate('2017-05-16T13:50:02+0200'), y: 1 }],
- type: 'INT',
- },
- {
- name: 'my_metric',
- translatedName: 'My Metric',
- data: [{ x: parseDate('2017-05-16T13:50:02+0200'), y: 1 }],
- type: 'INT',
- },
- {
- name: 'foo',
- translatedName: 'Foo',
- data: [],
- type: 'INT',
- },
- ]}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendItem-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendItem-test.tsx
deleted file mode 100644
index d2c9a3ea8d5..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendItem-test.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { ClearButton } from '../../../components/controls/buttons';
-import { click } from '../../../helpers/testUtils';
-import GraphsLegendItem from '../GraphsLegendItem';
-
-it('should render correctly a legend', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(
- shallowRender({
- className: 'myclass',
- index: 1,
- metric: 'foo',
- name: 'Foo',
- removeMetric: jest.fn(),
- })
- ).toMatchSnapshot('with legend');
- expect(shallowRender({ showWarning: true })).toMatchSnapshot('with warning');
-});
-
-it('should correctly handle clicks', () => {
- const removeMetric = jest.fn();
- const wrapper = shallowRender({ removeMetric });
- click(wrapper.find(ClearButton));
- expect(removeMetric).toHaveBeenCalledWith('bugs');
-});
-
-function shallowRender(props: Partial<GraphsLegendItem['props']> = {}) {
- return shallow<GraphsLegendItem>(
- <GraphsLegendItem index={2} metric="bugs" name="Bugs" {...props} />
- );
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendNewCode-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendNewCode-test.tsx
deleted file mode 100644
index 2e5d932fcd2..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendNewCode-test.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import GraphsLegendNewCode from '../GraphsLegendNewCode';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
-});
-
-function shallowRender() {
- return shallow(<GraphsLegendNewCode />);
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendStatic-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendStatic-test.tsx
deleted file mode 100644
index 98403cb1eb0..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsLegendStatic-test.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import GraphsLegendStatic, { GraphsLegendStaticProps } from '../GraphsLegendStatic';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
-});
-
-function shallowRender(props: Partial<GraphsLegendStaticProps> = {}) {
- return shallow<GraphsLegendStaticProps>(
- <GraphsLegendStatic
- series={[
- { name: 'bugs', translatedName: 'Bugs' },
- { name: 'code_smells', translatedName: 'Code Smells' },
- ]}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-it.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-it.tsx
new file mode 100644
index 00000000000..0886532eed5
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-it.tsx
@@ -0,0 +1,127 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { screen } from '@testing-library/react';
+import * as React from 'react';
+import { parseDate } from '../../../helpers/dates';
+import {
+ mockAnalysisEvent,
+ mockHistoryItem,
+ mockMeasureHistory,
+} from '../../../helpers/mocks/project-activity';
+import { mockMetric } from '../../../helpers/testMocks';
+import { renderComponent } from '../../../helpers/testReactTestingUtils';
+import { MetricKey } from '../../../types/metrics';
+import { GraphType, MeasureHistory } from '../../../types/project-activity';
+import { Metric } from '../../../types/types';
+import GraphsTooltips from '../GraphsTooltips';
+import { generateSeries, getDisplayedHistoryMetrics } from '../utils';
+
+it.each([
+ [
+ GraphType.issues,
+ [
+ [MetricKey.bugs, 1, 'C'],
+ [MetricKey.code_smells, 0, 'A'],
+ [MetricKey.vulnerabilities, 2, 'E'],
+ ],
+ ],
+ [
+ GraphType.coverage,
+ [
+ ['metric.coverage.name', '75.0%'],
+ ['metric.uncovered_lines.name', 8],
+ ],
+ ],
+ [GraphType.duplications, [['metric.duplicated_lines_density.name', '3.0%']]],
+ [GraphType.custom, [[MetricKey.bugs, 1]]],
+])(
+ 'renders correctly for graph of type %s',
+ (graph, metrics: Array<[string, number, string] | [string, number]>) => {
+ renderGraphsTooltips({ graph });
+
+ // Render events.
+ expect(screen.getByText('event.category.QUALITY_GATE', { exact: false })).toBeInTheDocument();
+
+ // Measures table.
+ metrics.forEach(([key, n, rating]) => {
+ expect(
+ screen.getByRole('row', {
+ // eslint-disable-next-line jest/no-conditional-in-test
+ name: rating ? `${n} metric.has_rating_X.${rating} ${key}` : `${n} ${key}`,
+ })
+ ).toBeInTheDocument();
+ });
+ }
+);
+
+function renderGraphsTooltips(props: Partial<GraphsTooltips['props']> = {}) {
+ const graph = (props.graph as GraphType) || GraphType.coverage;
+ const measuresHistory: MeasureHistory[] = [];
+ const date = props.selectedDate || parseDate('2016-01-01T00:00:00+0200');
+ const metrics: Metric[] = [];
+
+ [
+ [MetricKey.bugs, '1'],
+ [MetricKey.reliability_rating, '3'],
+ [MetricKey.code_smells, '0'],
+ [MetricKey.sqale_rating, '1'],
+ [MetricKey.vulnerabilities, '2'],
+ [MetricKey.security_rating, '5'],
+ [MetricKey.lines_to_cover, '10'],
+ [MetricKey.uncovered_lines, '8'],
+ [MetricKey.coverage, '75'],
+ [MetricKey.duplicated_lines_density, '3'],
+ ].forEach(([metric, value]) => {
+ measuresHistory.push(
+ mockMeasureHistory({
+ metric,
+ history: [mockHistoryItem({ date, value })],
+ })
+ );
+ metrics.push(
+ mockMetric({
+ key: metric,
+ type: metric.includes('_density') || metric === MetricKey.coverage ? 'PERCENT' : 'INT',
+ })
+ );
+ });
+
+ const series = generateSeries(
+ measuresHistory,
+ graph,
+ metrics,
+ getDisplayedHistoryMetrics(graph, graph === GraphType.custom ? [MetricKey.bugs] : [])
+ );
+
+ return renderComponent(
+ <GraphsTooltips
+ events={[mockAnalysisEvent({ key: '1' })]}
+ graph={graph}
+ graphWidth={100}
+ measuresHistory={measuresHistory}
+ selectedDate={date}
+ series={series}
+ tooltipIdx={0}
+ tooltipPos={0}
+ formatValue={(n: number | string) => String(n)}
+ {...props}
+ />
+ );
+}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-test.tsx
deleted file mode 100644
index d76eceafecb..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltips-test.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { parseDate } from '../../../helpers/dates';
-import { mockEvent } from '../../../helpers/testUtils';
-import GraphsTooltips from '../GraphsTooltips';
-import { DEFAULT_GRAPH } from '../utils';
-
-const SERIES_ISSUES = [
- {
- name: 'bugs',
- translatedName: 'Bugs',
- data: [
- {
- x: parseDate('2011-10-01T22:01:00.000Z'),
- y: 3,
- },
- {
- x: parseDate('2011-10-25T10:27:41.000Z'),
- y: 0,
- },
- ],
- type: 'INT',
- },
- {
- name: 'code_smells',
- translatedName: 'Code Smells',
- data: [
- {
- x: parseDate('2011-10-01T22:01:00.000Z'),
- y: 18,
- },
- {
- x: parseDate('2011-10-25T10:27:41.000Z'),
- y: 15,
- },
- ],
- type: 'INT',
- },
- {
- name: 'vulnerabilities',
- translatedName: 'Vulnerabilities',
- data: [
- {
- x: parseDate('2011-10-01T22:01:00.000Z'),
- y: 0,
- },
- {
- x: parseDate('2011-10-25T10:27:41.000Z'),
- y: 1,
- },
- ],
- type: 'INT',
- },
-];
-
-const DEFAULT_PROPS: GraphsTooltips['props'] = {
- events: [],
- formatValue: (val) => 'Formated.' + val,
- graph: DEFAULT_GRAPH,
- graphWidth: 500,
- measuresHistory: [],
- selectedDate: parseDate('2011-10-01T22:01:00.000Z'),
- series: SERIES_ISSUES,
- tooltipIdx: 0,
- tooltipPos: 666,
-};
-
-it('should render correctly for issues graphs', () => {
- expect(shallow(<GraphsTooltips {...DEFAULT_PROPS} />)).toMatchSnapshot();
- expect(shallow(<GraphsTooltips {...DEFAULT_PROPS} events={[mockEvent()]} />)).toMatchSnapshot(
- 'with events'
- );
-});
-
-it('should render correctly for random graphs', () => {
- expect(
- shallow(
- <GraphsTooltips
- {...DEFAULT_PROPS}
- graph="random"
- selectedDate={parseDate('2011-10-25T10:27:41.000Z')}
- tooltipIdx={1}
- />
- )
- ).toMatchSnapshot();
-});
-
-it('should not add separators if not needed', () => {
- expect(
- shallow(<GraphsTooltips {...DEFAULT_PROPS} graph="coverage" series={[]} />)
- ).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContent-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContent-test.tsx
deleted file mode 100644
index ab5c3cb022c..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContent-test.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import GraphsTooltipsContent from '../GraphsTooltipsContent';
-
-const DEFAULT_PROPS = {
- index: 1,
- name: 'code_smells',
- translatedName: 'Code Smells',
- value: '1.2k',
-};
-
-it('should render correctly', () => {
- expect(shallow(<GraphsTooltipsContent {...DEFAULT_PROPS} />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentCoverage-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentCoverage-test.tsx
deleted file mode 100644
index f7f1a6d1851..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentCoverage-test.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { parseDate } from '../../../helpers/dates';
-import GraphsTooltipsContentCoverage, {
- GraphsTooltipsContentCoverageProps,
-} from '../GraphsTooltipsContentCoverage';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(shallowRender({ addSeparator: true })).toMatchSnapshot('with separator');
- expect(shallowRender({ tooltipIdx: -1 }).type()).toBeNull();
-});
-
-function shallowRender(props: Partial<GraphsTooltipsContentCoverageProps> = {}) {
- return shallow<GraphsTooltipsContentCoverageProps>(
- <GraphsTooltipsContentCoverage
- addSeparator={false}
- measuresHistory={[
- {
- metric: 'coverage',
- history: [
- { date: parseDate('2011-10-01T22:01:00.000Z') },
- { date: parseDate('2011-10-25T10:27:41.000Z'), value: '80.3' },
- ],
- },
- {
- metric: 'lines_to_cover',
- history: [
- { date: parseDate('2011-10-01T22:01:00.000Z'), value: '60545' },
- { date: parseDate('2011-10-25T10:27:41.000Z'), value: '65215' },
- ],
- },
- {
- metric: 'uncovered_lines',
- history: [
- { date: parseDate('2011-10-01T22:01:00.000Z'), value: '40564' },
- { date: parseDate('2011-10-25T10:27:41.000Z'), value: '10245' },
- ],
- },
- ]}
- tooltipIdx={1}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentDuplication-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentDuplication-test.tsx
deleted file mode 100644
index 69d82091e3b..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentDuplication-test.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { parseDate } from '../../../helpers/dates';
-import GraphsTooltipsContentDuplication, {
- GraphsTooltipsContentDuplicationProps,
-} from '../GraphsTooltipsContentDuplication';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(shallowRender({ addSeparator: true })).toMatchSnapshot('with separator');
- expect(shallowRender({ tooltipIdx: -1 }).type()).toBeNull();
- expect(shallowRender({ measuresHistory: [] }).type()).toBeNull();
-});
-
-function shallowRender(props: Partial<GraphsTooltipsContentDuplicationProps> = {}) {
- return shallow<GraphsTooltipsContentDuplicationProps>(
- <GraphsTooltipsContentDuplication
- addSeparator={false}
- measuresHistory={[
- {
- metric: 'duplicated_lines_density',
- history: [
- { date: parseDate('2011-10-01T22:01:00.000Z') },
- { date: parseDate('2011-10-25T10:27:41.000Z'), value: '10245' },
- ],
- },
- ]}
- tooltipIdx={1}
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentEvents-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentEvents-test.tsx
deleted file mode 100644
index 24f8075b0cd..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentEvents-test.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import GraphsTooltipsContentEvents from '../GraphsTooltipsContentEvents';
-
-const EVENTS = [
- { key: '1', category: 'VERSION', name: '6.5' },
- { key: '2', category: 'OTHER', name: 'Foo' },
-];
-
-it('should render correctly', () => {
- expect(
- shallow(<GraphsTooltipsContentEvents addSeparator={true} events={EVENTS} />)
- ).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentIssues-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentIssues-test.tsx
deleted file mode 100644
index b3ab3a252cb..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/GraphsTooltipsContentIssues-test.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { parseDate } from '../../../helpers/dates';
-import GraphsTooltipsContentIssues, {
- GraphsTooltipsContentIssuesProps,
-} from '../GraphsTooltipsContentIssues';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(shallowRender({ tooltipIdx: -1 }).type()).toBeNull();
-});
-
-function shallowRender(props: Partial<GraphsTooltipsContentIssuesProps> = {}) {
- return shallow<GraphsTooltipsContentIssuesProps>(
- <GraphsTooltipsContentIssues
- index={2}
- measuresHistory={[
- {
- metric: 'bugs',
- history: [
- { date: parseDate('2011-10-01T22:01:00.000Z'), value: '500' },
- { date: parseDate('2011-10-25T10:27:41.000Z'), value: '1.2k' },
- ],
- },
- {
- metric: 'reliability_rating',
- history: [
- { date: parseDate('2011-10-01T22:01:00.000Z') },
- { date: parseDate('2011-10-25T10:27:41.000Z'), value: '5.0' },
- ],
- },
- ]}
- name="bugs"
- tooltipIdx={1}
- translatedName="Bugs"
- value="1.2k"
- {...props}
- />
- );
-}
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/RichQualityGateEventInner-test.tsx b/server/sonar-web/src/main/js/components/activity-graph/__tests__/RichQualityGateEventInner-test.tsx
deleted file mode 100644
index 471c2ad61db..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/RichQualityGateEventInner-test.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { click } from '../../../helpers/testUtils';
-import { RichQualityGateEvent, RichQualityGateEventInner } from '../RichQualityGateEventInner';
-
-const event: RichQualityGateEvent = {
- category: 'QUALITY_GATE',
- key: 'foo1234',
- name: '',
- qualityGate: {
- failing: [
- { branch: 'master', key: 'foo', name: 'Foo' },
- { branch: 'master', key: 'bar', name: 'Bar' },
- ],
- status: 'ERROR',
- stillFailing: true,
- },
-};
-
-it('should render', () => {
- const wrapper = shallow(<RichQualityGateEventInner event={event} />);
- expect(wrapper).toMatchSnapshot();
-
- click(wrapper.find('.project-activity-event-inner-more-link'));
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
-
-it('should not expand', () => {
- const wrapper = shallow(
- <RichQualityGateEventInner
- event={{ ...event, qualityGate: { ...event.qualityGate, failing: [] } }}
- />
- );
- expect(wrapper.find('.project-activity-event-inner-more-link').exists()).toBe(false);
-});
-
-it('should not expand when readonly', () => {
- const wrapper = shallow(<RichQualityGateEventInner event={event} readonly={true} />);
- expect(wrapper.find('.project-activity-event-inner-more-link').exists()).toBe(false);
-});
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/DefinitionChangeEventInner-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/DefinitionChangeEventInner-test.tsx.snap
deleted file mode 100644
index ce770c6fcd3..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/DefinitionChangeEventInner-test.tsx.snap
+++ /dev/null
@@ -1,248 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<Fragment>
- <span
- className="note"
- >
- event.category.DEFINITION_CHANGE
- :
- </span>
- <div>
- <ButtonLink
- className="project-activity-event-inner-more-link"
- onClick={[Function]}
- stopPropagation={true}
- >
- more
- <DropdownIcon
- className="little-spacer-left"
- turned={false}
- />
- </ButtonLink>
- </div>
-</Fragment>
-`;
-
-exports[`should render 2`] = `
-<Fragment>
- <span
- className="note"
- >
- event.category.DEFINITION_CHANGE
- :
- </span>
- <div>
- <ButtonLink
- className="project-activity-event-inner-more-link"
- onClick={[Function]}
- stopPropagation={true}
- >
- hide
- <DropdownIcon
- className="little-spacer-left"
- turned={true}
- />
- </ButtonLink>
- </div>
- <ul
- className="spacer-left spacer-top"
- >
- <li
- className="display-flex-center spacer-top"
- key="foo"
- >
- <div
- className="text-ellipsis"
- >
- <FormattedMessage
- defaultMessage="event.definition_change.added"
- id="event.definition_change.added"
- values={
- Object {
- "branch": <span
- className="nowrap"
- title="master"
- >
- <BranchIcon
- className="little-spacer-left text-text-top"
- />
- master
- </span>,
- "project": <ForwardRef(Link)
- onClick={[Function]}
- title="Foo"
- to={
- Object {
- "pathname": "/dashboard",
- "search": "?id=foo&branch=master",
- }
- }
- >
- Foo
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- </li>
- <li
- className="display-flex-center spacer-top"
- key="bar"
- >
- <div
- className="text-ellipsis"
- >
- <FormattedMessage
- defaultMessage="event.definition_change.removed"
- id="event.definition_change.removed"
- values={
- Object {
- "branch": <span
- className="nowrap"
- title="master"
- >
- <BranchIcon
- className="little-spacer-left text-text-top"
- />
- master
- </span>,
- "project": <ForwardRef(Link)
- onClick={[Function]}
- title="Bar"
- to={
- Object {
- "pathname": "/dashboard",
- "search": "?id=bar&branch=master",
- }
- }
- >
- Bar
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- </li>
- </ul>
-</Fragment>
-`;
-
-exports[`should render for a branch 1`] = `
-<Fragment>
- <span
- className="note"
- >
- event.category.DEFINITION_CHANGE
- :
- </span>
- <div>
- <ButtonLink
- className="project-activity-event-inner-more-link"
- onClick={[Function]}
- stopPropagation={true}
- >
- hide
- <DropdownIcon
- className="little-spacer-left"
- turned={true}
- />
- </ButtonLink>
- </div>
- <ul
- className="spacer-left spacer-top"
- >
- <li
- className="display-flex-center spacer-top"
- key="foo"
- >
- <div
- className="text-ellipsis"
- >
- <FormattedMessage
- defaultMessage="event.definition_change.branch_added"
- id="event.definition_change.branch_added"
- values={
- Object {
- "branch": <span
- className="nowrap"
- title="feature-x"
- >
- <BranchIcon
- className="little-spacer-left text-text-top"
- />
- feature-x
- </span>,
- "project": <ForwardRef(Link)
- onClick={[Function]}
- title="Foo"
- to={
- Object {
- "pathname": "/dashboard",
- "search": "?id=foo&branch=feature-x",
- }
- }
- >
- Foo
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- </li>
- <li
- className="display-flex-center spacer-top"
- key="bar"
- >
- <FormattedMessage
- defaultMessage="event.definition_change.branch_replaced"
- id="event.definition_change.branch_replaced"
- values={
- Object {
- "newBranch": <span
- className="nowrap"
- title="feature-y"
- >
- <BranchIcon
- className="little-spacer-left text-text-top"
- />
- feature-y
- </span>,
- "oldBranch": <span
- className="nowrap"
- title="master"
- >
- <BranchIcon
- className="little-spacer-left text-text-top"
- />
- master
- </span>,
- "project": <ForwardRef(Link)
- onClick={[Function]}
- title="Bar"
- to={
- Object {
- "pathname": "/dashboard",
- "search": "?id=bar&branch=feature-y",
- }
- }
- >
- Bar
- </ForwardRef(Link)>,
- }
- }
- />
- </li>
- </ul>
-</Fragment>
-`;
-
-exports[`should render when readonly 1`] = `
-<Fragment>
- <span
- className="note"
- >
- event.category.DEFINITION_CHANGE
- </span>
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendCustom-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendCustom-test.tsx.snap
deleted file mode 100644
index eb50e58ca57..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendCustom-test.tsx.snap
+++ /dev/null
@@ -1,52 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<div
- className="activity-graph-legends display-flex-center"
->
- <div
- className="flex-1"
- >
- <span
- className="spacer-left spacer-right"
- key="bugs"
- >
- <GraphsLegendItem
- index={0}
- metric="bugs"
- name="Bugs"
- removeMetric={[MockFunction]}
- showWarning={false}
- />
- </span>
- <span
- className="spacer-left spacer-right"
- key="my_metric"
- >
- <GraphsLegendItem
- index={1}
- metric="my_metric"
- name="My Metric"
- removeMetric={[MockFunction]}
- showWarning={false}
- />
- </span>
- <Tooltip
- key="foo"
- overlay="project_activity.graphs.custom.metric_no_history"
- >
- <span
- className="spacer-left spacer-right"
- >
- <GraphsLegendItem
- index={2}
- metric="foo"
- name="Foo"
- removeMetric={[MockFunction]}
- showWarning={true}
- />
- </span>
- </Tooltip>
- </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap
deleted file mode 100644
index 37369e0d970..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap
+++ /dev/null
@@ -1,58 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly a legend: default 1`] = `
-<span
- className=""
->
- <ChartLegendIcon
- className="text-middle spacer-right"
- index={2}
- />
- <span
- className="text-middle"
- >
- Bugs
- </span>
-</span>
-`;
-
-exports[`should render correctly a legend: with legend 1`] = `
-<span
- className="activity-graph-legend-actionable myclass"
->
- <ChartLegendIcon
- className="text-middle spacer-right"
- index={1}
- />
- <span
- className="text-middle"
- >
- Foo
- </span>
- <ClearButton
- aria-label="project_activity.graphs.custom.remove_metric.Foo"
- className="button-tiny spacer-left text-middle"
- iconProps={
- Object {
- "size": 12,
- }
- }
- onClick={[Function]}
- />
-</span>
-`;
-
-exports[`should render correctly a legend: with warning 1`] = `
-<span
- className=""
->
- <AlertWarnIcon
- className="spacer-right"
- />
- <span
- className="text-middle"
- >
- Bugs
- </span>
-</span>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendNewCode-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendNewCode-test.tsx.snap
deleted file mode 100644
index e6c7707ef39..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendNewCode-test.tsx.snap
+++ /dev/null
@@ -1,14 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<Tooltip
- overlay="project_activity.graphs.new_code_long"
->
- <span
- aria-label="project_activity.graphs.new_code_long"
- className="activity-graph-new-code-legend display-flex-center pull-right note"
- >
- project_activity.graphs.new_code
- </span>
-</Tooltip>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendStatic-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendStatic-test.tsx.snap
deleted file mode 100644
index 00239dc81f1..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsLegendStatic-test.tsx.snap
+++ /dev/null
@@ -1,22 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<div
- className="activity-graph-legends"
->
- <GraphsLegendItem
- className="big-spacer-left big-spacer-right"
- index={0}
- key="bugs"
- metric="bugs"
- name="Bugs"
- />
- <GraphsLegendItem
- className="big-spacer-left big-spacer-right"
- index={1}
- key="code_smells"
- metric="code_smells"
- name="Code Smells"
- />
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltips-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltips-test.tsx.snap
deleted file mode 100644
index c4f775ce431..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltips-test.tsx.snap
+++ /dev/null
@@ -1,226 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should not add separators if not needed 1`] = `
-<Popup
- className="disabled-pointer-events"
- placement="left-top"
- style={
- Object {
- "left": 476,
- "top": 30,
- "width": 250,
- }
- }
->
- <div
- className="activity-graph-tooltip"
- >
- <div
- className="activity-graph-tooltip-title spacer-bottom"
- >
- <DateTimeFormatter
- date={2011-10-01T22:01:00.000Z}
- />
- </div>
- <table
- className="width-100"
- >
- <tbody />
- <GraphsTooltipsContentCoverage
- addSeparator={false}
- measuresHistory={Array []}
- tooltipIdx={0}
- />
- </table>
- </div>
-</Popup>
-`;
-
-exports[`should render correctly for issues graphs 1`] = `
-<Popup
- className="disabled-pointer-events"
- placement="left-top"
- style={
- Object {
- "left": 476,
- "top": 30,
- "width": 250,
- }
- }
->
- <div
- className="activity-graph-tooltip"
- >
- <div
- className="activity-graph-tooltip-title spacer-bottom"
- >
- <DateTimeFormatter
- date={2011-10-01T22:01:00.000Z}
- />
- </div>
- <table
- className="width-100"
- >
- <tbody>
- <GraphsTooltipsContentIssues
- index={0}
- key="bugs"
- measuresHistory={Array []}
- name="bugs"
- tooltipIdx={0}
- translatedName="Bugs"
- value="Formated.3"
- />
- <GraphsTooltipsContentIssues
- index={1}
- key="code_smells"
- measuresHistory={Array []}
- name="code_smells"
- tooltipIdx={0}
- translatedName="Code Smells"
- value="Formated.18"
- />
- <GraphsTooltipsContentIssues
- index={2}
- key="vulnerabilities"
- measuresHistory={Array []}
- name="vulnerabilities"
- tooltipIdx={0}
- translatedName="Vulnerabilities"
- value="Formated.0"
- />
- </tbody>
- </table>
- </div>
-</Popup>
-`;
-
-exports[`should render correctly for issues graphs: with events 1`] = `
-<Popup
- className="disabled-pointer-events"
- placement="left-top"
- style={
- Object {
- "left": 476,
- "top": 30,
- "width": 250,
- }
- }
->
- <div
- className="activity-graph-tooltip"
- >
- <div
- className="activity-graph-tooltip-title spacer-bottom"
- >
- <DateTimeFormatter
- date={2011-10-01T22:01:00.000Z}
- />
- </div>
- <table
- className="width-100"
- >
- <GraphsTooltipsContentEvents
- addSeparator={true}
- events={
- Array [
- Object {
- "currentTarget": Object {
- "blur": [Function],
- },
- "preventDefault": [Function],
- "stopImmediatePropagation": [Function],
- "stopPropagation": [Function],
- "target": Object {
- "blur": [Function],
- },
- },
- ]
- }
- />
- <tbody>
- <GraphsTooltipsContentIssues
- index={0}
- key="bugs"
- measuresHistory={Array []}
- name="bugs"
- tooltipIdx={0}
- translatedName="Bugs"
- value="Formated.3"
- />
- <GraphsTooltipsContentIssues
- index={1}
- key="code_smells"
- measuresHistory={Array []}
- name="code_smells"
- tooltipIdx={0}
- translatedName="Code Smells"
- value="Formated.18"
- />
- <GraphsTooltipsContentIssues
- index={2}
- key="vulnerabilities"
- measuresHistory={Array []}
- name="vulnerabilities"
- tooltipIdx={0}
- translatedName="Vulnerabilities"
- value="Formated.0"
- />
- </tbody>
- </table>
- </div>
-</Popup>
-`;
-
-exports[`should render correctly for random graphs 1`] = `
-<Popup
- className="disabled-pointer-events"
- placement="left-top"
- style={
- Object {
- "left": 476,
- "top": 30,
- "width": 250,
- }
- }
->
- <div
- className="activity-graph-tooltip"
- >
- <div
- className="activity-graph-tooltip-title spacer-bottom"
- >
- <DateTimeFormatter
- date={2011-10-25T10:27:41.000Z}
- />
- </div>
- <table
- className="width-100"
- >
- <tbody>
- <GraphsTooltipsContent
- index={0}
- key="bugs"
- name="bugs"
- translatedName="Bugs"
- value="Formated.0"
- />
- <GraphsTooltipsContent
- index={1}
- key="code_smells"
- name="code_smells"
- translatedName="Code Smells"
- value="Formated.15"
- />
- <GraphsTooltipsContent
- index={2}
- key="vulnerabilities"
- name="vulnerabilities"
- translatedName="Vulnerabilities"
- value="Formated.1"
- />
- </tbody>
- </table>
- </div>
-</Popup>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContent-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContent-test.tsx.snap
deleted file mode 100644
index 4bfd687cf88..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContent-test.tsx.snap
+++ /dev/null
@@ -1,25 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<tr
- className="activity-graph-tooltip-line"
- key="code_smells"
->
- <td
- className="thin"
- >
- <ChartLegendIcon
- className="spacer-right"
- index={1}
- />
- </td>
- <td
- className="activity-graph-tooltip-value text-right spacer-right thin"
- >
- 1.2k
- </td>
- <td>
- Code Smells
- </td>
-</tr>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentCoverage-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentCoverage-test.tsx.snap
deleted file mode 100644
index f83e91ef9f5..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentCoverage-test.tsx.snap
+++ /dev/null
@@ -1,71 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<tbody>
- <tr
- className="activity-graph-tooltip-line"
- >
- <td
- className="activity-graph-tooltip-value text-right spacer-right thin"
- colSpan={2}
- >
- 10short_number_suffix.k
- </td>
- <td>
- metric.uncovered_lines.name
- </td>
- </tr>
- <tr
- className="activity-graph-tooltip-line"
- >
- <td
- className="activity-graph-tooltip-value text-right spacer-right thin"
- colSpan={2}
- >
- 80.3%
- </td>
- <td>
- metric.coverage.name
- </td>
- </tr>
-</tbody>
-`;
-
-exports[`should render correctly: with separator 1`] = `
-<tbody>
- <tr>
- <td
- className="activity-graph-tooltip-separator"
- colSpan={3}
- >
- <hr />
- </td>
- </tr>
- <tr
- className="activity-graph-tooltip-line"
- >
- <td
- className="activity-graph-tooltip-value text-right spacer-right thin"
- colSpan={2}
- >
- 10short_number_suffix.k
- </td>
- <td>
- metric.uncovered_lines.name
- </td>
- </tr>
- <tr
- className="activity-graph-tooltip-line"
- >
- <td
- className="activity-graph-tooltip-value text-right spacer-right thin"
- colSpan={2}
- >
- 80.3%
- </td>
- <td>
- metric.coverage.name
- </td>
- </tr>
-</tbody>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentDuplication-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentDuplication-test.tsx.snap
deleted file mode 100644
index 30fc8c8118a..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentDuplication-test.tsx.snap
+++ /dev/null
@@ -1,45 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<tbody>
- <tr
- className="activity-graph-tooltip-line"
- >
- <td
- className="activity-graph-tooltip-value text-right spacer-right thin"
- colSpan={2}
- >
- 10,245.0%
- </td>
- <td>
- metric.duplicated_lines_density.name
- </td>
- </tr>
-</tbody>
-`;
-
-exports[`should render correctly: with separator 1`] = `
-<tbody>
- <tr>
- <td
- className="activity-graph-tooltip-separator"
- colSpan={3}
- >
- <hr />
- </td>
- </tr>
- <tr
- className="activity-graph-tooltip-line"
- >
- <td
- className="activity-graph-tooltip-value text-right spacer-right thin"
- colSpan={2}
- >
- 10,245.0%
- </td>
- <td>
- metric.duplicated_lines_density.name
- </td>
- </tr>
-</tbody>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentEvents-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentEvents-test.tsx.snap
deleted file mode 100644
index c4297a01b3d..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentEvents-test.tsx.snap
+++ /dev/null
@@ -1,60 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<tbody>
- <tr>
- <td
- className="activity-graph-tooltip-separator"
- colSpan={3}
- >
- <hr />
- </td>
- </tr>
- <tr
- className="activity-graph-tooltip-line"
- >
- <td
- colSpan={3}
- >
- <div
- className="little-spacer-bottom"
- key="1"
- >
- <EventInner
- event={
- Object {
- "category": "VERSION",
- "key": "1",
- "name": "6.5",
- }
- }
- readonly={true}
- />
- </div>
- <div
- className="little-spacer-bottom"
- key="2"
- >
- <EventInner
- event={
- Object {
- "category": "OTHER",
- "key": "2",
- "name": "Foo",
- }
- }
- readonly={true}
- />
- </div>
- </td>
- </tr>
- <tr>
- <td
- className="activity-graph-tooltip-separator"
- colSpan={3}
- >
- <hr />
- </td>
- </tr>
-</tbody>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentIssues-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentIssues-test.tsx.snap
deleted file mode 100644
index 43f9d71b1dc..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/GraphsTooltipsContentIssues-test.tsx.snap
+++ /dev/null
@@ -1,34 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<tr
- className="activity-graph-tooltip-issues-line"
- key="bugs"
->
- <td
- className="thin"
- >
- <ChartLegendIcon
- className="spacer-right"
- index={2}
- />
- </td>
- <td
- className="text-right spacer-right"
- >
- <span
- className="activity-graph-tooltip-value"
- >
- 1.2k
- </span>
- <Rating
- className="spacer-left"
- small={true}
- value="5.0"
- />
- </td>
- <td>
- Bugs
- </td>
-</tr>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/RichQualityGateEventInner-test.tsx.snap b/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/RichQualityGateEventInner-test.tsx.snap
deleted file mode 100644
index cd9373673f2..00000000000
--- a/server/sonar-web/src/main/js/components/activity-graph/__tests__/__snapshots__/RichQualityGateEventInner-test.tsx.snap
+++ /dev/null
@@ -1,139 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<Fragment>
- <span
- className="note spacer-right"
- >
- event.category.QUALITY_GATE
- :
- </span>
- <FormattedMessage
- defaultMessage="event.quality_gate.still_x"
- id="event.quality_gate.still_x"
- values={
- Object {
- "status": <Level
- level="ERROR"
- small={true}
- />,
- }
- }
- />
- <div>
- <ResetButtonLink
- className="project-activity-event-inner-more-link"
- onClick={[Function]}
- stopPropagation={true}
- >
- more
- <DropdownIcon
- className="little-spacer-left"
- turned={false}
- />
- </ResetButtonLink>
- </div>
-</Fragment>
-`;
-
-exports[`should render 2`] = `
-<Fragment>
- <span
- className="note spacer-right"
- >
- event.category.QUALITY_GATE
- :
- </span>
- <FormattedMessage
- defaultMessage="event.quality_gate.still_x"
- id="event.quality_gate.still_x"
- values={
- Object {
- "status": <Level
- level="ERROR"
- small={true}
- />,
- }
- }
- />
- <div>
- <ResetButtonLink
- className="project-activity-event-inner-more-link"
- onClick={[Function]}
- stopPropagation={true}
- >
- hide
- <DropdownIcon
- className="little-spacer-left"
- turned={true}
- />
- </ResetButtonLink>
- </div>
- <ul
- className="spacer-left spacer-top"
- >
- <li
- className="display-flex-center spacer-top"
- key="foo"
- >
- <Level
- aria-label="quality_gates.status"
- className="spacer-right"
- level="ERROR"
- small={true}
- />
- <div
- className="flex-1 text-ellipsis"
- >
- <ForwardRef(Link)
- onClick={[Function]}
- title="Foo"
- to={
- Object {
- "pathname": "/dashboard",
- "search": "?id=foo&branch=master",
- }
- }
- >
- <span
- aria-label="project_x.Foo"
- >
- Foo
- </span>
- </ForwardRef(Link)>
- </div>
- </li>
- <li
- className="display-flex-center spacer-top"
- key="bar"
- >
- <Level
- aria-label="quality_gates.status"
- className="spacer-right"
- level="ERROR"
- small={true}
- />
- <div
- className="flex-1 text-ellipsis"
- >
- <ForwardRef(Link)
- onClick={[Function]}
- title="Bar"
- to={
- Object {
- "pathname": "/dashboard",
- "search": "?id=bar&branch=master",
- }
- }
- >
- <span
- aria-label="project_x.Bar"
- >
- Bar
- </span>
- </ForwardRef(Link)>
- </div>
- </li>
- </ul>
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/components/activity-graph/styles.css b/server/sonar-web/src/main/js/components/activity-graph/styles.css
index 73d9cda0f64..81e4f03e602 100644
--- a/server/sonar-web/src/main/js/components/activity-graph/styles.css
+++ b/server/sonar-web/src/main/js/components/activity-graph/styles.css
@@ -54,9 +54,9 @@
}
.activity-graph-legends {
- flex-grow: 0;
+ display: flex;
+ justify-content: center;
padding-bottom: calc(2 * var(--gridSize));
- text-align: center;
}
.activity-graph-legend-actionable {