@@ -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 | |||
); | |||
} |
@@ -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, |
@@ -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} |
@@ -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} |
@@ -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,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); |
@@ -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} |
@@ -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", |
@@ -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 [], |
@@ -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 [], |
@@ -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 [ |
@@ -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; | |||
} |
@@ -28,3 +28,8 @@ export enum ComponentQualifier { | |||
SubProject = 'BRC', | |||
TestFile = 'UTS' | |||
} | |||
export enum Visibility { | |||
Public = 'public', | |||
Private = 'private' | |||
} |
@@ -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 { |