]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14133 Add identifying fields to azure project binding
authorJeremy Davis <jeremy.davis@sonarsource.com>
Wed, 18 Nov 2020 08:29:46 +0000 (09:29 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 25 Nov 2020 20:06:26 +0000 (20:06 +0000)
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBindingRenderer.tsx
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/AlmSpecificForm-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap
server/sonar-web/src/main/js/types/alm-settings.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx
new file mode 100644 (file)
index 0000000..6483db5
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { FormattedMessage } from 'react-intl';
+import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { AlmKeys, ProjectAlmBindingResponse } from '../../../../types/alm-settings';
+import InputForBoolean from '../inputs/InputForBoolean';
+
+export interface AlmSpecificFormProps {
+  alm: AlmKeys;
+  formData: T.Omit<ProjectAlmBindingResponse, 'alm'>;
+  onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
+}
+
+interface LabelProps {
+  help?: boolean;
+  helpParams?: T.Dict<string | JSX.Element>;
+  id: string;
+  optional?: boolean;
+}
+
+interface CommonFieldProps extends LabelProps {
+  onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
+  propKey: keyof ProjectAlmBindingResponse;
+}
+
+function renderLabel(props: LabelProps) {
+  const { help, helpParams, optional, id } = props;
+  return (
+    <label className="display-flex-center" htmlFor={id}>
+      {translate('settings.pr_decoration.binding.form', id)}
+      {!optional && <em className="mandatory">*</em>}
+      {help && (
+        <HelpTooltip
+          className="spacer-left"
+          overlay={
+            <FormattedMessage
+              defaultMessage={translate('settings.pr_decoration.binding.form', id, 'help')}
+              id={`settings.pr_decoration.binding.form.${id}.help`}
+              values={helpParams}
+            />
+          }
+          placement="right"
+        />
+      )}
+    </label>
+  );
+}
+
+function renderBooleanField(
+  props: Omit<CommonFieldProps, 'optional'> & {
+    value: boolean;
+  }
+) {
+  const { id, value, onFieldChange, propKey } = props;
+  return (
+    <div className="form-field">
+      {renderLabel({ ...props, optional: true })}
+      <InputForBoolean
+        isDefault={true}
+        name={id}
+        onChange={v => onFieldChange(propKey, v)}
+        value={value}
+      />
+    </div>
+  );
+}
+
+function renderField(
+  props: CommonFieldProps & {
+    value: string;
+  }
+) {
+  const { id, propKey, value, onFieldChange } = props;
+  return (
+    <div className="form-field">
+      {renderLabel(props)}
+      <input
+        className="input-super-large"
+        id={id}
+        maxLength={256}
+        name={id}
+        onChange={e => onFieldChange(propKey, e.currentTarget.value)}
+        type="text"
+        value={value}
+      />
+    </div>
+  );
+}
+
+export default function AlmSpecificForm(props: AlmSpecificFormProps) {
+  const {
+    alm,
+    formData: { repository, slug, summaryCommentEnabled }
+  } = props;
+
+  switch (alm) {
+    case AlmKeys.Azure:
+      return (
+        <>
+          {renderField({
+            help: true,
+            id: 'azure.project',
+            onFieldChange: props.onFieldChange,
+            propKey: 'slug',
+            value: slug || ''
+          })}
+          {renderField({
+            help: true,
+            id: 'azure.repository',
+            onFieldChange: props.onFieldChange,
+            propKey: 'repository',
+            value: repository || ''
+          })}
+        </>
+      );
+    case AlmKeys.Bitbucket:
+      return (
+        <>
+          {renderField({
+            help: true,
+            helpParams: {
+              example: (
+                <>
+                  {'.../projects/'}
+                  <strong>{'{KEY}'}</strong>
+                  {'/repos/{SLUG}/browse'}
+                </>
+              )
+            },
+            id: 'bitbucket.repository',
+            onFieldChange: props.onFieldChange,
+            propKey: 'repository',
+            value: repository || ''
+          })}
+          {renderField({
+            help: true,
+            helpParams: {
+              example: (
+                <>
+                  {'.../projects/{KEY}/repos/'}
+                  <strong>{'{SLUG}'}</strong>
+                  {'/browse'}
+                </>
+              )
+            },
+            id: 'bitbucket.slug',
+            onFieldChange: props.onFieldChange,
+            propKey: 'slug',
+            value: slug || ''
+          })}
+        </>
+      );
+    case AlmKeys.GitHub:
+      return (
+        <>
+          {renderField({
+            help: true,
+            helpParams: { example: 'SonarSource/sonarqube' },
+            id: 'github.repository',
+            onFieldChange: props.onFieldChange,
+            propKey: 'repository',
+            value: repository || ''
+          })}
+          {renderBooleanField({
+            help: true,
+            id: 'github.summary_comment_setting',
+            onFieldChange: props.onFieldChange,
+            propKey: 'summaryCommentEnabled',
+            value: summaryCommentEnabled === undefined ? true : summaryCommentEnabled
+          })}
+        </>
+      );
+    case AlmKeys.GitLab:
+      return renderField({
+        id: 'gitlab.repository',
+        onFieldChange: props.onFieldChange,
+        propKey: 'repository',
+        value: repository || ''
+      });
+    default:
+      return null;
+  }
+}
index 0b4dc3e2a06af50becda02a863bf88800b1fbda1..18336d366dead4fb179d7e337e52df367c124067 100644 (file)
@@ -18,6 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
+import { HttpStatus } from 'sonar-ui-common/helpers/request';
 import {
   deleteProjectAlmBinding,
   getAlmSettings,
@@ -56,7 +57,7 @@ interface State {
 const REQUIRED_FIELDS_BY_ALM: {
   [almKey in AlmKeys]: Array<keyof T.Omit<FormData, 'key'>>;
 } = {
-  [AlmKeys.Azure]: [],
+  [AlmKeys.Azure]: ['repository', 'slug'],
   [AlmKeys.Bitbucket]: ['repository', 'slug'],
   [AlmKeys.GitHub]: ['repository'],
   [AlmKeys.GitLab]: ['repository']
@@ -112,7 +113,7 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat
 
   getProjectBinding(project: string): Promise<ProjectAlmBindingResponse | undefined> {
     return getProjectAlmBinding(project).catch((response: Response) => {
-      if (response && response.status === 404) {
+      if (response && response.status === HttpStatus.NotFound) {
         return undefined;
       }
       return throwGlobalError(response);
@@ -156,11 +157,19 @@ export default class PRDecorationBinding extends React.PureComponent<Props, Stat
     const project = this.props.component.key;
 
     switch (alm) {
-      case AlmKeys.Azure:
+      case AlmKeys.Azure: {
+        const projectName = almSpecificFields?.slug;
+        const repositoryName = almSpecificFields?.repository;
+        if (!projectName || !repositoryName) {
+          return Promise.reject();
+        }
         return setProjectAzureBinding({
           almSetting,
-          project
+          project,
+          projectName,
+          repositoryName
         });
+      }
       case AlmKeys.Bitbucket: {
         if (!almSpecificFields) {
           return Promise.reject();
index efebc487226b0afcd23ce550c7b37f210a2e6197..59357f92a675b9b2d0a806f2090acc02120d4831 100644 (file)
@@ -21,18 +21,13 @@ import * as React from 'react';
 import { FormattedMessage } from 'react-intl';
 import { Link } from 'react-router';
 import { Button, SubmitButton } from 'sonar-ui-common/components/controls/buttons';
-import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
 import Select from 'sonar-ui-common/components/controls/Select';
 import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon';
 import { Alert } from 'sonar-ui-common/components/ui/Alert';
 import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
 import { translate } from 'sonar-ui-common/helpers/l10n';
-import {
-  AlmKeys,
-  AlmSettingsInstance,
-  ProjectAlmBindingResponse
-} from '../../../../types/alm-settings';
-import InputForBoolean from '../inputs/InputForBoolean';
+import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../../../types/alm-settings';
+import AlmSpecificForm from './AlmSpecificForm';
 
 export interface PRDecorationBindingRendererProps {
   formData: T.Omit<ProjectAlmBindingResponse, 'alm'>;
@@ -48,18 +43,6 @@ export interface PRDecorationBindingRendererProps {
   success: boolean;
 }
 
-interface LabelProps {
-  help?: boolean;
-  helpParams?: T.Dict<string | JSX.Element>;
-  id: string;
-  optional?: boolean;
-}
-
-interface CommonFieldProps extends LabelProps {
-  onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
-  propKey: keyof ProjectAlmBindingResponse;
-}
-
 function optionRenderer(instance: AlmSettingsInstance) {
   return instance.url ? (
     <>
@@ -71,81 +54,8 @@ function optionRenderer(instance: AlmSettingsInstance) {
   );
 }
 
-function renderLabel(props: LabelProps) {
-  const { help, helpParams, optional, id } = props;
-  return (
-    <label className="display-flex-center" htmlFor={id}>
-      {translate('settings.pr_decoration.binding.form', id)}
-      {!optional && <em className="mandatory">*</em>}
-      {help && (
-        <HelpTooltip
-          className="spacer-left"
-          overlay={
-            <FormattedMessage
-              defaultMessage={translate('settings.pr_decoration.binding.form', id, 'help')}
-              id={`settings.pr_decoration.binding.form.${id}.help`}
-              values={helpParams}
-            />
-          }
-          placement="right"
-        />
-      )}
-    </label>
-  );
-}
-
-function renderBooleanField(
-  props: Omit<CommonFieldProps, 'optional'> & {
-    value: boolean;
-  }
-) {
-  const { id, value, onFieldChange, propKey } = props;
-  return (
-    <div className="form-field">
-      {renderLabel({ ...props, optional: true })}
-      <InputForBoolean
-        isDefault={true}
-        name={id}
-        onChange={v => onFieldChange(propKey, v)}
-        value={value}
-      />
-    </div>
-  );
-}
-
-function renderField(
-  props: CommonFieldProps & {
-    value: string;
-  }
-) {
-  const { id, propKey, value, onFieldChange } = props;
-  return (
-    <div className="form-field">
-      {renderLabel(props)}
-      <input
-        className="input-super-large"
-        id={id}
-        maxLength={256}
-        name={id}
-        onChange={e => onFieldChange(propKey, e.currentTarget.value)}
-        type="text"
-        value={value}
-      />
-    </div>
-  );
-}
-
 export default function PRDecorationBindingRenderer(props: PRDecorationBindingRendererProps) {
-  const {
-    formData: { key, repository, slug, summaryCommentEnabled },
-    instances,
-    isChanged,
-    isConfigured,
-    isValid,
-    loading,
-    saving,
-    success
-  } = props;
+  const { formData, instances, isChanged, isConfigured, isValid, loading, saving, success } = props;
 
   if (loading) {
     return <DeferredSpinner />;
@@ -171,7 +81,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe
     );
   }
 
-  const selected = key && instances.find(i => i.key === key);
+  const selected = formData.key && instances.find(i => i.key === formData.key);
   const alm = selected && selected.alm;
 
   return (
@@ -207,77 +117,16 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe
             optionRenderer={optionRenderer}
             options={instances}
             searchable={false}
-            value={key}
+            value={formData.key}
             valueKey="key"
             valueRenderer={optionRenderer}
           />
         </div>
 
-        {alm === AlmKeys.Bitbucket && (
-          <>
-            {renderField({
-              help: true,
-              helpParams: {
-                example: (
-                  <>
-                    {'.../projects/'}
-                    <strong>{'{KEY}'}</strong>
-                    {'/repos/{SLUG}/browse'}
-                  </>
-                )
-              },
-              id: 'bitbucket.repository',
-              onFieldChange: props.onFieldChange,
-              propKey: 'repository',
-              value: repository || ''
-            })}
-            {renderField({
-              help: true,
-              helpParams: {
-                example: (
-                  <>
-                    {'.../projects/{KEY}/repos/'}
-                    <strong>{'{SLUG}'}</strong>
-                    {'/browse'}
-                  </>
-                )
-              },
-              id: 'bitbucket.slug',
-              onFieldChange: props.onFieldChange,
-              propKey: 'slug',
-              value: slug || ''
-            })}
-          </>
+        {alm && (
+          <AlmSpecificForm alm={alm} formData={formData} onFieldChange={props.onFieldChange} />
         )}
 
-        {alm === AlmKeys.GitHub && (
-          <>
-            {renderField({
-              help: true,
-              helpParams: { example: 'SonarSource/sonarqube' },
-              id: 'github.repository',
-              onFieldChange: props.onFieldChange,
-              propKey: 'repository',
-              value: repository || ''
-            })}
-            {renderBooleanField({
-              help: true,
-              id: 'github.summary_comment_setting',
-              onFieldChange: props.onFieldChange,
-              propKey: 'summaryCommentEnabled',
-              value: summaryCommentEnabled === undefined ? true : summaryCommentEnabled
-            })}
-          </>
-        )}
-
-        {alm === AlmKeys.GitLab &&
-          renderField({
-            id: 'gitlab.repository',
-            onFieldChange: props.onFieldChange,
-            propKey: 'repository',
-            value: repository || ''
-          })}
-
         <div className="display-flex-center">
           <DeferredSpinner className="spacer-right" loading={saving} />
           {isChanged && (
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/AlmSpecificForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/AlmSpecificForm-test.tsx
new file mode 100644 (file)
index 0000000..57a2416
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { shallow } from 'enzyme';
+import * as React from 'react';
+import { AlmKeys } from '../../../../../types/alm-settings';
+import AlmSpecificForm, { AlmSpecificFormProps } from '../AlmSpecificForm';
+
+it.each([[AlmKeys.Azure], [AlmKeys.Bitbucket], [AlmKeys.GitHub], [AlmKeys.GitLab]])(
+  'it should render correctly for %s',
+  alm => {
+    expect(shallowRender(alm)).toMatchSnapshot();
+  }
+);
+
+function shallowRender(alm: AlmKeys, props: Partial<AlmSpecificFormProps> = {}) {
+  return shallow(
+    <AlmSpecificForm
+      alm={alm}
+      formData={{
+        key: '',
+        repository: ''
+      }}
+      onFieldChange={jest.fn()}
+      {...props}
+    />
+  );
+}
index bbdbf6f7da061844158bfc38df0bd92d7d73e661..2599949af78d8fff580b14569a502151db2633a9 100644 (file)
@@ -120,13 +120,20 @@ describe('handleSubmit', () => {
     const wrapper = shallowRender();
     await waitAndUpdate(wrapper);
     const azureKey = 'azure';
-    wrapper.setState({ formData: { key: azureKey }, instances });
+    const repository = 'az-rep';
+    const slug = 'az-project';
+    wrapper.setState({
+      formData: { key: azureKey, repository, slug },
+      instances
+    });
     wrapper.instance().handleSubmit();
     await waitAndUpdate(wrapper);
 
     expect(setProjectAzureBinding).toBeCalledWith({
       almSetting: azureKey,
-      project: PROJECT_KEY
+      project: PROJECT_KEY,
+      projectName: slug,
+      repositoryName: repository
     });
     expect(wrapper.state().success).toBe(true);
   });
@@ -212,6 +219,33 @@ it('should handle field changes', async () => {
   });
 });
 
+it('should reject submitted azure settings', async () => {
+  const wrapper = shallowRender();
+
+  expect.assertions(2);
+  await expect(
+    wrapper.instance().submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { slug: 'project' })
+  ).rejects.toBeUndefined();
+  await expect(
+    wrapper
+      .instance()
+      .submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { repository: 'repo' })
+  ).rejects.toBeUndefined();
+});
+
+it('should accept submit azure settings', async () => {
+  const wrapper = shallowRender();
+  await wrapper
+    .instance()
+    .submitProjectAlmBinding(AlmKeys.Azure, 'azure', { repository: 'az-repo', slug: 'az-project' });
+  expect(setProjectAzureBinding).toHaveBeenCalledWith({
+    almSetting: 'azure',
+    project: PROJECT_KEY,
+    repositoryName: 'az-repo',
+    projectName: 'az-project'
+  });
+});
+
 it('should reject submit github settings', async () => {
   const wrapper = shallowRender();
 
@@ -262,7 +296,11 @@ it('should validate form', async () => {
     ]
   });
 
-  expect(wrapper.instance().validateForm({ key: 'azure' })).toBe(true);
+  expect(wrapper.instance().validateForm({ key: 'azure', repository: 'rep' })).toBe(false);
+  expect(wrapper.instance().validateForm({ key: 'azure', slug: 'project' })).toBe(false);
+  expect(
+    wrapper.instance().validateForm({ key: 'azure', repository: 'repo', slug: 'project' })
+  ).toBe(true);
 
   expect(wrapper.instance().validateForm({ key: 'github', repository: '' })).toBe(false);
   expect(wrapper.instance().validateForm({ key: 'github', repository: 'asdf' })).toBe(true);
index 735fe355f7ca44541ab65e537abc81dcae9783d0..3144d479b516b24a672f52269491a4bceffbf225 100644 (file)
@@ -129,20 +129,6 @@ it('should render select options correctly', async () => {
   expect(optionRenderer!(instances[1])).toMatchSnapshot();
 });
 
-it('should render optional fields correctly', () => {
-  expect(
-    shallowRender({
-      formData: {
-        key: 'key'
-      },
-      isChanged: true,
-      isConfigured: false,
-      instances: [{ key: 'key', url: 'http://example.com', alm: AlmKeys.GitHub }],
-      loading: false
-    }).find('label[htmlFor="github.summary_comment_setting"]')
-  ).toMatchSnapshot();
-});
-
 function shallowRender(props: Partial<PRDecorationBindingRendererProps> = {}) {
   return shallow(
     <PRDecorationBindingRenderer
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap
new file mode 100644 (file)
index 0000000..6e57edf
--- /dev/null
@@ -0,0 +1,269 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`it should render correctly for azure 1`] = `
+<Fragment>
+  <div
+    className="form-field"
+  >
+    <label
+      className="display-flex-center"
+      htmlFor="azure.project"
+    >
+      settings.pr_decoration.binding.form.azure.project
+      <em
+        className="mandatory"
+      >
+        *
+      </em>
+      <HelpTooltip
+        className="spacer-left"
+        overlay={
+          <FormattedMessage
+            defaultMessage="settings.pr_decoration.binding.form.azure.project.help"
+            id="settings.pr_decoration.binding.form.azure.project.help"
+            values={Object {}}
+          />
+        }
+        placement="right"
+      />
+    </label>
+    <input
+      className="input-super-large"
+      id="azure.project"
+      maxLength={256}
+      name="azure.project"
+      onChange={[Function]}
+      type="text"
+      value=""
+    />
+  </div>
+  <div
+    className="form-field"
+  >
+    <label
+      className="display-flex-center"
+      htmlFor="azure.repository"
+    >
+      settings.pr_decoration.binding.form.azure.repository
+      <em
+        className="mandatory"
+      >
+        *
+      </em>
+      <HelpTooltip
+        className="spacer-left"
+        overlay={
+          <FormattedMessage
+            defaultMessage="settings.pr_decoration.binding.form.azure.repository.help"
+            id="settings.pr_decoration.binding.form.azure.repository.help"
+            values={Object {}}
+          />
+        }
+        placement="right"
+      />
+    </label>
+    <input
+      className="input-super-large"
+      id="azure.repository"
+      maxLength={256}
+      name="azure.repository"
+      onChange={[Function]}
+      type="text"
+      value=""
+    />
+  </div>
+</Fragment>
+`;
+
+exports[`it should render correctly for bitbucket 1`] = `
+<Fragment>
+  <div
+    className="form-field"
+  >
+    <label
+      className="display-flex-center"
+      htmlFor="bitbucket.repository"
+    >
+      settings.pr_decoration.binding.form.bitbucket.repository
+      <em
+        className="mandatory"
+      >
+        *
+      </em>
+      <HelpTooltip
+        className="spacer-left"
+        overlay={
+          <FormattedMessage
+            defaultMessage="settings.pr_decoration.binding.form.bitbucket.repository.help"
+            id="settings.pr_decoration.binding.form.bitbucket.repository.help"
+            values={
+              Object {
+                "example": <React.Fragment>
+                  .../projects/
+                  <strong>
+                    {KEY}
+                  </strong>
+                  /repos/{SLUG}/browse
+                </React.Fragment>,
+              }
+            }
+          />
+        }
+        placement="right"
+      />
+    </label>
+    <input
+      className="input-super-large"
+      id="bitbucket.repository"
+      maxLength={256}
+      name="bitbucket.repository"
+      onChange={[Function]}
+      type="text"
+      value=""
+    />
+  </div>
+  <div
+    className="form-field"
+  >
+    <label
+      className="display-flex-center"
+      htmlFor="bitbucket.slug"
+    >
+      settings.pr_decoration.binding.form.bitbucket.slug
+      <em
+        className="mandatory"
+      >
+        *
+      </em>
+      <HelpTooltip
+        className="spacer-left"
+        overlay={
+          <FormattedMessage
+            defaultMessage="settings.pr_decoration.binding.form.bitbucket.slug.help"
+            id="settings.pr_decoration.binding.form.bitbucket.slug.help"
+            values={
+              Object {
+                "example": <React.Fragment>
+                  .../projects/{KEY}/repos/
+                  <strong>
+                    {SLUG}
+                  </strong>
+                  /browse
+                </React.Fragment>,
+              }
+            }
+          />
+        }
+        placement="right"
+      />
+    </label>
+    <input
+      className="input-super-large"
+      id="bitbucket.slug"
+      maxLength={256}
+      name="bitbucket.slug"
+      onChange={[Function]}
+      type="text"
+      value=""
+    />
+  </div>
+</Fragment>
+`;
+
+exports[`it should render correctly for github 1`] = `
+<Fragment>
+  <div
+    className="form-field"
+  >
+    <label
+      className="display-flex-center"
+      htmlFor="github.repository"
+    >
+      settings.pr_decoration.binding.form.github.repository
+      <em
+        className="mandatory"
+      >
+        *
+      </em>
+      <HelpTooltip
+        className="spacer-left"
+        overlay={
+          <FormattedMessage
+            defaultMessage="settings.pr_decoration.binding.form.github.repository.help"
+            id="settings.pr_decoration.binding.form.github.repository.help"
+            values={
+              Object {
+                "example": "SonarSource/sonarqube",
+              }
+            }
+          />
+        }
+        placement="right"
+      />
+    </label>
+    <input
+      className="input-super-large"
+      id="github.repository"
+      maxLength={256}
+      name="github.repository"
+      onChange={[Function]}
+      type="text"
+      value=""
+    />
+  </div>
+  <div
+    className="form-field"
+  >
+    <label
+      className="display-flex-center"
+      htmlFor="github.summary_comment_setting"
+    >
+      settings.pr_decoration.binding.form.github.summary_comment_setting
+      <HelpTooltip
+        className="spacer-left"
+        overlay={
+          <FormattedMessage
+            defaultMessage="settings.pr_decoration.binding.form.github.summary_comment_setting.help"
+            id="settings.pr_decoration.binding.form.github.summary_comment_setting.help"
+            values={Object {}}
+          />
+        }
+        placement="right"
+      />
+    </label>
+    <InputForBoolean
+      isDefault={true}
+      name="github.summary_comment_setting"
+      onChange={[Function]}
+      value={true}
+    />
+  </div>
+</Fragment>
+`;
+
+exports[`it should render correctly for gitlab 1`] = `
+<div
+  className="form-field"
+>
+  <label
+    className="display-flex-center"
+    htmlFor="gitlab.repository"
+  >
+    settings.pr_decoration.binding.form.gitlab.repository
+    <em
+      className="mandatory"
+    >
+      *
+    </em>
+  </label>
+  <input
+    className="input-super-large"
+    id="gitlab.repository"
+    maxLength={256}
+    name="gitlab.repository"
+    onChange={[Function]}
+    type="text"
+    value=""
+  />
+</div>
+`;
index 50eceef7346a94851790ffdf3b7f278d83262245..8f87ef8a1cb648fcca749bc66e4c5d39b2f7e746 100644 (file)
@@ -411,72 +411,16 @@ exports[`should render multiple instances correctly 2`] = `
         valueRenderer={[Function]}
       />
     </div>
-    <div
-      className="form-field"
-    >
-      <label
-        className="display-flex-center"
-        htmlFor="github.repository"
-      >
-        settings.pr_decoration.binding.form.github.repository
-        <em
-          className="mandatory"
-        >
-          *
-        </em>
-        <HelpTooltip
-          className="spacer-left"
-          overlay={
-            <FormattedMessage
-              defaultMessage="settings.pr_decoration.binding.form.github.repository.help"
-              id="settings.pr_decoration.binding.form.github.repository.help"
-              values={
-                Object {
-                  "example": "SonarSource/sonarqube",
-                }
-              }
-            />
-          }
-          placement="right"
-        />
-      </label>
-      <input
-        className="input-super-large"
-        id="github.repository"
-        maxLength={256}
-        name="github.repository"
-        onChange={[Function]}
-        type="text"
-        value="account/repo"
-      />
-    </div>
-    <div
-      className="form-field"
-    >
-      <label
-        className="display-flex-center"
-        htmlFor="github.summary_comment_setting"
-      >
-        settings.pr_decoration.binding.form.github.summary_comment_setting
-        <HelpTooltip
-          className="spacer-left"
-          overlay={
-            <FormattedMessage
-              defaultMessage="settings.pr_decoration.binding.form.github.summary_comment_setting.help"
-              id="settings.pr_decoration.binding.form.github.summary_comment_setting.help"
-              values={Object {}}
-            />
-          }
-          placement="right"
-        />
-      </label>
-      <InputForBoolean
-        isDefault={true}
-        name="github.summary_comment_setting"
-        onChange={[Function]}
-        value={true}
-      />
-    </div>
+    <AlmSpecificForm
+      alm="github"
+      formData={
+        Object {
+          "key": "i1",
+          "repository": "account/repo",
+        }
+      }
+      onFieldChange={[MockFunction]}
+    />
     <div
       className="display-flex-center"
     >
@@ -499,26 +443,6 @@ exports[`should render multiple instances correctly 2`] = `
 </div>
 `;
 
-exports[`should render optional fields correctly 1`] = `
-<label
-  className="display-flex-center"
-  htmlFor="github.summary_comment_setting"
->
-  settings.pr_decoration.binding.form.github.summary_comment_setting
-  <HelpTooltip
-    className="spacer-left"
-    overlay={
-      <FormattedMessage
-        defaultMessage="settings.pr_decoration.binding.form.github.summary_comment_setting.help"
-        id="settings.pr_decoration.binding.form.github.summary_comment_setting.help"
-        values={Object {}}
-      />
-    }
-    placement="right"
-  />
-</label>
-`;
-
 exports[`should render select options correctly 1`] = `
 <span>
   azure
index 8ae38c80b9113c817dd860af4fa266bb6257c4b6..c27018afb2518d55d6c71177e428baafd7a93187 100644 (file)
@@ -82,7 +82,10 @@ export interface ProjectAlmBindingParams {
   project: string;
 }
 
-export interface AzureProjectAlmBindingParams extends ProjectAlmBindingParams {}
+export interface AzureProjectAlmBindingParams extends ProjectAlmBindingParams {
+  projectName: string;
+  repositoryName: string;
+}
 
 export interface BitbucketProjectAlmBindingParams extends ProjectAlmBindingParams {
   repository: string;
index 2bf94b588ac5d07c7e82b9298e7d0d0b69b14bc7..a0717a0f97e5f3a89f54ccd420f16db6798ae9ab 100644 (file)
@@ -1123,6 +1123,10 @@ settings.pr_decoration.binding.title=Pull Request Decoration
 settings.pr_decoration.binding.description=Enable Pull Request Decoration for this project.
 settings.pr_decoration.binding.form.url=Project location
 settings.pr_decoration.binding.form.name=Configuration name
+settings.pr_decoration.binding.form.azure.project=Project Name
+settings.pr_decoration.binding.form.azure.project.help=The name of the Azure DevOps Server project containing your repository.
+settings.pr_decoration.binding.form.azure.repository=Repository Name
+settings.pr_decoration.binding.form.azure.repository.help=The name of your Azure DevOps Server repository.
 settings.pr_decoration.binding.form.github.repository=Repository identifier
 settings.pr_decoration.binding.form.github.repository.help=The path of your repository URL. Example: {example}
 settings.pr_decoration.binding.form.github.summary_comment_setting=Enable analysis summary under the GitHub Conversation tab