* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as classNames from 'classnames';
+import { differenceBy, uniq } from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
}
interface DispatchProps {
- fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => Promise<void>;
+ fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => void;
}
interface OwnProps {
componentDidMount() {
this.mounted = true;
- this.fetchBranchData();
+ if (this.props.conditions === undefined) {
+ this.fetchBranchStatusData();
+ } else {
+ this.fetchBranchData();
+ }
+ }
+
+ componentDidUpdate(prevProps: Props) {
+ if (this.conditionsHaveChanged(prevProps)) {
+ this.fetchBranchData();
+ }
}
componentWillUnmount() {
this.mounted = false;
}
- fetchBranchData = () => {
+ conditionsHaveChanged = (prevProps: Props) => {
+ const prevConditions = prevProps.conditions ?? [];
+ const newConditions = this.props.conditions ?? [];
+ const diff = differenceBy(
+ prevConditions.filter(c => c.level === 'ERROR'),
+ newConditions.filter(c => c.level === 'ERROR'),
+ c => c.metric
+ );
+
+ return (
+ (prevProps.conditions === undefined && this.props.conditions !== undefined) || diff.length > 0
+ );
+ };
+
+ fetchBranchStatusData = () => {
const {
branchLike,
component: { key }
} = this.props;
+ this.props.fetchBranchStatus(branchLike, key);
+ };
+
+ fetchBranchData = () => {
+ const {
+ branchLike,
+ component: { key },
+ conditions
+ } = this.props;
this.setState({ loading: true });
- Promise.all([
- getMeasuresAndMeta(key, PR_METRICS, {
- additionalFields: 'metrics',
- ...getBranchLikeQuery(branchLike)
- }),
- this.props.fetchBranchStatus(branchLike, key)
- ]).then(
- ([{ component, metrics }]) => {
+ const metricKeys =
+ conditions !== undefined
+ ? // Also load metrics that apply to failing QG conditions.
+ uniq([...PR_METRICS, ...conditions.filter(c => c.level !== 'OK').map(c => c.metric)])
+ : PR_METRICS;
+
+ getMeasuresAndMeta(key, metricKeys, {
+ additionalFields: 'metrics',
+ ...getBranchLikeQuery(branchLike)
+ }).then(
+ ({ component, metrics }) => {
if (this.mounted && component.measures) {
this.setState({
loading: false,
import { mockPullRequest } from '../../../../helpers/mocks/branch-like';
import { mockQualityGateStatusCondition } from '../../../../helpers/mocks/quality-gates';
import { mockComponent } from '../../../../helpers/testMocks';
+import { PR_METRICS } from '../../utils';
import { PullRequestOverview } from '../PullRequestOverview';
jest.mock('../../../../api/measures', () => {
expect(wrapper).toMatchSnapshot();
});
-it('should correctly handle a WS failure', async () => {
- (getMeasuresAndMeta as jest.Mock).mockRejectedValueOnce({});
- const fetchBranchStatus = jest.fn().mockRejectedValue({});
- const wrapper = shallowRender({ fetchBranchStatus });
+it('should correctly fetch all required metrics for a passing QG', async () => {
+ const wrapper = shallowRender({ conditions: [] });
+ await waitAndUpdate(wrapper);
+ expect(getMeasuresAndMeta).toBeCalledWith('my-project', PR_METRICS, expect.any(Object));
+});
+it('should correctly fetch all required metrics for a failing QG', async () => {
+ const wrapper = shallowRender({
+ conditions: [mockQualityGateStatusCondition({ level: 'ERROR', metric: 'foo' })]
+ });
await waitAndUpdate(wrapper);
- expect(wrapper.type()).toBeNull();
+ expect(getMeasuresAndMeta).toBeCalledWith(
+ 'my-project',
+ [...PR_METRICS, 'foo'],
+ expect.any(Object)
+ );
});
function shallowRender(props: Partial<PullRequestOverview['props']> = {}) {