Browse Source

SONAR-13307: Fix application branch overview with different project branch

tags/8.3.0.34182
Mathieu Suen 4 years ago
parent
commit
a35c677063

+ 8
- 1
server/sonar-web/src/main/js/api/application.ts View File

@@ -19,7 +19,7 @@
*/
import { getJSON } from 'sonar-ui-common/helpers/request';
import throwGlobalError from '../app/utils/throwGlobalError';
import { ApplicationPeriod } from '../types/application';
import { Application, ApplicationPeriod } from '../types/application';

export function getApplicationLeak(
application: string,
@@ -30,3 +30,10 @@ export function getApplicationLeak(
throwGlobalError
);
}

export function getApplicationDetails(application: string, branch?: string): Promise<Application> {
return getJSON('/api/applications/show', { application, branch }).then(
r => r.application,
throwGlobalError
);
}

+ 30
- 12
server/sonar-web/src/main/js/apps/overview/branches/BranchOverview.tsx View File

@@ -21,7 +21,7 @@ import { sortBy, uniq } from 'lodash';
import * as React from 'react';
import { parseDate, toNotSoISOString } from 'sonar-ui-common/helpers/dates';
import { isDefined } from 'sonar-ui-common/helpers/types';
import { getApplicationLeak } from '../../../api/application';
import { getApplicationDetails, getApplicationLeak } from '../../../api/application';
import { getMeasuresWithPeriodAndMetrics } from '../../../api/measures';
import { getProjectActivity } from '../../../api/projectActivity';
import { getApplicationQualityGate, getQualityGateProjectStatus } from '../../../api/quality-gates';
@@ -34,6 +34,7 @@ import {
import {
getBranchLikeDisplayName,
getBranchLikeQuery,
isMainBranch,
isSameBranchLike
} from '../../../helpers/branch-like';
import { enhanceConditionWithMeasure, enhanceMeasuresWithMetrics } from '../../../helpers/measures';
@@ -116,7 +117,6 @@ export default class BranchOverview extends React.PureComponent<Props, State> {
loadApplicationStatus = async () => {
const { branchLike, component } = this.props;
this.setState({ loadingStatus: true });

// Start by loading the application quality gate info, as well as the meta
// data for the application as a whole.
const appStatus = await getApplicationQualityGate({
@@ -124,11 +124,18 @@ export default class BranchOverview extends React.PureComponent<Props, State> {
...getBranchLikeQuery(branchLike)
});
const { measures: appMeasures, metrics, period } = await this.loadMeasuresAndMeta(
component.key
component.key,
branchLike
);

const appBranchName =
(branchLike && !isMainBranch(branchLike) && getBranchLikeDisplayName(branchLike)) ||
undefined;

const appDetails = await getApplicationDetails(component.key, appBranchName);

// We also need to load the application leak periods separately.
getApplicationLeak(component.key, branchLike && getBranchLikeDisplayName(branchLike)).then(
getApplicationLeak(component.key, appBranchName).then(
leaks => {
if (this.mounted && leaks && leaks.length) {
const sortedLeaks = sortBy(leaks, leak => {
@@ -152,20 +159,27 @@ export default class BranchOverview extends React.PureComponent<Props, State> {
// information, unfortunately, as they are aggregated.
Promise.all(
appStatus.projects.map(project => {
const projectDetails = appDetails.projects.find(p => p.key === project.key);
const projectBranchLike = projectDetails
? { isMain: projectDetails.isMain, name: projectDetails.branch, excludedFromPurge: false }
: undefined;

return this.loadMeasuresAndMeta(
project.key,
projectBranchLike,
// Only load metrics that apply to failing QG conditions; we don't
// need the others anyway.
project.conditions.filter(c => c.status !== 'OK').map(c => c.metric)
).then(({ measures }) => ({
measures,
project
project,
projectBranchLike
}));
})
).then(
results => {
if (this.mounted) {
const qgStatuses = results.map(({ measures = [], project }) => {
const qgStatuses = results.map(({ measures = [], project, projectBranchLike }) => {
const { key, name, status } = project;
const conditions = extractStatusConditionsFromApplicationStatusChildProject(project);
const failedConditions = this.getFailedConditions(conditions, measures);
@@ -174,7 +188,8 @@ export default class BranchOverview extends React.PureComponent<Props, State> {
failedConditions,
key,
name,
status
status,
branchLike: projectBranchLike
};
});

@@ -214,7 +229,7 @@ export default class BranchOverview extends React.PureComponent<Props, State> {
? uniq([...METRICS, ...projectStatus.conditions.map(c => c.metricKey)])
: METRICS;

this.loadMeasuresAndMeta(key, metricKeys).then(
this.loadMeasuresAndMeta(key, branchLike, metricKeys).then(
({ measures, metrics, period }) => {
if (this.mounted && measures) {
const { ignoredConditions, status } = projectStatus;
@@ -226,7 +241,8 @@ export default class BranchOverview extends React.PureComponent<Props, State> {
failedConditions,
key,
name,
status
status,
branchLike
};

this.setState({
@@ -248,9 +264,11 @@ export default class BranchOverview extends React.PureComponent<Props, State> {
);
};

loadMeasuresAndMeta = (componentKey: string, metricKeys: string[] = []) => {
const { branchLike } = this.props;

loadMeasuresAndMeta = (
componentKey: string,
branchLike?: BranchLike,
metricKeys: string[] = []
) => {
return getMeasuresWithPeriodAndMetrics(
componentKey,
metricKeys.length > 0 ? metricKeys : METRICS,

+ 0
- 1
server/sonar-web/src/main/js/apps/overview/branches/BranchOverviewRenderer.tsx View File

@@ -74,7 +74,6 @@ export function BranchOverviewRenderer(props: BranchOverviewRendererProps) {
<div className="display-flex-row">
<div className="width-25 big-spacer-right">
<QualityGatePanel
branchLike={branchLike}
component={component}
loading={loadingStatus}
qgStatuses={qgStatuses}

+ 1
- 4
server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanel.tsx View File

@@ -24,19 +24,17 @@ import { Alert } from 'sonar-ui-common/components/ui/Alert';
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
import DocTooltip from '../../../components/docs/DocTooltip';
import { BranchLike } from '../../../types/branch-like';
import { QualityGateStatus } from '../../../types/quality-gates';
import QualityGatePanelSection from './QualityGatePanelSection';

export interface QualityGatePanelProps {
branchLike?: BranchLike;
component: Pick<T.Component, 'key' | 'qualifier'>;
loading?: boolean;
qgStatuses?: QualityGateStatus[];
}

export function QualityGatePanel(props: QualityGatePanelProps) {
const { branchLike, component, loading, qgStatuses = [] } = props;
const { component, loading, qgStatuses = [] } = props;

if (qgStatuses === undefined) {
return null;
@@ -107,7 +105,6 @@ export function QualityGatePanel(props: QualityGatePanelProps) {
<div data-test="overview__quality-gate-conditions">
{qgStatuses.map(qgStatus => (
<QualityGatePanelSection
branchLike={branchLike}
component={component}
key={qgStatus.key}
qgStatus={qgStatus}

+ 3
- 3
server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx View File

@@ -32,7 +32,7 @@ export interface QualityGatePanelSectionProps {
}

export function QualityGatePanelSection(props: QualityGatePanelSectionProps) {
const { branchLike, component, qgStatus } = props;
const { component, qgStatus } = props;
const newCodeFailedConditions = qgStatus.failedConditions.filter(c => isDiffMetric(c.metric));
const overallFailedConditions = qgStatus.failedConditions.filter(c => !isDiffMetric(c.metric));

@@ -54,8 +54,8 @@ export function QualityGatePanelSection(props: QualityGatePanelSectionProps) {
{translate('quality_gates.conditions.new_code')}
</h4>
<QualityGateConditions
branchLike={branchLike}
component={qgStatus}
branchLike={qgStatus.branchLike}
failedConditions={newCodeFailedConditions}
/>
</>
@@ -67,8 +67,8 @@ export function QualityGatePanelSection(props: QualityGatePanelSectionProps) {
{translate('quality_gates.conditions.overall_code')}
</h4>
<QualityGateConditions
branchLike={branchLike}
component={qgStatus}
branchLike={qgStatus.branchLike}
failedConditions={overallFailedConditions}
/>
</>

+ 22
- 2
server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-test.tsx View File

@@ -22,7 +22,7 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import { isDiffMetric } from 'sonar-ui-common/helpers/measures';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { getApplicationLeak } from '../../../../api/application';
import { getApplicationDetails, getApplicationLeak } from '../../../../api/application';
import { getMeasuresWithPeriodAndMetrics } from '../../../../api/measures';
import { getProjectActivity } from '../../../../api/projectActivity';
import {
@@ -31,7 +31,7 @@ import {
} from '../../../../api/quality-gates';
import { getTimeMachineData } from '../../../../api/time-machine';
import { getActivityGraph, saveActivityGraph } from '../../../../components/activity-graph/utils';
import { mockMainBranch } from '../../../../helpers/mocks/branch-like';
import { mockBranch, mockMainBranch } from '../../../../helpers/mocks/branch-like';
import { mockComponent } from '../../../../helpers/testMocks';
import { ComponentQualifier } from '../../../../types/component';
import { MetricKey } from '../../../../types/metrics';
@@ -152,6 +152,19 @@ jest.mock('../../../../api/projectActivity', () => {
});

jest.mock('../../../../api/application', () => ({
getApplicationDetails: jest.fn().mockResolvedValue({
branches: [],
key: 'key-1',
name: 'app',
projects: [
{
branch: 'foo',
key: 'KEY-P1',
name: 'P1'
}
],
visibility: 'Private'
}),
getApplicationLeak: jest.fn().mockResolvedValue([
{
date: '2017-01-05',
@@ -240,6 +253,13 @@ describe('application overview', () => {
expect(wrapper).toMatchSnapshot();
});

it('should fetch correctly other branch', async () => {
const wrapper = shallowRender({ branchLike: mockBranch(), component });
await waitAndUpdate(wrapper);
expect(getApplicationDetails).toHaveBeenCalled();
expect(wrapper).toMatchSnapshot();
});

it("should correctly load an application's status", async () => {
const wrapper = shallowRender({ component });
await waitAndUpdate(wrapper);

+ 0
- 2
server/sonar-web/src/main/js/apps/overview/branches/__tests__/QualityGatePanel-test.tsx View File

@@ -19,7 +19,6 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
import { mockMainBranch } from '../../../../helpers/mocks/branch-like';
import {
mockQualityGateStatus,
mockQualityGateStatusConditionEnhanced
@@ -78,7 +77,6 @@ it('should render correctly for applications', () => {
function shallowRender(props: Partial<QualityGatePanelProps> = {}) {
return shallow(
<QualityGatePanel
branchLike={mockMainBranch()}
component={mockComponent()}
qgStatuses={[mockQualityGateStatus()]}
{...props}

+ 962
- 0
server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/BranchOverview-test.tsx.snap View File

@@ -1,5 +1,959 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`application overview should fetch correctly other branch 1`] = `
<Memo(BranchOverviewRenderer)
analyses={
Array [
Object {
"date": "2017-03-01T09:36:01+0100",
"events": Array [],
"key": "foo",
"projectVersion": "1.0",
},
Object {
"date": "2017-03-01T09:36:01+0100",
"events": Array [],
"key": "foo",
"projectVersion": "1.0",
},
Object {
"date": "2017-03-01T09:36:01+0100",
"events": Array [],
"key": "foo",
"projectVersion": "1.0",
},
Object {
"date": "2017-03-01T09:36:01+0100",
"events": Array [],
"key": "foo",
"projectVersion": "1.0",
},
Object {
"date": "2017-03-01T09:36:01+0100",
"events": Array [],
"key": "foo",
"projectVersion": "1.0",
},
]
}
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": false,
"name": "branch-6.7",
}
}
component={
Object {
"breadcrumbs": Array [
Object {
"breadcrumbs": Array [],
"key": "foo",
"name": "MyProject",
"organization": "foo",
"qualifier": "APP",
"qualityGate": Object {
"isDefault": true,
"key": "30",
"name": "Sonar way",
},
"qualityProfiles": Array [
Object {
"deleted": false,
"key": "my-qp",
"language": "ts",
"name": "Sonar way",
},
],
"tags": Array [],
},
],
"key": "my-project",
"name": "MyProject",
"organization": "foo",
"qualifier": "APP",
"qualityGate": Object {
"isDefault": true,
"key": "30",
"name": "Sonar way",
},
"qualityProfiles": Array [
Object {
"deleted": false,
"key": "my-qp",
"language": "ts",
"name": "Sonar way",
},
],
"tags": Array [],
}
}
graph="coverage"
leakPeriod={
Object {
"date": "2017-01-05",
"project": "foo",
"projectName": "Foo",
}
}
loadingHistory={false}
loadingStatus={false}
measures={
Array [
Object {
"bestValue": true,
"metric": Object {
"id": "alert_status",
"key": "alert_status",
"name": "alert_status",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "quality_gate_details",
"key": "quality_gate_details",
"name": "quality_gate_details",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "bugs",
"key": "bugs",
"name": "bugs",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_bugs",
"key": "new_bugs",
"name": "new_bugs",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "reliability_rating",
"key": "reliability_rating",
"name": "reliability_rating",
"type": "RATING",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_reliability_rating",
"key": "new_reliability_rating",
"name": "new_reliability_rating",
"type": "RATING",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "vulnerabilities",
"key": "vulnerabilities",
"name": "vulnerabilities",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_vulnerabilities",
"key": "new_vulnerabilities",
"name": "new_vulnerabilities",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "security_rating",
"key": "security_rating",
"name": "security_rating",
"type": "RATING",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_security_rating",
"key": "new_security_rating",
"name": "new_security_rating",
"type": "RATING",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "security_hotspots",
"key": "security_hotspots",
"name": "security_hotspots",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_security_hotspots",
"key": "new_security_hotspots",
"name": "new_security_hotspots",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "security_hotspots_reviewed",
"key": "security_hotspots_reviewed",
"name": "security_hotspots_reviewed",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_security_hotspots_reviewed",
"key": "new_security_hotspots_reviewed",
"name": "new_security_hotspots_reviewed",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "security_review_rating",
"key": "security_review_rating",
"name": "security_review_rating",
"type": "RATING",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_security_review_rating",
"key": "new_security_review_rating",
"name": "new_security_review_rating",
"type": "RATING",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "code_smells",
"key": "code_smells",
"name": "code_smells",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_code_smells",
"key": "new_code_smells",
"name": "new_code_smells",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "sqale_rating",
"key": "sqale_rating",
"name": "sqale_rating",
"type": "RATING",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_maintainability_rating",
"key": "new_maintainability_rating",
"name": "new_maintainability_rating",
"type": "RATING",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "sqale_index",
"key": "sqale_index",
"name": "sqale_index",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_technical_debt",
"key": "new_technical_debt",
"name": "new_technical_debt",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "coverage",
"key": "coverage",
"name": "coverage",
"type": "PERCENT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_coverage",
"key": "new_coverage",
"name": "new_coverage",
"type": "PERCENT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "lines_to_cover",
"key": "lines_to_cover",
"name": "lines_to_cover",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_lines_to_cover",
"key": "new_lines_to_cover",
"name": "new_lines_to_cover",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "tests",
"key": "tests",
"name": "tests",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "duplicated_lines_density",
"key": "duplicated_lines_density",
"name": "duplicated_lines_density",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_duplicated_lines_density",
"key": "new_duplicated_lines_density",
"name": "new_duplicated_lines_density",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "duplicated_blocks",
"key": "duplicated_blocks",
"name": "duplicated_blocks",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "ncloc",
"key": "ncloc",
"name": "ncloc",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "ncloc_language_distribution",
"key": "ncloc_language_distribution",
"name": "ncloc_language_distribution",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "projects",
"key": "projects",
"name": "projects",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"metric": Object {
"id": "lines",
"key": "lines",
"name": "lines",
"type": "INT",
},
"periods": undefined,
"value": "1.0",
},
Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_lines",
"key": "new_lines",
"name": "new_lines",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
]
}
measuresHistory={
Array [
Object {
"history": Array [
Object {
"date": "PARSED:2019-01-05",
"value": "2.0",
},
],
"metric": "bugs",
},
Object {
"history": Array [
Object {
"date": "PARSED:2019-01-05",
"value": "0",
},
],
"metric": "vulnerabilities",
},
Object {
"history": Array [
Object {
"date": "PARSED:2019-01-01",
"value": "1.0",
},
],
"metric": "sqale_index",
},
Object {
"history": Array [
Object {
"date": "PARSED:2019-01-02",
"value": "1.0",
},
],
"metric": "duplicated_lines_density",
},
Object {
"history": Array [
Object {
"date": "PARSED:2019-01-03",
"value": "10000",
},
],
"metric": "ncloc",
},
Object {
"history": Array [
Object {
"date": "PARSED:2019-01-04",
"value": "95.5",
},
],
"metric": "coverage",
},
]
}
metrics={
Array [
Object {
"id": "alert_status",
"key": "alert_status",
"name": "alert_status",
"type": "INT",
},
Object {
"id": "quality_gate_details",
"key": "quality_gate_details",
"name": "quality_gate_details",
"type": "INT",
},
Object {
"id": "bugs",
"key": "bugs",
"name": "bugs",
"type": "INT",
},
Object {
"id": "new_bugs",
"key": "new_bugs",
"name": "new_bugs",
"type": "INT",
},
Object {
"id": "reliability_rating",
"key": "reliability_rating",
"name": "reliability_rating",
"type": "RATING",
},
Object {
"id": "new_reliability_rating",
"key": "new_reliability_rating",
"name": "new_reliability_rating",
"type": "RATING",
},
Object {
"id": "vulnerabilities",
"key": "vulnerabilities",
"name": "vulnerabilities",
"type": "INT",
},
Object {
"id": "new_vulnerabilities",
"key": "new_vulnerabilities",
"name": "new_vulnerabilities",
"type": "INT",
},
Object {
"id": "security_rating",
"key": "security_rating",
"name": "security_rating",
"type": "RATING",
},
Object {
"id": "new_security_rating",
"key": "new_security_rating",
"name": "new_security_rating",
"type": "RATING",
},
Object {
"id": "security_hotspots",
"key": "security_hotspots",
"name": "security_hotspots",
"type": "INT",
},
Object {
"id": "new_security_hotspots",
"key": "new_security_hotspots",
"name": "new_security_hotspots",
"type": "INT",
},
Object {
"id": "security_hotspots_reviewed",
"key": "security_hotspots_reviewed",
"name": "security_hotspots_reviewed",
"type": "INT",
},
Object {
"id": "new_security_hotspots_reviewed",
"key": "new_security_hotspots_reviewed",
"name": "new_security_hotspots_reviewed",
"type": "INT",
},
Object {
"id": "security_review_rating",
"key": "security_review_rating",
"name": "security_review_rating",
"type": "RATING",
},
Object {
"id": "new_security_review_rating",
"key": "new_security_review_rating",
"name": "new_security_review_rating",
"type": "RATING",
},
Object {
"id": "code_smells",
"key": "code_smells",
"name": "code_smells",
"type": "INT",
},
Object {
"id": "new_code_smells",
"key": "new_code_smells",
"name": "new_code_smells",
"type": "INT",
},
Object {
"id": "sqale_rating",
"key": "sqale_rating",
"name": "sqale_rating",
"type": "RATING",
},
Object {
"id": "new_maintainability_rating",
"key": "new_maintainability_rating",
"name": "new_maintainability_rating",
"type": "RATING",
},
Object {
"id": "sqale_index",
"key": "sqale_index",
"name": "sqale_index",
"type": "INT",
},
Object {
"id": "new_technical_debt",
"key": "new_technical_debt",
"name": "new_technical_debt",
"type": "INT",
},
Object {
"id": "coverage",
"key": "coverage",
"name": "coverage",
"type": "PERCENT",
},
Object {
"id": "new_coverage",
"key": "new_coverage",
"name": "new_coverage",
"type": "PERCENT",
},
Object {
"id": "lines_to_cover",
"key": "lines_to_cover",
"name": "lines_to_cover",
"type": "INT",
},
Object {
"id": "new_lines_to_cover",
"key": "new_lines_to_cover",
"name": "new_lines_to_cover",
"type": "INT",
},
Object {
"id": "tests",
"key": "tests",
"name": "tests",
"type": "INT",
},
Object {
"id": "duplicated_lines_density",
"key": "duplicated_lines_density",
"name": "duplicated_lines_density",
"type": "INT",
},
Object {
"id": "new_duplicated_lines_density",
"key": "new_duplicated_lines_density",
"name": "new_duplicated_lines_density",
"type": "INT",
},
Object {
"id": "duplicated_blocks",
"key": "duplicated_blocks",
"name": "duplicated_blocks",
"type": "INT",
},
Object {
"id": "ncloc",
"key": "ncloc",
"name": "ncloc",
"type": "INT",
},
Object {
"id": "ncloc_language_distribution",
"key": "ncloc_language_distribution",
"name": "ncloc_language_distribution",
"type": "INT",
},
Object {
"id": "projects",
"key": "projects",
"name": "projects",
"type": "INT",
},
Object {
"id": "lines",
"key": "lines",
"name": "lines",
"type": "INT",
},
Object {
"id": "new_lines",
"key": "new_lines",
"name": "new_lines",
"type": "INT",
},
]
}
onGraphChange={[Function]}
projectIsEmpty={false}
qgStatuses={
Array [
Object {
"branchLike": undefined,
"failedConditions": Array [
Object {
"actual": "10",
"error": "1.0",
"level": "ERROR",
"measure": Object {
"bestValue": true,
"metric": Object {
"id": "coverage",
"key": "coverage",
"name": "coverage",
"type": "PERCENT",
},
"periods": undefined,
"value": "1.0",
},
"metric": "coverage",
"op": "GT",
"period": undefined,
},
Object {
"actual": "5",
"error": "1.0",
"level": "ERROR",
"measure": Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_bugs",
"key": "new_bugs",
"name": "new_bugs",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
"metric": "new_bugs",
"op": "GT",
"period": 1,
},
],
"key": "foo",
"name": "Foo",
"status": "ERROR",
},
Object {
"branchLike": undefined,
"failedConditions": Array [
Object {
"actual": "15",
"error": "5.0",
"level": "ERROR",
"measure": Object {
"bestValue": true,
"leak": "1",
"metric": Object {
"id": "new_bugs",
"key": "new_bugs",
"name": "new_bugs",
"type": "INT",
},
"periods": Array [
Object {
"bestValue": true,
"index": 1,
"value": "1.0",
},
],
"value": "1.0",
},
"metric": "new_bugs",
"op": "GT",
"period": 1,
},
],
"key": "bar",
"name": "Bar",
"status": "ERROR",
},
]
}
/>
`;

exports[`application overview should render correctly 1`] = `
<Memo(BranchOverviewRenderer)
analyses={
@@ -863,6 +1817,7 @@ exports[`application overview should render correctly 1`] = `
qgStatuses={
Array [
Object {
"branchLike": undefined,
"failedConditions": Array [
Object {
"actual": "10",
@@ -915,6 +1870,7 @@ exports[`application overview should render correctly 1`] = `
"status": "ERROR",
},
Object {
"branchLike": undefined,
"failedConditions": Array [
Object {
"actual": "15",
@@ -1808,6 +2764,12 @@ exports[`project overview should render correctly 1`] = `
qgStatuses={
Array [
Object {
"branchLike": Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
},
"failedConditions": Array [
Object {
"actual": "2",

+ 0
- 16
server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/BranchOverviewRenderer-test.tsx.snap View File

@@ -17,14 +17,6 @@ exports[`should render correctly 1`] = `
className="width-25 big-spacer-right"
>
<Memo(QualityGatePanel)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],
@@ -244,14 +236,6 @@ exports[`should render correctly 3`] = `
className="width-25 big-spacer-right"
>
<Memo(QualityGatePanel)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],

+ 0
- 48
server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanel-test.tsx.snap View File

@@ -36,14 +36,6 @@ exports[`should render correctly for applications 1`] = `
data-test="overview__quality-gate-conditions"
>
<Memo(QualityGatePanelSection)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],
@@ -105,14 +97,6 @@ exports[`should render correctly for applications 1`] = `
}
/>
<Memo(QualityGatePanelSection)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],
@@ -239,14 +223,6 @@ exports[`should render correctly for applications 2`] = `
data-test="overview__quality-gate-conditions"
>
<Memo(QualityGatePanelSection)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],
@@ -308,14 +284,6 @@ exports[`should render correctly for applications 2`] = `
}
/>
<Memo(QualityGatePanelSection)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],
@@ -391,14 +359,6 @@ exports[`should render correctly for projects 1`] = `
data-test="overview__quality-gate-conditions"
>
<Memo(QualityGatePanelSection)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],
@@ -551,14 +511,6 @@ exports[`should render correctly for projects 3`] = `
data-test="overview__quality-gate-conditions"
>
<Memo(QualityGatePanelSection)
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"breadcrumbs": Array [],

+ 0
- 32
server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap View File

@@ -10,14 +10,6 @@ exports[`should render correctly 1`] = `
quality_gates.conditions.new_code
</h4>
<QualityGateConditions
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"failedConditions": Array [
@@ -114,14 +106,6 @@ exports[`should render correctly 1`] = `
quality_gates.conditions.overall_code
</h4>
<QualityGateConditions
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"failedConditions": Array [
@@ -230,14 +214,6 @@ exports[`should render correctly 2`] = `
quality_gates.conditions.new_code
</h4>
<QualityGateConditions
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"failedConditions": Array [
@@ -334,14 +310,6 @@ exports[`should render correctly 2`] = `
quality_gates.conditions.overall_code
</h4>
<QualityGateConditions
branchLike={
Object {
"analysisDate": "2018-01-01",
"excludedFromPurge": true,
"isMain": true,
"name": "master",
}
}
component={
Object {
"failedConditions": Array [

+ 21
- 0
server/sonar-web/src/main/js/types/application.ts View File

@@ -17,8 +17,29 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { Branch } from './branch-like';
import { Visibility } from './component';

export interface ApplicationPeriod {
date: string;
project: string;
projectName: string;
}

export interface Application {
branches: Pick<Branch, 'isMain' | 'name'>[];
description?: string;
key: string;
name: string;
projects: ApplicationProject[];
visibility: Visibility;
}

export interface ApplicationProject {
branch: string;
enabled?: boolean;
isMain: boolean;
key: string;
name: string;
selected?: boolean;
}

+ 5
- 0
server/sonar-web/src/main/js/types/component.ts View File

@@ -28,3 +28,8 @@ export enum ComponentQualifier {
SubProject = 'BRC',
TestFile = 'UTS'
}

export enum Visibility {
Public = 'public',
Private = 'private'
}

+ 3
- 0
server/sonar-web/src/main/js/types/quality-gates.ts View File

@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { BranchLike } from './branch-like';

export interface QualityGateProjectStatus {
conditions?: QualityGateProjectStatusCondition[];
ignoredConditions: boolean;
@@ -62,6 +64,7 @@ export interface QualityGateStatus {
key: string;
name: string;
status: T.Status;
branchLike?: BranchLike;
}

export interface QualityGateStatusCondition {

Loading…
Cancel
Save