aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/quality-gates/components
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps/quality-gates/components')
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx (renamed from server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js)144
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx100
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Details.js11
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js9
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js5
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js23
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.tsx (renamed from server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js)33
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js)18
12 files changed, 247 insertions, 116 deletions
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx
index 5907e9d5770..7496c7cefe1 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx
@@ -36,8 +36,10 @@ export default function BuiltInQualityGateBadge({ className, tooltip = true }: P
const overlay = (
<div>
- <p>{translate('quality_gates.built_in.description.1')}</p>
- <p>{translate('quality_gates.built_in.description.2')}</p>
+ <span>{translate('quality_gates.built_in.description.1')}</span>
+ <span className="little-spacer-left">
+ {translate('quality_gates.built_in.description.2')}
+ </span>
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx
index c66890153f3..741a7b2efd0 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx
@@ -17,54 +17,71 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React, { Component } from 'react';
-import ThresholdInput from './ThresholdInput';
-import DeleteConditionView from '../views/gate-conditions-delete-view';
+import * as React from 'react';
import Checkbox from '../../../components/controls/Checkbox';
-import { createCondition, updateCondition } from '../../../api/quality-gates';
+import DeleteConditionForm from './DeleteConditionForm';
import Select from '../../../components/controls/Select';
+import ThresholdInput from './ThresholdInput';
+import {
+ Condition as ICondition,
+ ConditionBase,
+ createCondition,
+ QualityGate,
+ updateCondition
+} from '../../../api/quality-gates';
+import { Metric } from '../../../app/types';
import { translate, getLocalizedMetricName } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';
-export default class Condition extends Component {
- constructor(props) {
+interface Props {
+ condition: ICondition;
+ edit: boolean;
+ metric: Metric;
+ organization: string;
+ onDeleteCondition: (condition: ICondition) => void;
+ onError: (error: any) => void;
+ onResetError: () => void;
+ onSaveCondition: (condition: ICondition, newCondition: ICondition) => void;
+ qualityGate: QualityGate;
+}
+
+interface State {
+ changed: boolean;
+ period?: number;
+ op?: string;
+ openDeleteCondition: boolean;
+ warning: string;
+ error: string;
+}
+
+export default class Condition extends React.PureComponent<Props, State> {
+ constructor(props: Props) {
super(props);
this.state = {
changed: false,
period: props.condition.period,
op: props.condition.op,
+ openDeleteCondition: false,
warning: props.condition.warning || '',
error: props.condition.error || ''
};
}
- componentDidMount() {
- if (!this.props.condition.id && this.operator) {
- this.operator.focus();
- }
- }
+ handleOperatorChange = ({ value }: any) => this.setState({ changed: true, op: value });
- handleOperatorChange = ({ value }) => {
- this.setState({ changed: true, op: value });
- };
-
- handlePeriodChange = checked => {
- const period = checked ? '1' : undefined;
+ handlePeriodChange = (checked: boolean) => {
+ const period = checked ? 1 : undefined;
this.setState({ changed: true, period });
};
- handleWarningChange = value => {
- this.setState({ changed: true, warning: value });
- };
+ handleWarningChange = (warning: string) => this.setState({ changed: true, warning });
- handleErrorChange = value => {
- this.setState({ changed: true, error: value });
- };
+ handleErrorChange = (error: string) => this.setState({ changed: true, error });
- handleSaveClick = e => {
- const { qualityGate, condition, metric, onSaveCondition, onError, onResetError } = this.props;
+ handleSaveClick = () => {
+ const { qualityGate, condition, metric, organization } = this.props;
const { period } = this.state;
- const data = {
+ const data: ConditionBase = {
metric: condition.metric,
op: metric.type === 'RATING' ? 'GT' : this.state.op,
warning: this.state.warning,
@@ -76,23 +93,19 @@ export default class Condition extends Component {
}
if (metric.key.indexOf('new_') === 0) {
- data.period = '1';
+ data.period = 1;
}
- e.preventDefault();
- createCondition(qualityGate.id, data)
- .then(newCondition => {
- this.setState({ changed: false });
- onSaveCondition(condition, newCondition);
- onResetError();
- })
- .catch(onError);
+ createCondition({ gateId: qualityGate.id, organization, ...data }).then(
+ this.handleConditionResponse,
+ this.props.onError
+ );
};
- handleUpdateClick = e => {
- const { condition, onSaveCondition, metric, onError, onResetError } = this.props;
+ handleUpdateClick = () => {
+ const { condition, metric, organization } = this.props;
const { period } = this.state;
- const data = {
+ const data: ICondition = {
id: condition.id,
metric: condition.metric,
op: metric.type === 'RATING' ? 'GT' : this.state.op,
@@ -105,38 +118,30 @@ export default class Condition extends Component {
}
if (metric.key.indexOf('new_') === 0) {
- data.period = '1';
+ data.period = 1;
}
- e.preventDefault();
- updateCondition(data)
- .then(newCondition => {
- this.setState({ changed: false });
- onSaveCondition(condition, newCondition);
- onResetError();
- })
- .catch(onError);
+ updateCondition({ organization, ...data }).then(
+ this.handleConditionResponse,
+ this.props.onError
+ );
};
- handleDeleteClick = e => {
- const { qualityGate, condition, metric, onDeleteCondition } = this.props;
-
- e.preventDefault();
- new DeleteConditionView({
- qualityGate,
- condition,
- metric,
- onDelete: () => onDeleteCondition(condition)
- }).render();
+ handleConditionResponse = (newCondition: ICondition) => {
+ this.setState({ changed: false });
+ this.props.onSaveCondition(this.props.condition, newCondition);
+ this.props.onResetError();
};
- handleCancelClick = e => {
- const { condition, onDeleteCondition } = this.props;
-
+ handleCancelClick = (e: React.SyntheticEvent<HTMLAnchorElement>) => {
e.preventDefault();
- onDeleteCondition(condition);
+ e.stopPropagation();
+ this.props.onDeleteCondition(this.props.condition);
};
+ openDeleteConditionForm = () => this.setState({ openDeleteCondition: true });
+ closeDeleteConditionForm = () => this.setState({ openDeleteCondition: false });
+
renderPeriodValue() {
const { condition, metric } = this.props;
const isLeakSelected = !!this.state.period;
@@ -175,7 +180,7 @@ export default class Condition extends Component {
renderOperator() {
const { condition, edit, metric } = this.props;
- if (!edit) {
+ if (!edit && condition.op) {
return metric.type === 'RATING'
? translate('quality_gates.operator', condition.op, 'rating')
: translate('quality_gates.operator', condition.op);
@@ -193,9 +198,9 @@ export default class Condition extends Component {
return (
<Select
+ autofocus={true}
className="input-medium"
clearable={false}
- innerRef={node => (this.operator = node)}
name="operator"
onChange={this.handleOperatorChange}
options={operatorOptions}
@@ -206,7 +211,7 @@ export default class Condition extends Component {
}
render() {
- const { condition, edit, metric } = this.props;
+ const { condition, edit, metric, organization } = this.props;
return (
<tr>
<td className="text-middle">
@@ -258,9 +263,18 @@ export default class Condition extends Component {
</button>
<button
className="button-red delete-condition little-spacer-left"
- onClick={this.handleDeleteClick}>
+ onClick={this.openDeleteConditionForm}>
{translate('delete')}
</button>
+ {this.state.openDeleteCondition && (
+ <DeleteConditionForm
+ condition={condition}
+ metric={metric}
+ onClose={this.closeDeleteConditionForm}
+ onDelete={this.props.onDeleteCondition}
+ organization={organization}
+ />
+ )}
</div>
) : (
<div>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
index 7986f5a1816..547543cb215 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
@@ -62,7 +62,8 @@ export default class Conditions extends React.PureComponent {
edit,
onAddCondition,
onSaveCondition,
- onDeleteCondition
+ onDeleteCondition,
+ organization
} = this.props;
const existingConditions = conditions.filter(condition => metrics[condition.metric]);
@@ -130,6 +131,7 @@ export default class Conditions extends React.PureComponent {
onDeleteCondition={onDeleteCondition}
onError={this.handleError.bind(this)}
onResetError={this.handleResetError.bind(this)}
+ organization={organization}
/>
))}
</tbody>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx
new file mode 100644
index 00000000000..c4d1ea5fcfa
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx
@@ -0,0 +1,100 @@
+/*
+* SonarQube
+* Copyright (C) 2009-2017 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 Modal from '../../../components/controls/Modal';
+import { Metric } from '../../../app/types';
+import { Condition, deleteCondition } from '../../../api/quality-gates';
+import { getLocalizedMetricName, translate, translateWithParameters } from '../../../helpers/l10n';
+
+interface Props {
+ condition: Condition;
+ metric: Metric;
+ onClose: () => void;
+ onDelete: (condition: Condition) => void;
+ organization?: string;
+}
+
+interface State {
+ loading: boolean;
+}
+
+export default class DeleteConditionForm extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = { loading: false };
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
+ event.preventDefault();
+ this.props.onClose();
+ };
+
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
+ event.preventDefault();
+ const { organization, condition } = this.props;
+ this.setState({ loading: true });
+ deleteCondition({ id: condition.id, organization }).then(
+ () => this.props.onDelete(condition),
+ () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ }
+ );
+ };
+
+ render() {
+ const { metric } = this.props;
+ const header = translate('quality_gates.delete_condition');
+
+ return (
+ <Modal contentLabel={header} onRequestClose={this.props.onClose}>
+ <form id="delete-profile-form" onSubmit={this.handleFormSubmit}>
+ <div className="modal-head">
+ <h2>{header}</h2>
+ </div>
+ <div className="modal-body">
+ <p>
+ {translateWithParameters(
+ 'quality_gates.delete_condition.confirm.message',
+ getLocalizedMetricName(metric)
+ )}
+ </p>
+ </div>
+ <div className="modal-foot">
+ {this.state.loading && <i className="spinner spacer-right" />}
+ <button className="js-delete button-red" disabled={this.state.loading}>
+ {translate('delete')}
+ </button>
+ <a href="#" className="js-modal-close" onClick={this.handleCancelClick}>
+ {translate('cancel')}
+ </a>
+ </div>
+ </form>
+ </Modal>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx
index ab80d7e9df9..6bb533c415c 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx
@@ -62,7 +62,7 @@ export default class DeleteQualityGateForm extends React.PureComponent<Props, St
event.preventDefault();
const { organization, qualityGate } = this.props;
this.setState({ loading: true });
- deleteQualityGate(qualityGate.id).then(
+ deleteQualityGate({ id: qualityGate.id, organization }).then(
() => {
this.props.onDelete(qualityGate);
this.context.router.replace(getQualityGatesUrl(organization));
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js
index b6ff64b5c87..a231079b6a2 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js
@@ -20,7 +20,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import Helmet from 'react-helmet';
-import { fetchQualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
+import { fetchQualityGate } from '../../../api/quality-gates';
import DetailsHeader from './DetailsHeader';
import DetailsContent from './DetailsContent';
@@ -41,10 +41,10 @@ export default class Details extends React.PureComponent {
}
fetchDetails = () =>
- fetchQualityGate(this.props.params.id).then(
- qualityGate => this.props.onShow(qualityGate),
- () => {}
- );
+ fetchQualityGate({
+ id: this.props.params.id,
+ organization: this.props.organization && this.props.organization.key
+ }).then(qualityGate => this.props.onShow(qualityGate), () => {});
render() {
const { organization, metrics, qualityGate } = this.props;
@@ -72,6 +72,7 @@ export default class Details extends React.PureComponent {
onAddCondition={onAddCondition}
onSaveCondition={onSaveCondition}
onDeleteCondition={onDeleteCondition}
+ organization={organization && organization.key}
/>
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
index 0489459a58c..8a424be367e 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
@@ -24,7 +24,7 @@ import { translate } from '../../../helpers/l10n';
export default class DetailsContent extends React.PureComponent {
render() {
- const { gate, metrics } = this.props;
+ const { gate, metrics, organization } = this.props;
const { onAddCondition, onDeleteCondition, onSaveCondition } = this.props;
const conditions = gate.conditions || [];
const actions = gate.actions || {};
@@ -43,6 +43,7 @@ export default class DetailsContent extends React.PureComponent {
onAddCondition={onAddCondition}
onSaveCondition={onSaveCondition}
onDeleteCondition={onDeleteCondition}
+ organization={organization}
/>
<div id="quality-gate-projects" className="quality-gate-section">
@@ -50,7 +51,11 @@ export default class DetailsContent extends React.PureComponent {
{gate.isDefault ? (
defaultMessage
) : (
- <Projects qualityGate={gate} edit={actions.associateProjects} />
+ <Projects
+ qualityGate={gate}
+ edit={actions.associateProjects}
+ organization={organization}
+ />
)}
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
index aa3d836b237..f781cc253b8 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
@@ -22,7 +22,7 @@ import BuiltInQualityGateBadge from './BuiltInQualityGateBadge';
import RenameQualityGateForm from './RenameQualityGateForm';
import CopyQualityGateForm from './CopyQualityGateForm';
import DeleteQualityGateForm from './DeleteQualityGateForm';
-import { QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
+import { fetchQualityGate, QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
import { translate } from '../../../helpers/l10n';
interface Props {
@@ -53,9 +53,11 @@ export default class DetailsHeader extends React.PureComponent<Props, State> {
handleSetAsDefaultClick = (e: React.SyntheticEvent<HTMLButtonElement>) => {
e.preventDefault();
- const { qualityGate, onSetAsDefault } = this.props;
+ const { qualityGate, onSetAsDefault, organization } = this.props;
if (!qualityGate.isDefault) {
- setQualityGateAsDefault(qualityGate.id).then(() => onSetAsDefault(qualityGate), () => {});
+ setQualityGateAsDefault({ id: qualityGate.id, organization })
+ .then(() => fetchQualityGate({ id: qualityGate.id, organization }))
+ .then(qualityGate => onSetAsDefault(qualityGate), () => {});
}
};
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
index 33a9c447d13..344bf1e2881 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
@@ -44,12 +44,13 @@ export default class Projects extends React.PureComponent {
}
renderView() {
- const { qualityGate, edit } = this.props;
+ const { qualityGate, edit, organization } = this.props;
this.projectsView = new ProjectsView({
qualityGate,
edit,
- container: this.refs.container
+ container: this.refs.container,
+ organization
});
this.projectsView.render();
}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js
index 96c3ed76f9a..0ec8d28794d 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js
@@ -51,15 +51,20 @@ export default class QualityGatesApp extends Component {
}
fetchQualityGates = () =>
- fetchQualityGates().then(({ actions, qualitygates: qualityGates }) => {
- const { organization, updateStore } = this.props;
- updateStore({ actions, qualityGates });
- if (qualityGates && qualityGates.length === 1 && !actions.create) {
- this.context.router.replace(
- getQualityGateUrl(String(qualityGates[0].id), organization && organization.key)
- );
- }
- });
+ fetchQualityGates({
+ organization: this.props.organization && this.props.organization.key
+ }).then(
+ ({ actions, qualitygates: qualityGates }) => {
+ const { organization, updateStore } = this.props;
+ updateStore({ actions, qualityGates });
+ if (qualityGates && qualityGates.length === 1 && !actions.create) {
+ this.context.router.replace(
+ getQualityGateUrl(String(qualityGates[0].id), organization && organization.key)
+ );
+ }
+ },
+ () => {}
+ );
render() {
const { children, qualityGates, actions, organization } = this.props;
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js b/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.tsx
index b00a7e8419f..cf60765a6f3 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.tsx
@@ -17,23 +17,23 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React from 'react';
-import PropTypes from 'prop-types';
+import * as React from 'react';
import Select from '../../../components/controls/Select';
+import { Metric } from '../../../app/types';
-export default class ThresholdInput extends React.PureComponent {
- static propTypes = {
- name: PropTypes.string.isRequired,
- value: PropTypes.any,
- metric: PropTypes.object.isRequired,
- onChange: PropTypes.func.isRequired
- };
+interface Props {
+ name: string;
+ value: string;
+ metric: Metric;
+ onChange: (value: string) => void;
+}
- handleChange = e => {
- this.props.onChange(e.target.value);
+export default class ThresholdInput extends React.PureComponent<Props> {
+ handleChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
+ this.props.onChange(e.currentTarget.value);
};
- handleSelectChange = option => {
+ handleSelectChange = (option: any) => {
if (option) {
this.props.onChange(option.value);
} else {
@@ -51,17 +51,15 @@ export default class ThresholdInput extends React.PureComponent {
{ label: 'D', value: '4' }
];
- const realValue = value === '' ? null : value;
-
return (
<Select
className="input-tiny text-middle"
name={name}
- value={realValue}
+ onChange={this.handleSelectChange}
options={options}
- searchable={false}
placeholder=""
- onChange={this.handleSelectChange}
+ searchable={false}
+ value={value}
/>
);
}
@@ -80,7 +78,6 @@ export default class ThresholdInput extends React.PureComponent {
className="input-tiny text-middle"
value={value}
data-type={metric.type}
- placeholder={metric.placeholder}
onChange={this.handleChange}
/>
);
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx
index 32727393559..42f29a6a6a8 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx
@@ -17,15 +17,16 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React from 'react';
+import * as React from 'react';
import { shallow } from 'enzyme';
import ThresholdInput from '../ThresholdInput';
import { change } from '../../../../helpers/testUtils';
describe('on strings', () => {
+ const metric = { key: 'foo', name: 'Foo', type: 'INTEGER' };
it('should render text input', () => {
const input = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'INTEGER' }} onChange={jest.fn()} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={jest.fn()} />
).find('input');
expect(input.length).toEqual(1);
expect(input.prop('name')).toEqual('foo');
@@ -35,7 +36,7 @@ describe('on strings', () => {
it('should change', () => {
const onChange = jest.fn();
const input = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'INTEGER' }} onChange={onChange} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={onChange} />
).find('input');
change(input, 'bar');
expect(onChange).toBeCalledWith('bar');
@@ -43,9 +44,10 @@ describe('on strings', () => {
});
describe('on ratings', () => {
+ const metric = { key: 'foo', name: 'Foo', type: 'RATING' };
it('should render Select', () => {
const select = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={jest.fn()} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={jest.fn()} />
).find('Select');
expect(select.length).toEqual(1);
expect(select.prop('value')).toEqual('2');
@@ -54,18 +56,18 @@ describe('on ratings', () => {
it('should set', () => {
const onChange = jest.fn();
const select = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={onChange} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={onChange} />
).find('Select');
- select.prop('onChange')({ label: 'D', value: '4' });
+ (select.prop('onChange') as Function)({ label: 'D', value: '4' });
expect(onChange).toBeCalledWith('4');
});
it('should unset', () => {
const onChange = jest.fn();
const select = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={onChange} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={onChange} />
).find('Select');
- select.prop('onChange')(null);
+ (select.prop('onChange') as Function)(null);
expect(onChange).toBeCalledWith('');
});
});