aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/coding-rules
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps/coding-rules')
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/BulkChangeModal.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx303
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsCustomRules.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/ActivationFormModal-test.tsx38
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/BulkChangeModal-test.tsx41
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/CustomRuleFormModal-test.tsx39
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleListItem-test.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap101
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/BulkChangeModal-test.tsx.snap56
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap237
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleListItem-test.tsx.snap8
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/styles.css9
15 files changed, 673 insertions, 209 deletions
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
index e9ffd00fa0d..50b5cce4633 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import Modal from '../../../components/controls/Modal';
import Select from '../../../components/controls/Select';
import SeverityHelper from '../../../components/shared/SeverityHelper';
-import { activateRule, Profile as BaseProfile } from '../../../api/quality-profiles';
+import { activateRule, Profile } from '../../../api/quality-profiles';
import { SEVERITIES } from '../../../helpers/constants';
import { translate } from '../../../helpers/l10n';
import { sortProfiles } from '../../quality-profiles/utils';
@@ -34,7 +34,7 @@ interface Props {
onClose: () => void;
onDone: (severity: string) => Promise<void>;
organization: string | undefined;
- profiles: BaseProfile[];
+ profiles: Profile[];
rule: T.Rule | T.RuleDetails;
}
@@ -153,7 +153,7 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat
const isUpdateMode = !!activation;
return (
- <Modal contentLabel={this.props.modalHeader} onRequestClose={this.props.onClose}>
+ <Modal contentLabel={this.props.modalHeader} onRequestClose={this.props.onClose} size="small">
<form onSubmit={this.handleFormSubmit}>
<div className="modal-head">
<h2>{this.props.modalHeader}</h2>
@@ -206,7 +206,6 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat
<label title={param.key}>{param.key}</label>
{param.type === 'TEXT' ? (
<textarea
- className="width100"
disabled={submitting}
name={param.key}
onChange={this.handleParameterChange}
@@ -216,7 +215,6 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat
/>
) : (
<input
- className="input-super-large"
disabled={submitting}
name={param.key}
onChange={this.handleParameterChange}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/BulkChangeModal.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/BulkChangeModal.tsx
index 0a8158a153c..b6bf6c9d4ec 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/BulkChangeModal.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/BulkChangeModal.tsx
@@ -19,13 +19,13 @@
*/
import * as React from 'react';
import { Query, serializeQuery } from '../query';
-import { Profile, bulkActivateRules, bulkDeactivateRules } from '../../../api/quality-profiles';
import Modal from '../../../components/controls/Modal';
import Select from '../../../components/controls/Select';
+import { Alert } from '../../../components/ui/Alert';
+import { SubmitButton, ResetButtonLink } from '../../../components/ui/buttons';
+import { Profile, bulkActivateRules, bulkDeactivateRules } from '../../../api/quality-profiles';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';
-import { SubmitButton, ResetButtonLink } from '../../../components/ui/buttons';
-import { Alert } from '../../../components/ui/Alert';
interface Props {
action: string;
@@ -198,7 +198,7 @@ export default class BulkChangeModal extends React.PureComponent<Props, State> {
: `${translate('coding_rules.deactivate_in_quality_profile')} (${formatMeasure(total, 'INT')} ${translate('coding_rules._rules')})`;
return (
- <Modal contentLabel={header} onRequestClose={this.props.onClose}>
+ <Modal contentLabel={header} onRequestClose={this.props.onClose} size="small">
<form onSubmit={this.handleFormSubmit}>
<header className="modal-head">
<h2>{header}</h2>
@@ -218,11 +218,11 @@ export default class BulkChangeModal extends React.PureComponent<Props, State> {
</label>
</h3>
{profile ? (
- <h3 className="readonly-field">
+ <span>
{profile.name}
{' — '}
{translate('are_you_sure')}
- </h3>
+ </span>
) : (
this.renderProfileSelect()
)}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
index a0d0385a8ec..c97036fd75a 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
@@ -153,76 +153,60 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat
};
renderNameField = () => (
- <tr className="property">
- <th className="nowrap">
- <h3>
- {translate('name')} <em className="mandatory">*</em>
- </h3>
- </th>
- <td>
+ <div className="modal-field">
+ <label htmlFor="coding-rules-custom-rule-creation-name">
+ {translate('name')} <em className="mandatory">*</em>
+ </label>
+ <input
+ autoFocus={true}
+ disabled={this.state.submitting}
+ id="coding-rules-custom-rule-creation-name"
+ onChange={this.handleNameChange}
+ required={true}
+ type="text"
+ value={this.state.name}
+ />
+ </div>
+ );
+
+ renderKeyField = () => (
+ <div className="modal-field">
+ <label htmlFor="coding-rules-custom-rule-creation-key">
+ {translate('key')} {!this.props.customRule && <em className="mandatory">*</em>}
+ </label>
+
+ {this.props.customRule ? (
+ <span className="coding-rules-detail-custom-rule-key" title={this.props.customRule.key}>
+ {this.props.customRule.key}
+ </span>
+ ) : (
<input
- autoFocus={true}
- className="coding-rules-name-key"
disabled={this.state.submitting}
- id="coding-rules-custom-rule-creation-name"
- onChange={this.handleNameChange}
+ id="coding-rules-custom-rule-creation-key"
+ onChange={this.handleKeyChange}
required={true}
type="text"
- value={this.state.name}
+ value={this.state.key}
/>
- </td>
- </tr>
- );
-
- renderKeyField = () => (
- <tr className="property">
- <th className="nowrap">
- <h3>
- {translate('key')} {!this.props.customRule && <em className="mandatory">*</em>}
- </h3>
- </th>
- <td>
- {this.props.customRule ? (
- <span className="coding-rules-detail-custom-rule-key" title={this.props.customRule.key}>
- {this.props.customRule.key}
- </span>
- ) : (
- <input
- className="coding-rules-name-key"
- disabled={this.state.submitting}
- id="coding-rules-custom-rule-creation-key"
- onChange={this.handleKeyChange}
- required={true}
- type="text"
- value={this.state.key}
- />
- )}
- </td>
- </tr>
+ )}
+ </div>
);
renderDescriptionField = () => (
- <tr className="property">
- <th className="nowrap">
- <h3>
- {translate('description')} <em className="mandatory">*</em>
- </h3>
- </th>
- <td>
- <textarea
- className="coding-rules-markdown-description"
- disabled={this.state.submitting}
- id="coding-rules-custom-rule-creation-html-description"
- onChange={this.handleDescriptionChange}
- required={true}
- rows={5}
- value={this.state.description}
- />
- <span className="text-right">
- <MarkdownTips />
- </span>
- </td>
- </tr>
+ <div className="modal-field">
+ <label htmlFor="coding-rules-custom-rule-creation-html-description">
+ {translate('description')} <em className="mandatory">*</em>
+ </label>
+ <textarea
+ disabled={this.state.submitting}
+ id="coding-rules-custom-rule-creation-html-description"
+ onChange={this.handleDescriptionChange}
+ required={true}
+ rows={5}
+ value={this.state.description}
+ />
+ <MarkdownTips className="modal-field-descriptor text-right" />
+ </div>
);
renderTypeOption = ({ value }: { value: T.RuleType }) => {
@@ -230,107 +214,99 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat
};
renderTypeField = () => (
- <tr className="property">
- <th className="nowrap">
- <h3>{translate('type')}</h3>
- </th>
- <td>
- <Select
- className="input-medium"
- clearable={false}
- disabled={this.state.submitting}
- onChange={this.handleTypeChange}
- optionRenderer={this.renderTypeOption}
- options={RULE_TYPES.map(type => ({
- label: translate('issue.type', type),
- value: type
- }))}
- searchable={false}
- value={this.state.type}
- valueRenderer={this.renderTypeOption}
- />
- </td>
- </tr>
+ <div className="modal-field flex-1 spacer-right">
+ <label htmlFor="coding-rules-custom-rule-type">{translate('type')}</label>
+ <Select
+ clearable={false}
+ disabled={this.state.submitting}
+ id="coding-rules-custom-rule-type"
+ onChange={this.handleTypeChange}
+ optionRenderer={this.renderTypeOption}
+ options={RULE_TYPES.map(type => ({
+ label: translate('issue.type', type),
+ value: type
+ }))}
+ searchable={false}
+ value={this.state.type}
+ valueRenderer={this.renderTypeOption}
+ />
+ </div>
);
renderSeverityOption = ({ value }: { value: string }) => <SeverityHelper severity={value} />;
renderSeverityField = () => (
- <tr className="property">
- <th className="nowrap">
- <h3>{translate('severity')}</h3>
- </th>
- <td>
- <Select
- className="input-medium"
- clearable={false}
- disabled={this.state.submitting}
- onChange={this.handleSeverityChange}
- optionRenderer={this.renderSeverityOption}
- options={SEVERITIES.map(severity => ({
- label: translate('severity', severity),
- value: severity
- }))}
- searchable={false}
- value={this.state.severity}
- valueRenderer={this.renderSeverityOption}
- />
- </td>
- </tr>
+ <div className="modal-field flex-1 spacer-right">
+ <label htmlFor="coding-rules-custom-rule-severity">{translate('severity')}</label>
+ <Select
+ clearable={false}
+ disabled={this.state.submitting}
+ id="coding-rules-custom-rule-severity"
+ onChange={this.handleSeverityChange}
+ optionRenderer={this.renderSeverityOption}
+ options={SEVERITIES.map(severity => ({
+ label: translate('severity', severity),
+ value: severity
+ }))}
+ searchable={false}
+ value={this.state.severity}
+ valueRenderer={this.renderSeverityOption}
+ />
+ </div>
);
renderStatusField = () => (
- <tr className="property">
- <th className="nowrap">
- <h3>{translate('coding_rules.filters.status')}</h3>
- </th>
- <td>
- <Select
- className="input-medium"
- clearable={false}
- disabled={this.state.submitting}
- onChange={this.handleStatusChange}
- options={RULE_STATUSES.map(status => ({
- label: translate('rules.status', status),
- value: status
- }))}
- searchable={false}
- value={this.state.status}
- />
- </td>
- </tr>
+ <div className="modal-field flex-1">
+ <label htmlFor="coding-rules-custom-rule-status">
+ {translate('coding_rules.filters.status')}
+ </label>
+ <Select
+ clearable={false}
+ disabled={this.state.submitting}
+ id="coding-rules-custom-rule-status"
+ onChange={this.handleStatusChange}
+ options={RULE_STATUSES.map(status => ({
+ label: translate('rules.status', status),
+ value: status
+ }))}
+ searchable={false}
+ value={this.state.status}
+ />
+ </div>
);
renderParameterField = (param: T.RuleParameter) => (
- <tr className="property" key={param.key}>
- <th className="nowrap">
- <h3>{param.key}</h3>
- </th>
- <td>
- {param.type === 'TEXT' ? (
- <textarea
- className="width100"
- disabled={this.state.submitting}
- name={param.key}
- onChange={this.handleParameterChange}
- placeholder={param.defaultValue}
- rows={3}
- value={this.state.params[param.key] || ''}
- />
- ) : (
- <input
- className="input-super-large"
- disabled={this.state.submitting}
- name={param.key}
- onChange={this.handleParameterChange}
- placeholder={param.defaultValue}
- type="text"
- value={this.state.params[param.key] || ''}
- />
- )}
- <div className="note" dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }} />
- </td>
- </tr>
+ <div className="modal-field" key={param.key}>
+ <label className="capitalize" htmlFor={param.key}>
+ {param.key}
+ </label>
+
+ {param.type === 'TEXT' ? (
+ <textarea
+ disabled={this.state.submitting}
+ id={param.key}
+ name={param.key}
+ onChange={this.handleParameterChange}
+ placeholder={param.defaultValue}
+ rows={3}
+ value={this.state.params[param.key] || ''}
+ />
+ ) : (
+ <input
+ disabled={this.state.submitting}
+ id={param.key}
+ name={param.key}
+ onChange={this.handleParameterChange}
+ placeholder={param.defaultValue}
+ type="text"
+ value={this.state.params[param.key] || ''}
+ />
+ )}
+ <div
+ className="modal-field-description"
+ dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }}
+ />
+ </div>
);
renderSubmitButton = () => {
@@ -371,18 +347,17 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat
{reactivating && (
<Alert variant="warning">{translate('coding_rules.reactivate.help')}</Alert>
)}
- <table>
- <tbody>
- {this.renderNameField()}
- {this.renderKeyField()}
- {this.renderDescriptionField()}
- {/* do not allow to change the type of existing rule */}
- {!customRule && this.renderTypeField()}
- {this.renderSeverityField()}
- {this.renderStatusField()}
- {params.map(this.renderParameterField)}
- </tbody>
- </table>
+
+ {this.renderNameField()}
+ {this.renderKeyField()}
+ <div className="display-flex-space-between">
+ {/* do not allow to change the type of existing rule */}
+ {!customRule && this.renderTypeField()}
+ {this.renderSeverityField()}
+ {this.renderStatusField()}
+ </div>
+ {this.renderDescriptionField()}
+ {params.map(this.renderParameterField)}
</div>
<div className="modal-foot">
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsCustomRules.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsCustomRules.tsx
index 39c11d5468a..966a96ca51c 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsCustomRules.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsCustomRules.tsx
@@ -104,7 +104,7 @@ export default class RuleDetailsCustomRules extends React.PureComponent<Props, S
</td>
<td className="coding-rules-detail-list-severity">
- <SeverityHelper severity={rule.severity} />
+ <SeverityHelper className="display-flex-center" severity={rule.severity} />
</td>
<td className="coding-rules-detail-list-parameters">
@@ -163,7 +163,7 @@ export default class RuleDetailsCustomRules extends React.PureComponent<Props, S
</CustomRuleButton>
)}
- <DeferredSpinner loading={loading}>
+ <DeferredSpinner className="spacer-left" loading={loading}>
{rules.length > 0 && (
<table className="coding-rules-detail-list" id="coding-rules-detail-custom-rules">
<tbody>{sortBy(rules, rule => rule.name).map(this.renderRule)}</tbody>
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx
index c7bc85d7817..0f22be47412 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx
@@ -127,16 +127,16 @@ export default class RuleDetailsDescription extends React.PureComponent<Props, S
renderForm = () => (
<div className="coding-rules-detail-extend-description-form">
- <table className="width100">
+ <table className="width-100">
<tbody>
<tr>
- <td className="width100" colSpan={2}>
+ <td colSpan={2}>
<textarea
autoFocus={true}
+ className="width-100 little-spacer-bottom"
id="coding-rules-detail-extend-description-text"
onChange={this.handleDescriptionChange}
rows={4}
- style={{ width: '100%', marginBottom: 4 }}
value={this.state.description}
/>
</td>
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx
index 74cfa236e86..29f4de18cba 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx
@@ -280,7 +280,7 @@ export default class RuleDetailsProfiles extends React.PureComponent<Props, Stat
{activations.length > 0 && (
<table
- className="coding-rules-detail-quality-profiles width100"
+ className="coding-rules-detail-quality-profiles width-100"
id="coding-rules-detail-quality-profiles">
<tbody>{activations.map(this.renderActivation)}</tbody>
</table>
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/ActivationFormModal-test.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/ActivationFormModal-test.tsx
new file mode 100644
index 00000000000..5b9cd54183d
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/ActivationFormModal-test.tsx
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
+import ActivationFormModal from '../ActivationFormModal';
+import { mockQualityProfile, mockRule } from '../../../../helpers/testMocks';
+
+it('render correctly', () => {
+ expect(
+ shallow(
+ <ActivationFormModal
+ modalHeader="title"
+ onClose={jest.fn()}
+ onDone={jest.fn()}
+ organization="foo"
+ profiles={[mockQualityProfile()]}
+ rule={mockRule()}
+ />
+ )
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/BulkChangeModal-test.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/BulkChangeModal-test.tsx
new file mode 100644
index 00000000000..6174a899e02
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/BulkChangeModal-test.tsx
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
+import BulkChangeModal from '../BulkChangeModal';
+import { mockQualityProfile } from '../../../../helpers/testMocks';
+import { Query } from '../../query';
+
+it('render correctly', () => {
+ expect(
+ shallow(
+ <BulkChangeModal
+ action="activate"
+ languages={{ js: { key: 'js', name: 'JavaScript' } }}
+ onClose={jest.fn()}
+ organization="foo"
+ profile={mockQualityProfile()}
+ query={{ languages: ['js'] } as Query}
+ referencedProfiles={{ foo: mockQualityProfile() }}
+ total={42}
+ />
+ )
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/CustomRuleFormModal-test.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/CustomRuleFormModal-test.tsx
new file mode 100644
index 00000000000..8677a879507
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/CustomRuleFormModal-test.tsx
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
+import CustomRuleFormModal from '../CustomRuleFormModal';
+import { mockRule } from '../../../../helpers/testMocks';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<CustomRuleFormModal['props']> = {}) {
+ return shallow(
+ <CustomRuleFormModal
+ onClose={jest.fn()}
+ onDone={jest.fn()}
+ organization={undefined}
+ templateRule={{ ...mockRule(), createdAt: 'date', repo: 'squid' }}
+ {...props}
+ />
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleListItem-test.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleListItem-test.tsx
index 2b220a43753..3d7b44dcb09 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleListItem-test.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/RuleListItem-test.tsx
@@ -20,19 +20,7 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import RuleListItem from '../RuleListItem';
-import { mockEvent } from '../../../../helpers/testMocks';
-
-const rule: T.Rule = {
- key: 'foo',
- lang: 'js',
- langName: 'JavaScript',
- name: 'Use foo',
- severity: 'MAJOR',
- status: 'READY',
- sysTags: ['a', 'b'],
- tags: ['x'],
- type: 'CODE_SMELL'
-};
+import { mockEvent, mockRule } from '../../../../helpers/testMocks';
it('should render', () => {
expect(shallowRender()).toMatchSnapshot();
@@ -42,7 +30,7 @@ it('should open rule', () => {
const onOpen = jest.fn();
const wrapper = shallowRender({ onOpen });
wrapper.find('Link').prop<Function>('onClick')(mockEvent({ button: 0 }));
- expect(onOpen).toBeCalledWith('foo');
+ expect(onOpen).toBeCalledWith('javascript:S1067');
});
function shallowRender(props?: Partial<RuleListItem['props']>) {
@@ -53,7 +41,7 @@ function shallowRender(props?: Partial<RuleListItem['props']>) {
onFilterChange={jest.fn()}
onOpen={jest.fn()}
organization="org"
- rule={rule}
+ rule={mockRule()}
selected={false}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap
new file mode 100644
index 00000000000..2225b883507
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap
@@ -0,0 +1,101 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`render correctly 1`] = `
+<Modal
+ contentLabel="title"
+ onRequestClose={[MockFunction]}
+ size="small"
+>
+ <form
+ onSubmit={[Function]}
+ >
+ <div
+ className="modal-head"
+ >
+ <h2>
+ title
+ </h2>
+ </div>
+ <div
+ className="modal-body"
+ >
+ <Alert
+ variant="info"
+ >
+ coding_rules.active_in_all_profiles
+ </Alert>
+ <div
+ className="modal-field"
+ >
+ <label>
+ coding_rules.quality_profile
+ </label>
+ <Select
+ className="js-profile"
+ clearable={false}
+ disabled={false}
+ onChange={[Function]}
+ options={Array []}
+ value=""
+ />
+ </div>
+ <div
+ className="modal-field"
+ >
+ <label>
+ severity
+ </label>
+ <Select
+ className="js-severity"
+ clearable={false}
+ disabled={false}
+ onChange={[Function]}
+ optionRenderer={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "severity.BLOCKER",
+ "value": "BLOCKER",
+ },
+ Object {
+ "label": "severity.CRITICAL",
+ "value": "CRITICAL",
+ },
+ Object {
+ "label": "severity.MAJOR",
+ "value": "MAJOR",
+ },
+ Object {
+ "label": "severity.MINOR",
+ "value": "MINOR",
+ },
+ Object {
+ "label": "severity.INFO",
+ "value": "INFO",
+ },
+ ]
+ }
+ searchable={false}
+ value="MAJOR"
+ valueRenderer={[Function]}
+ />
+ </div>
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <SubmitButton
+ disabled={true}
+ >
+ coding_rules.activate
+ </SubmitButton>
+ <ResetButtonLink
+ disabled={false}
+ onClick={[MockFunction]}
+ >
+ cancel
+ </ResetButtonLink>
+ </footer>
+ </form>
+</Modal>
+`;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/BulkChangeModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/BulkChangeModal-test.tsx.snap
new file mode 100644
index 00000000000..fed86bf741a
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/BulkChangeModal-test.tsx.snap
@@ -0,0 +1,56 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`render correctly 1`] = `
+<Modal
+ contentLabel="coding_rules.activate_in_quality_profile (42 coding_rules._rules)"
+ onRequestClose={[MockFunction]}
+ size="small"
+>
+ <form
+ onSubmit={[Function]}
+ >
+ <header
+ className="modal-head"
+ >
+ <h2>
+ coding_rules.activate_in_quality_profile (42 coding_rules._rules)
+ </h2>
+ </header>
+ <div
+ className="modal-body"
+ >
+ <div
+ className="modal-field"
+ >
+ <h3>
+ <label
+ htmlFor="coding-rules-bulk-change-profile"
+ >
+ coding_rules.activate_in
+ </label>
+ </h3>
+ <span>
+ name
+ —
+ are_you_sure
+ </span>
+ </div>
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <SubmitButton
+ disabled={false}
+ id="coding-rules-submit-bulk-change"
+ >
+ apply
+ </SubmitButton>
+ <ResetButtonLink
+ onClick={[MockFunction]}
+ >
+ cancel
+ </ResetButtonLink>
+ </footer>
+ </form>
+</Modal>
+`;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap
new file mode 100644
index 00000000000..71f42992ddd
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap
@@ -0,0 +1,237 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Modal
+ contentLabel="coding_rules.create_custom_rule"
+ onRequestClose={[MockFunction]}
+>
+ <form
+ onSubmit={[Function]}
+ >
+ <div
+ className="modal-head"
+ >
+ <h2>
+ coding_rules.create_custom_rule
+ </h2>
+ </div>
+ <div
+ className="modal-body modal-container"
+ >
+ <div
+ className="modal-field"
+ >
+ <label
+ htmlFor="coding-rules-custom-rule-creation-name"
+ >
+ name
+
+ <em
+ className="mandatory"
+ >
+ *
+ </em>
+ </label>
+ <input
+ autoFocus={true}
+ disabled={false}
+ id="coding-rules-custom-rule-creation-name"
+ onChange={[Function]}
+ required={true}
+ type="text"
+ value=""
+ />
+ </div>
+ <div
+ className="modal-field"
+ >
+ <label
+ htmlFor="coding-rules-custom-rule-creation-key"
+ >
+ key
+
+ <em
+ className="mandatory"
+ >
+ *
+ </em>
+ </label>
+ <input
+ disabled={false}
+ id="coding-rules-custom-rule-creation-key"
+ onChange={[Function]}
+ required={true}
+ type="text"
+ value=""
+ />
+ </div>
+ <div
+ className="display-flex-space-between"
+ >
+ <div
+ className="modal-field flex-1 spacer-right"
+ >
+ <label
+ htmlFor="coding-rules-custom-rule-type"
+ >
+ type
+ </label>
+ <Select
+ clearable={false}
+ disabled={false}
+ id="coding-rules-custom-rule-type"
+ onChange={[Function]}
+ optionRenderer={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "issue.type.BUG",
+ "value": "BUG",
+ },
+ Object {
+ "label": "issue.type.VULNERABILITY",
+ "value": "VULNERABILITY",
+ },
+ Object {
+ "label": "issue.type.CODE_SMELL",
+ "value": "CODE_SMELL",
+ },
+ Object {
+ "label": "issue.type.SECURITY_HOTSPOT",
+ "value": "SECURITY_HOTSPOT",
+ },
+ Object {
+ "label": "issue.type.UNKNOWN",
+ "value": "UNKNOWN",
+ },
+ ]
+ }
+ searchable={false}
+ value="CODE_SMELL"
+ valueRenderer={[Function]}
+ />
+ </div>
+ <div
+ className="modal-field flex-1 spacer-right"
+ >
+ <label
+ htmlFor="coding-rules-custom-rule-severity"
+ >
+ severity
+ </label>
+ <Select
+ clearable={false}
+ disabled={false}
+ id="coding-rules-custom-rule-severity"
+ onChange={[Function]}
+ optionRenderer={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "severity.BLOCKER",
+ "value": "BLOCKER",
+ },
+ Object {
+ "label": "severity.CRITICAL",
+ "value": "CRITICAL",
+ },
+ Object {
+ "label": "severity.MAJOR",
+ "value": "MAJOR",
+ },
+ Object {
+ "label": "severity.MINOR",
+ "value": "MINOR",
+ },
+ Object {
+ "label": "severity.INFO",
+ "value": "INFO",
+ },
+ ]
+ }
+ searchable={false}
+ value="MAJOR"
+ valueRenderer={[Function]}
+ />
+ </div>
+ <div
+ className="modal-field flex-1"
+ >
+ <label
+ htmlFor="coding-rules-custom-rule-status"
+ >
+ coding_rules.filters.status
+ </label>
+ <Select
+ clearable={false}
+ disabled={false}
+ id="coding-rules-custom-rule-status"
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "rules.status.READY",
+ "value": "READY",
+ },
+ Object {
+ "label": "rules.status.BETA",
+ "value": "BETA",
+ },
+ Object {
+ "label": "rules.status.DEPRECATED",
+ "value": "DEPRECATED",
+ },
+ ]
+ }
+ searchable={false}
+ value="READY"
+ />
+ </div>
+ </div>
+ <div
+ className="modal-field"
+ >
+ <label
+ htmlFor="coding-rules-custom-rule-creation-html-description"
+ >
+ description
+
+ <em
+ className="mandatory"
+ >
+ *
+ </em>
+ </label>
+ <textarea
+ disabled={false}
+ id="coding-rules-custom-rule-creation-html-description"
+ onChange={[Function]}
+ required={true}
+ rows={5}
+ value=""
+ />
+ <MarkdownTips
+ className="modal-field-descriptor text-right"
+ />
+ </div>
+ </div>
+ <div
+ className="modal-foot"
+ >
+ <SubmitButton
+ disabled={false}
+ id="coding-rules-custom-rule-creation-create"
+ >
+ create
+ </SubmitButton>
+ <ResetButtonLink
+ disabled={false}
+ id="coding-rules-custom-rule-creation-cancel"
+ onClick={[MockFunction]}
+ >
+ cancel
+ </ResetButtonLink>
+ </div>
+ </form>
+</Modal>
+`;
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleListItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleListItem-test.tsx.snap
index 459a8165037..e1b94a8164a 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleListItem-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleListItem-test.tsx.snap
@@ -3,7 +3,7 @@
exports[`should render 1`] = `
<div
className="coding-rule"
- data-rule="foo"
+ data-rule="javascript:S1067"
>
<table
className="coding-rule-table"
@@ -23,8 +23,8 @@ exports[`should render 1`] = `
Object {
"pathname": "/organizations/org/rules",
"query": Object {
- "open": "foo",
- "rule_key": "foo",
+ "open": "javascript:S1067",
+ "rule_key": "javascript:S1067",
},
}
}
@@ -72,7 +72,7 @@ exports[`should render 1`] = `
onFilterChange={[MockFunction]}
rule={
Object {
- "key": "foo",
+ "key": "javascript:S1067",
"lang": "js",
"langName": "JavaScript",
"name": "Use foo",
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/styles.css b/server/sonar-web/src/main/js/apps/coding-rules/styles.css
index ca7a4fdde40..8450e0dab94 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/styles.css
+++ b/server/sonar-web/src/main/js/apps/coding-rules/styles.css
@@ -201,15 +201,6 @@
margin-left: 10px;
}
-input.coding-rules-name-key {
- width: 100%;
-}
-
-textarea.coding-rules-markdown-description {
- width: 100%;
- margin-bottom: 4px;
-}
-
.coding-rules-most-violated-projects td {
border-top-color: transparent;
}