]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-18581 Migrate RTL for EncryptionApp & components/AlmIntegration
authorstanislavh <stanislav.honcharov@sonarsource.com>
Wed, 29 Mar 2023 13:37:38 +0000 (15:37 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 30 Mar 2023 20:03:07 +0000 (20:03 +0000)
53 files changed:
server/sonar-web/src/main/js/api/alm-settings.ts
server/sonar-web/src/main/js/api/mocks/AlmSettingsServiceMock.ts
server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionBox.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormField.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmBindingDefinitionFormRenderer.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegration.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/AlmIntegrationRenderer.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/BitbucketForm.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionBox-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionForm-test.tsx
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormField-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormRenderer-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-it.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationRenderer-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTab-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTabRenderer-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketCloudForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketServerForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/CreationTooltip-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/DeleteModal-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionBox-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormField-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormRenderer-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationRenderer-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTab-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketCloudForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketServerForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/CreationTooltip-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/DeleteModal-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.tsx
server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.tsx
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-it.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/GenerateSecretKeyForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/GenerateSecretKeyForm-test.tsx.snap [deleted file]
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 60245542e3bed3dd123f8590c22d23297f27aae7..1ab02a892c793655fb57310771eaa8a0ef53f0c9 100644 (file)
@@ -110,7 +110,7 @@ export function deleteConfiguration(key: string) {
   return post('/api/alm_settings/delete', { key }).catch(throwGlobalError);
 }
 
-export function countBindedProjects(almSetting: string) {
+export function countBoundProjects(almSetting: string) {
   return getJSON('/api/alm_settings/count_binding', { almSetting })
     .then(({ projects }) => projects)
     .catch(throwGlobalError);
index 4a79a70f888b9538d37f8348cec949e1190ab01b..4b15331071aa8dd84d8d5d962977dad519689003 100644 (file)
  */
 import { cloneDeep } from 'lodash';
 import { mockAlmSettingsInstance } from '../../helpers/mocks/alm-settings';
-import { AlmKeys, AlmSettingsInstance } from '../../types/alm-settings';
-import { getAlmSettings } from '../alm-settings';
+import {
+  AlmKeys,
+  AlmSettingsBindingDefinitions,
+  AlmSettingsInstance,
+  AzureBindingDefinition,
+  BitbucketCloudBindingDefinition,
+  BitbucketServerBindingDefinition,
+  GithubBindingDefinition,
+  GitlabBindingDefinition,
+} from '../../types/alm-settings';
+import {
+  countBoundProjects,
+  createAzureConfiguration,
+  createBitbucketCloudConfiguration,
+  createBitbucketServerConfiguration,
+  createGithubConfiguration,
+  createGitlabConfiguration,
+  deleteConfiguration,
+  getAlmDefinitions,
+  getAlmSettings,
+  updateAzureConfiguration,
+  updateBitbucketCloudConfiguration,
+  updateBitbucketServerConfiguration,
+  updateGithubConfiguration,
+  updateGitlabConfiguration,
+  validateAlmSettings,
+} from '../alm-settings';
+
+const defaultAlmDefinitions = {
+  [AlmKeys.Azure]: [],
+  [AlmKeys.BitbucketServer]: [],
+  [AlmKeys.BitbucketCloud]: [],
+  [AlmKeys.GitHub]: [],
+  [AlmKeys.GitLab]: [],
+};
+
+const defaultAlmSettings = [
+  mockAlmSettingsInstance({ key: 'conf-final-1', alm: AlmKeys.GitLab }),
+  mockAlmSettingsInstance({ key: 'conf-final-2', alm: AlmKeys.GitLab }),
+  mockAlmSettingsInstance({ key: 'conf-github-1', alm: AlmKeys.GitHub, url: 'http://url' }),
+  mockAlmSettingsInstance({ key: 'conf-github-2', alm: AlmKeys.GitHub, url: 'http://url' }),
+  mockAlmSettingsInstance({ key: 'conf-github-3', alm: AlmKeys.GitHub, url: 'javascript://url' }),
+  mockAlmSettingsInstance({ key: 'conf-azure-1', alm: AlmKeys.Azure, url: 'url' }),
+  mockAlmSettingsInstance({ key: 'conf-azure-2', alm: AlmKeys.Azure, url: 'url' }),
+  mockAlmSettingsInstance({
+    key: 'conf-bitbucketcloud-1',
+    alm: AlmKeys.BitbucketCloud,
+    url: 'url',
+  }),
+  mockAlmSettingsInstance({
+    key: 'conf-bitbucketcloud-2',
+    alm: AlmKeys.BitbucketCloud,
+    url: 'url',
+  }),
+  mockAlmSettingsInstance({
+    key: 'conf-bitbucketserver-1',
+    alm: AlmKeys.BitbucketServer,
+    url: 'url',
+  }),
+  mockAlmSettingsInstance({
+    key: 'conf-bitbucketserver-2',
+    alm: AlmKeys.BitbucketServer,
+    url: 'url',
+  }),
+];
 
 export default class AlmSettingsServiceMock {
-  almSettings: AlmSettingsInstance[];
-  defaultSetting: AlmSettingsInstance[] = [
-    mockAlmSettingsInstance({ key: 'conf-final-1', alm: AlmKeys.GitLab }),
-    mockAlmSettingsInstance({ key: 'conf-final-2', alm: AlmKeys.GitLab }),
-    mockAlmSettingsInstance({ key: 'conf-github-1', alm: AlmKeys.GitHub, url: 'http://url' }),
-    mockAlmSettingsInstance({ key: 'conf-github-2', alm: AlmKeys.GitHub, url: 'http://url' }),
-    mockAlmSettingsInstance({ key: 'conf-github-3', alm: AlmKeys.GitHub, url: 'javascript://url' }),
-    mockAlmSettingsInstance({ key: 'conf-azure-1', alm: AlmKeys.Azure, url: 'url' }),
-    mockAlmSettingsInstance({ key: 'conf-azure-2', alm: AlmKeys.Azure, url: 'url' }),
-    mockAlmSettingsInstance({
-      key: 'conf-bitbucketcloud-1',
-      alm: AlmKeys.BitbucketCloud,
-      url: 'url',
-    }),
-    mockAlmSettingsInstance({
-      key: 'conf-bitbucketcloud-2',
-      alm: AlmKeys.BitbucketCloud,
-      url: 'url',
-    }),
-    mockAlmSettingsInstance({
-      key: 'conf-bitbucketserver-1',
-      alm: AlmKeys.BitbucketServer,
-      url: 'url',
-    }),
-    mockAlmSettingsInstance({
-      key: 'conf-bitbucketserver-2',
-      alm: AlmKeys.BitbucketServer,
-      url: 'url',
-    }),
-  ];
+  #almDefinitions: AlmSettingsBindingDefinitions;
+  #almSettings: AlmSettingsInstance[];
+  #definitionError = '';
 
   constructor() {
-    this.almSettings = cloneDeep(this.defaultSetting);
-    jest.mocked(getAlmSettings).mockImplementation(this.getAlmSettingsHandler);
+    this.#almSettings = cloneDeep(defaultAlmSettings);
+    this.#almDefinitions = cloneDeep(defaultAlmDefinitions);
+    jest.mocked(getAlmSettings).mockImplementation(this.handleGetAlmSettings);
+    jest.mocked(getAlmDefinitions).mockImplementation(this.handleGetAlmDefinitions);
+    jest.mocked(countBoundProjects).mockImplementation(this.handleCountBoundProjects);
+    jest.mocked(validateAlmSettings).mockImplementation(this.handleValidateAlmSettings);
+    jest.mocked(deleteConfiguration).mockImplementation(this.handleDeleteConfiguration);
+    jest.mocked(createGithubConfiguration).mockImplementation(this.handleCreateGithubConfiguration);
+    jest.mocked(createGitlabConfiguration).mockImplementation(this.handleCreateGitlabConfiguration);
+    jest.mocked(createAzureConfiguration).mockImplementation(this.handleCreateAzureConfiguration);
+    jest
+      .mocked(createBitbucketServerConfiguration)
+      .mockImplementation(this.handleCreateBitbucketServerConfiguration);
+    jest
+      .mocked(createBitbucketCloudConfiguration)
+      .mockImplementation(this.handleCreateBitbucketCloudConfiguration);
+    jest.mocked(updateGithubConfiguration).mockImplementation(this.handleUpdateGithubConfiguration);
+    jest.mocked(updateGitlabConfiguration).mockImplementation(this.handleUpdateGitlabConfiguration);
+    jest.mocked(updateAzureConfiguration).mockImplementation(this.handleUpdateAzureConfiguration);
+    jest
+      .mocked(updateBitbucketServerConfiguration)
+      .mockImplementation(this.handleUpdateBitbucketServerConfiguration);
+    jest
+      .mocked(updateBitbucketCloudConfiguration)
+      .mockImplementation(this.handleUpdateBitbucketCloudConfiguration);
   }
 
-  getAlmSettingsHandler = () => {
-    return Promise.resolve(this.almSettings);
+  handleGetAlmDefinitions = () => {
+    return this.reply(this.#almDefinitions);
+  };
+
+  handleGetAlmSettings = () => {
+    return this.reply(this.#almSettings);
+  };
+
+  handleValidateAlmSettings = () => {
+    return this.reply(this.#definitionError);
+  };
+
+  handleCountBoundProjects = () => {
+    return this.reply({ projects: 5 });
+  };
+
+  setDefinitionErrorMessage = (message: string) => {
+    this.#definitionError = message;
+  };
+
+  handleDeleteConfiguration = (key: string) => {
+    for (const definitionsGroup of Object.values(this.#almDefinitions) as [
+      GithubBindingDefinition[],
+      GitlabBindingDefinition[],
+      AzureBindingDefinition[],
+      BitbucketCloudBindingDefinition[],
+      BitbucketServerBindingDefinition[]
+    ]) {
+      const foundIndex = definitionsGroup.findIndex((definition) => definition.key === key);
+      if (foundIndex !== -1) {
+        definitionsGroup.splice(foundIndex, 1);
+        break;
+      }
+    }
+    return this.reply(undefined);
+  };
+
+  handleCreateGithubConfiguration = (data: GithubBindingDefinition) => {
+    this.#almDefinitions[AlmKeys.GitHub].push(data);
+
+    return this.reply(undefined);
+  };
+
+  handleCreateGitlabConfiguration = (data: GitlabBindingDefinition) => {
+    this.#almDefinitions[AlmKeys.GitLab].push(data);
+
+    return this.reply(undefined);
+  };
+
+  handleCreateAzureConfiguration = (data: AzureBindingDefinition) => {
+    this.#almDefinitions[AlmKeys.Azure].push(data);
+
+    return this.reply(undefined);
+  };
+
+  handleCreateBitbucketServerConfiguration = (data: BitbucketServerBindingDefinition) => {
+    this.#almDefinitions[AlmKeys.BitbucketServer].push(data);
+
+    return this.reply(undefined);
+  };
+
+  handleCreateBitbucketCloudConfiguration = (data: BitbucketCloudBindingDefinition) => {
+    this.#almDefinitions[AlmKeys.BitbucketCloud].push(data);
+
+    return this.reply(undefined);
+  };
+
+  handleUpdateGithubConfiguration = (data: GithubBindingDefinition & { newKey: string }) => {
+    const definition = this.#almDefinitions[AlmKeys.GitHub].find(
+      (item) => item.key === data.key
+    ) as GithubBindingDefinition;
+    Object.assign(definition, { ...data, key: data.newKey });
+
+    return this.reply(undefined);
+  };
+
+  handleUpdateGitlabConfiguration = (data: GitlabBindingDefinition & { newKey: string }) => {
+    const definition = this.#almDefinitions[AlmKeys.GitLab].find(
+      (item) => item.key === data.key
+    ) as GitlabBindingDefinition;
+    Object.assign(definition, { ...data, key: data.newKey });
+
+    return this.reply(undefined);
+  };
+
+  handleUpdateAzureConfiguration = (data: AzureBindingDefinition & { newKey: string }) => {
+    const definition = this.#almDefinitions[AlmKeys.Azure].find(
+      (item) => item.key === data.key
+    ) as AzureBindingDefinition;
+    Object.assign(definition, { ...data, key: data.newKey });
+
+    return this.reply(undefined);
+  };
+
+  handleUpdateBitbucketServerConfiguration = (
+    data: BitbucketServerBindingDefinition & { newKey: string }
+  ) => {
+    const definition = this.#almDefinitions[AlmKeys.BitbucketServer].find(
+      (item) => item.key === data.key
+    ) as BitbucketServerBindingDefinition;
+    Object.assign(definition, { ...data, key: data.newKey });
+
+    return this.reply(undefined);
+  };
+
+  handleUpdateBitbucketCloudConfiguration = (
+    data: BitbucketCloudBindingDefinition & { newKey: string }
+  ) => {
+    const definition = this.#almDefinitions[AlmKeys.BitbucketCloud].find(
+      (item) => item.key === data.key
+    ) as BitbucketCloudBindingDefinition;
+    Object.assign(definition, { ...data, key: data.newKey });
+
+    return this.reply(undefined);
   };
 
   reset = () => {
-    this.almSettings = cloneDeep(this.defaultSetting);
+    this.#almSettings = cloneDeep(defaultAlmSettings);
+    this.#almDefinitions = cloneDeep(defaultAlmDefinitions);
+    this.setDefinitionErrorMessage('');
   };
+
+  reply<T>(response: T): Promise<T> {
+    return Promise.resolve(cloneDeep(response));
+  }
 }
index b22051af84a9a68a69a8a29563636ab8838fcf07..9d0901edcc202b567151efcda4ddb11a6dc6ed8f 100644 (file)
@@ -29,6 +29,9 @@ import {
   SettingValue,
 } from '../../types/settings';
 import {
+  checkSecretKey,
+  encryptValue,
+  generateSecretKey,
   getAllValues,
   getDefinitions,
   getValue,
@@ -113,6 +116,8 @@ export default class SettingsServiceMock {
 
   #definitions: ExtendedSettingDefinition[] = cloneDeep(DEFAULT_DEFINITIONS_MOCK);
 
+  #secretKeyAvailable: boolean = false;
+
   constructor() {
     jest.mocked(getDefinitions).mockImplementation(this.handleGetDefinitions);
     jest.mocked(getValue).mockImplementation(this.handleGetValue);
@@ -120,6 +125,9 @@ export default class SettingsServiceMock {
     jest.mocked(getAllValues).mockImplementation(this.handleGetAllValues);
     jest.mocked(setSettingValue).mockImplementation(this.handleSetSettingValue);
     jest.mocked(resetSettingValue).mockImplementation(this.handleResetSettingValue);
+    jest.mocked(checkSecretKey).mockImplementation(this.handleCheckSecretKey);
+    jest.mocked(generateSecretKey).mockImplementation(this.handleGenerateSecretKey);
+    jest.mocked(encryptValue).mockImplementation(this.handleEcnryptValue);
   }
 
   handleGetValue = (data: { key: string; component?: string } & BranchParameters) => {
@@ -193,9 +201,26 @@ export default class SettingsServiceMock {
     this.#definitions.push(definition);
   };
 
+  handleCheckSecretKey = () => {
+    return this.reply({ secretKeyAvailable: this.#secretKeyAvailable });
+  };
+
+  handleGenerateSecretKey = () => {
+    return this.reply({ secretKey: 'secretKey' });
+  };
+
+  handleEcnryptValue = () => {
+    return this.reply({ encryptedValue: 'encryptedValue' });
+  };
+
+  setSecretKeyAvailable = (val = false) => {
+    this.#secretKeyAvailable = val;
+  };
+
   reset = () => {
     this.#settingValues = cloneDeep(this.#defaultValues);
     this.#definitions = cloneDeep(DEFAULT_DEFINITIONS_MOCK);
+    this.#secretKeyAvailable = false;
     return this;
   };
 
index f513009699dae13bf2ec302f7e1d3ec75d030989..dc188c3cf9f6b2054fd72f85e151515b48da1227 100644 (file)
@@ -30,7 +30,7 @@ import EditIcon from '../../../../components/icons/EditIcon';
 import { Alert } from '../../../../components/ui/Alert';
 import { ALM_DOCUMENTATION_PATHS, IMPORT_COMPATIBLE_ALMS } from '../../../../helpers/constants';
 import { getEdition, getEditionUrl } from '../../../../helpers/editions';
-import { translate } from '../../../../helpers/l10n';
+import { translate, translateWithParameters } from '../../../../helpers/l10n';
 import {
   AlmBindingDefinitionBase,
   AlmKeys,
@@ -144,11 +144,28 @@ export default function AlmBindingDefinitionBox(props: AlmBindingDefinitionBoxPr
   return (
     <div className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition">
       <div className="actions pull-right">
-        <Button onClick={() => props.onEdit(definition.key)}>
+        <Button
+          aria-label={translateWithParameters(
+            'settings.almintegration.edit_configuration',
+            definition.key
+          )}
+          onClick={() => {
+            props.onEdit(definition.key);
+          }}
+        >
           <EditIcon className="spacer-right" />
           {translate('edit')}
         </Button>
-        <Button className="button-red spacer-left" onClick={() => props.onDelete(definition.key)}>
+        <Button
+          aria-label={translateWithParameters(
+            'settings.almintegration.delete_configuration',
+            definition.key
+          )}
+          className="button-red spacer-left"
+          onClick={() => {
+            props.onDelete(definition.key);
+          }}
+        >
           <DeleteIcon className="spacer-right" />
           {translate('delete')}
         </Button>
@@ -228,7 +245,14 @@ export default function AlmBindingDefinitionBox(props: AlmBindingDefinitionBoxPr
             )}
           </div>
 
-          <Button className="big-spacer-top" onClick={() => props.onCheck(definition.key)}>
+          <Button
+            aria-label={translateWithParameters(
+              'settings.almintegration.check_configuration_x',
+              definition.key
+            )}
+            className="big-spacer-top"
+            onClick={() => props.onCheck(definition.key)}
+          >
             {translate('settings.almintegration.check_configuration')}
           </Button>
         </>
index 4abfd2ab835086fde04933c9ff4243929ea357b9..ca8d1557dc2331d27cb32da17d4994ba9caf95c5 100644 (file)
@@ -47,7 +47,7 @@ import { Dict } from '../../../../types/types';
 import { BITBUCKET_CLOUD_WORKSPACE_ID_FORMAT } from '../../constants';
 import AlmBindingDefinitionFormRenderer from './AlmBindingDefinitionFormRenderer';
 
-interface Props {
+export interface AlmBindingDefinitionFormProps {
   alm: AlmKeys;
   bindingDefinition?: AlmBindingDefinition;
   onCancel: () => void;
@@ -121,9 +121,12 @@ const BINDING_PER_ALM: {
   },
 };
 
-export default class AlmBindingDefinitionForm extends React.PureComponent<Props, State> {
+export default class AlmBindingDefinitionForm extends React.PureComponent<
+  AlmBindingDefinitionFormProps,
+  State
+> {
   mounted = false;
-  constructor(props: Props) {
+  constructor(props: AlmBindingDefinitionFormProps) {
     super(props);
 
     let bitbucketVariant: AlmKeys.BitbucketServer | AlmKeys.BitbucketCloud | undefined = undefined;
index 767ea0ee5afca6a4ab193491fbd5d915cdb21d0f..f23219298ac302856e6bc08e45b944d3e7fbae04 100644 (file)
@@ -26,7 +26,7 @@ import ValidationInput, {
 } from '../../../../components/controls/ValidationInput';
 import { Alert } from '../../../../components/ui/Alert';
 import MandatoryFieldMarker from '../../../../components/ui/MandatoryFieldMarker';
-import { translate } from '../../../../helpers/l10n';
+import { translate, translateWithParameters } from '../../../../helpers/l10n';
 import { AlmBindingDefinitionBase } from '../../../../types/alm-settings';
 import '../../styles.css';
 
@@ -79,6 +79,10 @@ export function AlmBindingDefinitionFormField<B extends AlmBindingDefinitionBase
           <div>
             <p>{translate('settings.almintegration.form.secret.field')}</p>
             <ButtonLink
+              aria-label={translateWithParameters(
+                'settings.almintegration.form.secret.update_field_x',
+                translate('settings.almintegration.form', id)
+              )}
               onClick={() => {
                 props.onFieldChange(propKey, '');
                 setShowField(true);
index dbc82d76c89ae11034b283591217ce6d1a37fb8b..238b25851920b0feb5271d83bf0d776d172ef12a 100644 (file)
@@ -37,7 +37,7 @@ import BitbucketForm from './BitbucketForm';
 import GithubForm from './GithubForm';
 import GitlabForm from './GitlabForm';
 
-export interface AlmBindingDefinitionFormProps {
+export interface Props {
   alm: AlmKeys;
   isUpdate: boolean;
   canSubmit: boolean;
@@ -53,7 +53,7 @@ export interface AlmBindingDefinitionFormProps {
   validationError?: string;
 }
 
-export default class AlmBindingDefinitionFormRenderer extends React.PureComponent<AlmBindingDefinitionFormProps> {
+export default class AlmBindingDefinitionFormRenderer extends React.PureComponent<Props> {
   renderForm = () => {
     const { alm, formData, isUpdate, bitbucketVariant } = this.props;
 
index 2987ee7c7d61fd51e6e949e1d25eb0a684cc62d7..0c3bf80f84f715dfd17e5a2b8cd1881312f1ee40 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as React from 'react';
 import {
-  countBindedProjects,
+  countBoundProjects,
   deleteConfiguration,
   getAlmDefinitions,
   validateAlmSettings,
@@ -159,7 +159,7 @@ export class AlmIntegration extends React.PureComponent<Props, State> {
 
   handleDelete = (definitionKey: string) => {
     this.setState({ loadingProjectCount: true });
-    return countBindedProjects(definitionKey)
+    return countBoundProjects(definitionKey)
       .then((projectCount) => {
         if (this.mounted) {
           this.setState({
@@ -212,7 +212,6 @@ export class AlmIntegration extends React.PureComponent<Props, State> {
   };
 
   render() {
-    const { hasFeature } = this.props;
     const {
       currentAlmTab,
       definitionKeyForDeletion,
@@ -226,7 +225,7 @@ export class AlmIntegration extends React.PureComponent<Props, State> {
     return (
       <AlmIntegrationRenderer
         branchesEnabled={this.props.hasFeature(Feature.BranchSupport)}
-        multipleAlmEnabled={hasFeature(Feature.MultipleAlm)}
+        multipleAlmEnabled={this.props.hasFeature(Feature.MultipleAlm)}
         onCancelDelete={this.handleCancelDelete}
         onConfirmDelete={this.handleConfirmDelete}
         onCheckConfiguration={this.handleCheck}
index a2cc18c32bc7cc40f27f558e49cc5ab912eb6edb..0c618d4cfcd85bb242715e73d697cabf2e1be345 100644 (file)
@@ -60,7 +60,7 @@ const tabs = [
           height={16}
           src={`${getBaseUrl()}/images/alm/github.svg`}
         />
-        GitHub
+        {translate('settings.almintegration.tab.github')}
       </>
     ),
   },
@@ -74,7 +74,7 @@ const tabs = [
           height={16}
           src={`${getBaseUrl()}/images/alm/bitbucket.svg`}
         />
-        Bitbucket
+        {translate('settings.almintegration.tab.bitbucket')}
       </>
     ),
   },
@@ -88,7 +88,7 @@ const tabs = [
           height={16}
           src={`${getBaseUrl()}/images/alm/azure.svg`}
         />
-        Azure DevOps
+        {translate('settings.almintegration.tab.azure')}
       </>
     ),
   },
@@ -102,7 +102,7 @@ const tabs = [
           height={16}
           src={`${getBaseUrl()}/images/alm/gitlab.svg`}
         />
-        GitLab
+        {translate('settings.almintegration.tab.gitlab')}
       </>
     ),
   },
index ff0d3e5ebbc451c88d4c6a306079d61e752aea9f..52f34d904b9e84ccb8a8372fed2000ebb3a7aac3 100644 (file)
@@ -53,10 +53,10 @@ export default function BitbucketForm(props: BitbucketFormProps) {
               onCheck={props.onVariantChange}
               options={[
                 {
-                  label: 'Bitbucket Server',
+                  label: translate('alm.bitbucket.long'),
                   value: AlmKeys.BitbucketServer,
                 },
-                { label: 'Bitbucket Cloud', value: AlmKeys.BitbucketCloud },
+                { label: translate('alm.bitbucketcloud.long'), value: AlmKeys.BitbucketCloud },
               ]}
               value={variant}
             />
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionBox-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionBox-test.tsx
deleted file mode 100644 (file)
index 63320ac..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 {
-  mockAlmSettingsBindingStatus,
-  mockAzureBindingDefinition,
-  mockBitbucketCloudBindingDefinition,
-  mockGithubBindingDefinition,
-  mockGitlabBindingDefinition,
-} from '../../../../../helpers/mocks/alm-settings';
-import { AlmKeys, AlmSettingsBindingStatusType } from '../../../../../types/alm-settings';
-import AlmBindingDefinitionBox, { AlmBindingDefinitionBoxProps } from '../AlmBindingDefinitionBox';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(
-    shallowRender({
-      status: mockAlmSettingsBindingStatus({
-        type: AlmSettingsBindingStatusType.Success,
-      }),
-    })
-  ).toMatchSnapshot('success');
-  expect(
-    shallowRender({
-      status: mockAlmSettingsBindingStatus({
-        failureMessage: 'Oops, something went wrong',
-        type: AlmSettingsBindingStatusType.Failure,
-      }),
-    })
-  ).toMatchSnapshot('error');
-
-  expect(
-    shallowRender({
-      status: mockAlmSettingsBindingStatus({
-        alertSuccess: true,
-        type: AlmSettingsBindingStatusType.Success,
-      }),
-    })
-  ).toMatchSnapshot('success with alert');
-
-  expect(
-    shallowRender({
-      status: mockAlmSettingsBindingStatus({
-        type: AlmSettingsBindingStatusType.Warning,
-      }),
-    })
-  ).toMatchSnapshot('warning');
-
-  expect(
-    shallowRender({ alm: AlmKeys.Azure, definition: mockAzureBindingDefinition() })
-  ).toMatchSnapshot('Azure DevOps');
-
-  expect(
-    shallowRender({
-      status: mockAlmSettingsBindingStatus({
-        type: AlmSettingsBindingStatusType.Success,
-      }),
-      alm: AlmKeys.GitLab,
-      definition: mockGitlabBindingDefinition(),
-    })
-  ).toMatchSnapshot('success for GitLab');
-
-  expect(
-    shallowRender({
-      status: mockAlmSettingsBindingStatus({
-        type: AlmSettingsBindingStatusType.Success,
-      }),
-      alm: AlmKeys.BitbucketCloud,
-      definition: mockBitbucketCloudBindingDefinition(),
-    })
-  ).toMatchSnapshot('success for Bitbucket Cloud');
-
-  expect(
-    shallowRender({
-      branchesEnabled: false,
-      status: mockAlmSettingsBindingStatus({
-        alertSuccess: true,
-        type: AlmSettingsBindingStatusType.Success,
-      }),
-    })
-  ).toMatchSnapshot('success with branches disabled');
-});
-
-function shallowRender(props: Partial<AlmBindingDefinitionBoxProps> = {}) {
-  return shallow(
-    <AlmBindingDefinitionBox
-      alm={AlmKeys.GitHub}
-      branchesEnabled={true}
-      definition={mockGithubBindingDefinition()}
-      onCheck={jest.fn()}
-      onDelete={jest.fn()}
-      onEdit={jest.fn()}
-      {...props}
-    />
-  );
-}
index 7b76ad160bb201145438c6792f047e7edb2fd288..447d1249ad24a3529ca562334c5d184753504b89 100644 (file)
  * 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 {
-  createAzureConfiguration,
-  createBitbucketCloudConfiguration,
-  createBitbucketServerConfiguration,
-  createGithubConfiguration,
-  createGitlabConfiguration,
-  deleteConfiguration,
-  updateAzureConfiguration,
-  updateBitbucketCloudConfiguration,
-  updateBitbucketServerConfiguration,
-  updateGithubConfiguration,
-  updateGitlabConfiguration,
-  validateAlmSettings,
-} from '../../../../../api/alm-settings';
-import {
-  mockAzureBindingDefinition,
-  mockBitbucketCloudBindingDefinition,
-  mockBitbucketServerBindingDefinition,
-  mockGithubBindingDefinition,
-  mockGitlabBindingDefinition,
-} from '../../../../../helpers/mocks/alm-settings';
-import { waitAndUpdate } from '../../../../../helpers/testUtils';
-import { AlmBindingDefinition, AlmKeys } from '../../../../../types/alm-settings';
-import AlmBindingDefinitionForm from '../AlmBindingDefinitionForm';
-import AlmBindingDefinitionFormRenderer from '../AlmBindingDefinitionFormRenderer';
-
-jest.mock('../../../../../api/alm-settings', () => ({
-  createAzureConfiguration: jest.fn().mockResolvedValue({}),
-  createBitbucketCloudConfiguration: jest.fn().mockResolvedValue({}),
-  createBitbucketServerConfiguration: jest.fn().mockResolvedValue({}),
-  createGithubConfiguration: jest.fn().mockResolvedValue({}),
-  createGitlabConfiguration: jest.fn().mockResolvedValue({}),
-  updateAzureConfiguration: jest.fn().mockResolvedValue({}),
-  updateBitbucketCloudConfiguration: jest.fn().mockResolvedValue({}),
-  updateBitbucketServerConfiguration: jest.fn().mockResolvedValue({}),
-  updateGithubConfiguration: jest.fn().mockResolvedValue({}),
-  updateGitlabConfiguration: jest.fn().mockResolvedValue({}),
-  validateAlmSettings: jest.fn().mockResolvedValue(undefined),
-  deleteConfiguration: jest.fn().mockResolvedValue(undefined),
-}));
-
-beforeEach(() => {
-  jest.clearAllMocks();
-});
-
-it('should render correctly', () => {
-  expect(shallowRender({ bindingDefinition: undefined })).toMatchSnapshot('create');
-  expect(shallowRender({ bindingDefinition: mockGithubBindingDefinition() })).toMatchSnapshot(
-    'edit'
-  );
-});
-
-it('should handle field changes', () => {
-  const formData = mockGithubBindingDefinition();
-
-  const wrapper = shallowRender();
-
-  wrapper.instance().handleFieldChange('key', formData.key);
-  wrapper.instance().handleFieldChange('url', formData.url);
-  wrapper.instance().handleFieldChange('appId', formData.appId);
-  wrapper.instance().handleFieldChange('clientId', formData.clientId);
-  wrapper.instance().handleFieldChange('clientSecret', formData.clientSecret);
-  wrapper.instance().handleFieldChange('privateKey', formData.privateKey);
-  expect(wrapper.state().formData).toEqual(formData);
-  expect(wrapper.state().touched).toBe(true);
-});
-
-it('should handle form submit', async () => {
-  const afterSubmit = jest.fn();
-  const formData = mockGithubBindingDefinition();
-
-  const wrapper = shallowRender({ afterSubmit });
-
-  wrapper.instance().setState({ formData });
-  await wrapper.instance().handleFormSubmit();
-  expect(afterSubmit).toHaveBeenCalledWith(formData);
-});
-
-it('should handle validation error during submit, and cancellation', async () => {
-  const afterSubmit = jest.fn();
-  const formData = mockGithubBindingDefinition();
-  const error = 'This a test error message';
-  (validateAlmSettings as jest.Mock).mockResolvedValueOnce(error);
-
-  const wrapper = shallowRender({ afterSubmit, enforceValidation: true });
-
-  wrapper.instance().setState({ formData });
-  await wrapper.instance().handleFormSubmit();
-  expect(validateAlmSettings).toHaveBeenCalledWith(formData.key);
-  expect(wrapper.state().validationError).toBe(error);
-  expect(afterSubmit).not.toHaveBeenCalledWith();
-
-  wrapper.find(AlmBindingDefinitionFormRenderer).props().onCancel();
-  expect(deleteConfiguration).toHaveBeenCalledWith(formData.key);
+import userEvent from '@testing-library/user-event';
+import React from 'react';
+import { byRole } from 'testing-library-selector';
+import AlmSettingsServiceMock from '../../../../../api/mocks/AlmSettingsServiceMock';
+import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
+import { AlmKeys } from '../../../../../types/alm-settings';
+import AlmBindingDefinitionForm, {
+  AlmBindingDefinitionFormProps,
+} from '../AlmBindingDefinitionForm';
+
+jest.mock('../../../../../api/alm-settings');
+
+let almSettings: AlmSettingsServiceMock;
+
+beforeAll(() => {
+  almSettings = new AlmSettingsServiceMock();
 });
 
-it.each([
-  [AlmKeys.Azure, undefined, createAzureConfiguration],
-  [AlmKeys.Azure, mockAzureBindingDefinition(), updateAzureConfiguration],
-  [AlmKeys.GitLab, undefined, createGitlabConfiguration],
-  [AlmKeys.GitLab, mockGitlabBindingDefinition(), updateGitlabConfiguration],
-  [AlmKeys.GitHub, undefined, createGithubConfiguration],
-  [AlmKeys.GitHub, mockGithubBindingDefinition(), updateGithubConfiguration],
-  [AlmKeys.BitbucketServer, undefined, createBitbucketServerConfiguration],
-  [
-    AlmKeys.BitbucketServer,
-    mockBitbucketServerBindingDefinition(),
-    updateBitbucketServerConfiguration,
-  ],
-])(
-  'should call the proper api on submit for %s | %s',
-  async (
-    alm: AlmKeys,
-    bindingDefinition: AlmBindingDefinition | undefined,
-    api: (def: AlmBindingDefinition) => any
-  ) => {
-    const wrapper = shallowRender({ alm, bindingDefinition });
-
-    await waitAndUpdate(wrapper);
-    await wrapper.instance().handleFormSubmit();
-    expect(api).toHaveBeenCalled();
-  }
-);
-
-it('should call the proper api for BBC', async () => {
-  const wrapper = shallowRender({
-    // Reminder: due to the way the settings app works, we never pass AlmKeys.BitbucketCloud as `alm`.
-    alm: AlmKeys.BitbucketServer,
-    bindingDefinition: undefined,
-  });
-
-  wrapper.instance().handleBitbucketVariantChange(AlmKeys.BitbucketCloud);
-
-  await waitAndUpdate(wrapper);
-  await wrapper.instance().handleFormSubmit();
-  expect(createBitbucketCloudConfiguration).toHaveBeenCalled();
-
-  wrapper.setProps({ bindingDefinition: mockBitbucketCloudBindingDefinition() });
-  await wrapper.instance().handleFormSubmit();
-  expect(updateBitbucketCloudConfiguration).toHaveBeenCalled();
+afterEach(() => {
+  almSettings.reset();
 });
 
-it('should store bitbucket variant', async () => {
-  const wrapper = shallowRender();
+const ui = {
+  bitbucketConfiguration: (almKey: AlmKeys.BitbucketCloud | AlmKeys.BitbucketServer) =>
+    byRole('button', { name: `alm.${almKey}.long` }),
+  configurationInput: (id: string) =>
+    byRole('textbox', { name: `settings.almintegration.form.${id}` }),
+  saveConfigurationButton: byRole('button', { name: 'settings.almintegration.form.save' }),
+  cancelButton: byRole('button', { name: 'cancel' }),
+  validationError: byRole('alert'),
+};
 
-  wrapper
-    .find(AlmBindingDefinitionFormRenderer)
-    .props()
-    .onBitbucketVariantChange(AlmKeys.BitbucketCloud);
+const onCancel = jest.fn();
 
-  await waitAndUpdate(wrapper);
-
-  expect(wrapper.state().bitbucketVariant).toBe(AlmKeys.BitbucketCloud);
-  expect(wrapper.state().formData).toEqual({
-    clientId: '',
-    clientSecret: '',
-    key: '',
-    workspace: '',
-  });
-});
+it('enforceValidation enabled', async () => {
+  almSettings.setDefinitionErrorMessage('Validation Error');
+  renderAlmBindingDefinitionForm();
 
-it('should (dis)allow submit by validating its state (Bitbucket Cloud)', () => {
-  const wrapper = shallowRender({
-    // Reminder: due to the way the settings app works, we never pass AlmKeys.BitbucketCloud as `alm`.
-    alm: AlmKeys.BitbucketServer,
-    bindingDefinition: mockBitbucketCloudBindingDefinition(),
-  });
-  expect(wrapper.instance().canSubmit()).toBe(false);
-
-  wrapper.setState({
-    formData: mockBitbucketCloudBindingDefinition({ workspace: 'foo/bar' }),
-    touched: true,
-  });
-  expect(wrapper.instance().canSubmit()).toBe(false);
-
-  wrapper.setState({ formData: mockBitbucketCloudBindingDefinition() });
-  expect(wrapper.instance().canSubmit()).toBe(true);
-});
+  // Fill in form
+  await userEvent.type(await ui.configurationInput('name.gitlab').find(), 'Name');
+  await userEvent.type(ui.configurationInput('url.gitlab').get(), 'https://api.alm.com');
+  await userEvent.type(ui.configurationInput('personal_access_token').get(), 'Access Token');
 
-it('should (dis)allow submit by validating its state (others)', () => {
-  const wrapper = shallowRender();
-  expect(wrapper.instance().canSubmit()).toBe(false);
+  await userEvent.click(ui.saveConfigurationButton.get());
+  expect(ui.validationError.get()).toHaveTextContent('Validation Error');
 
-  wrapper.setState({ formData: mockGithubBindingDefinition(), touched: true });
-  expect(wrapper.instance().canSubmit()).toBe(true);
+  await userEvent.click(ui.cancelButton.get());
+  expect(onCancel).toHaveBeenCalled();
 });
 
-function shallowRender(props: Partial<AlmBindingDefinitionForm['props']> = {}) {
-  return shallow<AlmBindingDefinitionForm>(
+function renderAlmBindingDefinitionForm(props: Partial<AlmBindingDefinitionFormProps> = {}) {
+  return renderComponent(
     <AlmBindingDefinitionForm
-      alm={AlmKeys.GitHub}
-      bindingDefinition={mockGithubBindingDefinition()}
-      onCancel={jest.fn()}
+      onCancel={onCancel}
       afterSubmit={jest.fn()}
+      enforceValidation={true}
+      alm={AlmKeys.GitLab}
       {...props}
     />
   );
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormField-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormField-test.tsx
deleted file mode 100644 (file)
index 5b9df15..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { ButtonLink } from '../../../../../components/controls/buttons';
-import { click } from '../../../../../helpers/testUtils';
-import { AlmBindingDefinitionBase } from '../../../../../types/alm-settings';
-import {
-  AlmBindingDefinitionFormField,
-  AlmBindingDefinitionFormFieldProps,
-} from '../AlmBindingDefinitionFormField';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(shallowRender({ help: 'help' })).toMatchSnapshot('with help');
-  expect(shallowRender({ isTextArea: true })).toMatchSnapshot('textarea');
-  expect(shallowRender({ optional: true })).toMatchSnapshot('optional');
-  expect(shallowRender({ overwriteOnly: true })).toMatchSnapshot('secret');
-  expect(shallowRender({ isSecret: true })).toMatchSnapshot('encryptable');
-  expect(shallowRender({ error: 'some error message', isInvalid: true })).toMatchSnapshot(
-    'invalid with error'
-  );
-});
-
-it('should call onFieldChange', () => {
-  const onInputChange = jest.fn();
-  shallowRender({ onFieldChange: onInputChange })
-    .find('input')
-    .simulate('change', { currentTarget: { value: '' } });
-  expect(onInputChange).toHaveBeenCalled();
-
-  const onTextAreaChange = jest.fn();
-  shallowRender({ isTextArea: true, onFieldChange: onTextAreaChange })
-    .find('textarea')
-    .simulate('change', { currentTarget: { value: '' } });
-  expect(onTextAreaChange).toHaveBeenCalled();
-});
-
-it('should correctly toggle visibility for secret fields', () => {
-  const onFieldChange = jest.fn();
-  const wrapper = shallowRender({ onFieldChange, overwriteOnly: true });
-  expect(wrapper.find('input').exists()).toBe(false);
-
-  click(wrapper.find(ButtonLink));
-  expect(onFieldChange).toHaveBeenCalledWith('key', '');
-  expect(wrapper.find('input').exists()).toBe(true);
-});
-
-function shallowRender(
-  props: Partial<AlmBindingDefinitionFormFieldProps<AlmBindingDefinitionBase>> = {}
-) {
-  return shallow(
-    <AlmBindingDefinitionFormField
-      id="key"
-      isTextArea={false}
-      maxLength={40}
-      onFieldChange={jest.fn()}
-      propKey="key"
-      value="key"
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmBindingDefinitionFormRenderer-test.tsx
deleted file mode 100644 (file)
index c006090..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { ResetButtonLink } from '../../../../../components/controls/buttons';
-import { mockGithubBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
-import { click, mockEvent } from '../../../../../helpers/testUtils';
-import { AlmKeys } from '../../../../../types/alm-settings';
-import AlmBindingDefinitionFormRenderer, {
-  AlmBindingDefinitionFormProps,
-} from '../AlmBindingDefinitionFormRenderer';
-import GithubForm from '../GithubForm';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ submitting: true })).toMatchSnapshot('submitting');
-  expect(shallowRender({ isUpdate: true })).toMatchSnapshot('editing');
-  expect(shallowRender({ validationError: 'this is a validation error' })).toMatchSnapshot(
-    'with validation error'
-  );
-});
-
-it.each([[AlmKeys.Azure], [AlmKeys.GitHub], [AlmKeys.GitLab], [AlmKeys.BitbucketServer]])(
-  'should render correctly for %s',
-  (alm) => {
-    expect(shallowRender({ alm })).toMatchSnapshot();
-  }
-);
-
-it('should cancel properly', () => {
-  const onCancel = jest.fn();
-  const wrapper = shallowRender({ onCancel });
-
-  click(wrapper.find(ResetButtonLink));
-  expect(onCancel).toHaveBeenCalled();
-});
-
-it('should submit properly', () => {
-  const onSubmit = jest.fn();
-  const wrapper = shallowRender({ onSubmit });
-
-  const event: React.SyntheticEvent<HTMLFormElement> = mockEvent({ preventDefault: jest.fn() });
-
-  wrapper.find('form').simulate('submit', event);
-
-  expect(event.preventDefault).toHaveBeenCalled();
-  expect(onSubmit).toHaveBeenCalled();
-});
-
-it('should handle field change', () => {
-  const onFieldChange = jest.fn();
-  const wrapper = shallowRender({ onFieldChange });
-
-  wrapper.find(GithubForm).props().onFieldChange('key', 'test');
-
-  expect(onFieldChange).toHaveBeenCalledWith('key', 'test');
-});
-
-function shallowRender(props: Partial<AlmBindingDefinitionFormProps> = {}) {
-  return shallow(
-    <AlmBindingDefinitionFormRenderer
-      alm={AlmKeys.GitHub}
-      isUpdate={false}
-      canSubmit={false}
-      submitting={false}
-      formData={mockGithubBindingDefinition()}
-      onCancel={jest.fn()}
-      onSubmit={jest.fn()}
-      onFieldChange={jest.fn()}
-      bitbucketVariant={AlmKeys.BitbucketServer}
-      onBitbucketVariantChange={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-it.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-it.tsx
new file mode 100644 (file)
index 0000000..4c53917
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 { screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import React from 'react';
+import { byRole, byText } from 'testing-library-selector';
+import AlmSettingsServiceMock from '../../../../../api/mocks/AlmSettingsServiceMock';
+import { AvailableFeaturesContext } from '../../../../../app/components/available-features/AvailableFeaturesContext';
+import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
+import { AlmKeys } from '../../../../../types/alm-settings';
+import { Feature } from '../../../../../types/features';
+import AlmIntegration from '../AlmIntegration';
+
+jest.mock('../../../../../api/alm-settings');
+
+let almSettings: AlmSettingsServiceMock;
+
+beforeAll(() => {
+  almSettings = new AlmSettingsServiceMock();
+});
+
+afterEach(() => {
+  almSettings.reset();
+});
+
+const ui = {
+  almHeading: byRole('heading', { name: 'settings.almintegration.title' }),
+  emptyIntro: (almKey: AlmKeys) => byText(`settings.almintegration.empty.${almKey}`),
+  createConfigurationButton: byRole('button', { name: 'settings.almintegration.create' }),
+  tab: (almKey: AlmKeys) =>
+    byRole('tab', { name: `${almKey} settings.almintegration.tab.${almKey}` }),
+  bitbucketConfiguration: (almKey: AlmKeys.BitbucketCloud | AlmKeys.BitbucketServer) =>
+    byRole('button', { name: `alm.${almKey}.long` }),
+  configurationInput: (id: string) =>
+    byRole('textbox', { name: `settings.almintegration.form.${id}` }),
+  updateSecretValueButton: (key: string) =>
+    byRole('button', {
+      name: `settings.almintegration.form.secret.update_field_x.settings.almintegration.form.${key}`,
+    }),
+  saveConfigurationButton: byRole('button', { name: 'settings.almintegration.form.save' }),
+  editConfigurationButton: (key: string) =>
+    byRole('button', { name: `settings.almintegration.edit_configuration.${key}` }),
+  deleteConfigurationButton: (key: string) =>
+    byRole('button', { name: `settings.almintegration.delete_configuration.${key}` }),
+  cancelButton: byRole('button', { name: 'cancel' }),
+  confirmDelete: byRole('button', { name: 'delete' }),
+  checkConfigurationButton: (key: string) =>
+    byRole('button', { name: `settings.almintegration.check_configuration_x.${key}` }),
+  validationErrorMessage: byRole('alert'),
+  validationSuccessMessage: byRole('status'),
+};
+
+describe('github tab', () => {
+  it('can create/edit/delete new configuration', async () => {
+    const { rerender } = renderAlmIntegration();
+    expect(await ui.almHeading.find()).toBeInTheDocument();
+    expect(ui.emptyIntro(AlmKeys.GitHub).get()).toBeInTheDocument();
+
+    // Create new configuration
+    await createConfiguration('Name', {
+      'name.github': 'Name',
+      'url.github': 'https://api.github.com',
+      app_id: 'Github App ID',
+      'client_id.github': 'Github Client ID',
+      'client_secret.github': 'Client Secret',
+      private_key: 'Key',
+    });
+
+    await editConfiguration('New Name', 'Name', 'client_secret.github', AlmKeys.GitHub);
+
+    await checkConfiguration('New Name');
+
+    rerender(<AlmIntegration />);
+    expect(await screen.findByRole('heading', { name: 'New Name' })).toBeInTheDocument();
+
+    await deleteConfiguration('New Name');
+    expect(ui.emptyIntro(AlmKeys.GitHub).get()).toBeInTheDocument();
+  });
+});
+
+describe.each([AlmKeys.GitLab, AlmKeys.Azure])(
+  '%s tab',
+  (almKey: AlmKeys.Azure | AlmKeys.GitLab) => {
+    it('can create/edit/delete new configuration', async () => {
+      renderAlmIntegration();
+      expect(await ui.almHeading.find()).toBeInTheDocument();
+
+      await userEvent.click(ui.tab(almKey).get());
+      expect(ui.emptyIntro(almKey).get()).toBeInTheDocument();
+
+      // Create new configuration
+      await createConfiguration('Name', {
+        [`name.${almKey}`]: 'Name',
+        [`url.${almKey}`]: 'https://api.alm.com',
+        personal_access_token: 'Access Token',
+      });
+
+      // Cannot create another configuration without Multiple Alm feature
+      expect(ui.createConfigurationButton.get()).toBeDisabled();
+
+      await editConfiguration('New Name', 'Name', 'personal_access_token', almKey);
+
+      await checkConfiguration('New Name');
+
+      await deleteConfiguration('New Name');
+      expect(ui.emptyIntro(almKey).get()).toBeInTheDocument();
+    });
+  }
+);
+
+describe('bitbucket tab', () => {
+  it('can create/edit/delete new configuration', async () => {
+    renderAlmIntegration([Feature.MultipleAlm]);
+    expect(await ui.almHeading.find()).toBeInTheDocument();
+
+    await userEvent.click(ui.tab(AlmKeys.BitbucketServer).get());
+    expect(ui.emptyIntro(AlmKeys.BitbucketServer).get()).toBeInTheDocument();
+
+    // Create new Bitbucket Server configuration
+    await createConfiguration(
+      'Name',
+      {
+        'name.bitbucket': 'Name',
+        'url.bitbucket': 'https://api.bitbucket.com',
+        personal_access_token: 'Access Token',
+      },
+      AlmKeys.BitbucketServer
+    );
+
+    // Create new Bitbucket Cloud configuration
+    await createConfiguration(
+      'Name Cloud',
+      {
+        'name.bitbucket': 'Name Cloud',
+        'workspace.bitbucketcloud': 'workspace',
+        'client_id.bitbucketcloud': 'Client ID',
+        'client_secret.bitbucketcloud': 'Client Secret',
+      },
+      AlmKeys.BitbucketCloud
+    );
+
+    // Edit, check delete Bitbucket Server configuration
+    await editConfiguration('New Name', 'Name', 'personal_access_token', AlmKeys.BitbucketServer);
+
+    await checkConfiguration('New Name');
+
+    await deleteConfiguration('New Name');
+
+    // Cloud configuration still exists
+    expect(screen.getByRole('heading', { name: 'Name Cloud' })).toBeInTheDocument();
+  });
+});
+
+async function createConfiguration(
+  name: string,
+  params: { [key: string]: string },
+  almKey?: AlmKeys.BitbucketCloud | AlmKeys.BitbucketServer
+) {
+  await userEvent.click(ui.createConfigurationButton.get());
+  expect(ui.saveConfigurationButton.get()).toBeDisabled();
+
+  if (almKey) {
+    await userEvent.click(ui.bitbucketConfiguration(almKey).get());
+  }
+
+  for (const [key, value] of Object.entries(params)) {
+    // eslint-disable-next-line no-await-in-loop
+    await userEvent.type(ui.configurationInput(key).get(), value);
+  }
+  expect(ui.saveConfigurationButton.get()).toBeEnabled();
+  await userEvent.click(ui.saveConfigurationButton.get());
+
+  // New configuration is created
+  expect(screen.getByRole('heading', { name })).toBeInTheDocument();
+}
+
+async function editConfiguration(
+  newName: string,
+  currentName: string,
+  secretId: string,
+  almKey: AlmKeys
+) {
+  almSettings.setDefinitionErrorMessage('Something is wrong');
+  await userEvent.click(ui.editConfigurationButton(currentName).get());
+  expect(ui.configurationInput(secretId).query()).not.toBeInTheDocument();
+  await userEvent.click(ui.updateSecretValueButton(secretId).get());
+  await userEvent.type(ui.configurationInput(secretId).get(), 'New Secret Value');
+  await userEvent.clear(ui.configurationInput(`name.${almKey}`).get());
+  await userEvent.type(ui.configurationInput(`name.${almKey}`).get(), newName);
+  await userEvent.click(ui.saveConfigurationButton.get());
+
+  // Existing configuration is edited
+  expect(screen.queryByRole('heading', { name: currentName })).not.toBeInTheDocument();
+  expect(screen.getByRole('heading', { name: newName })).toBeInTheDocument();
+  expect(ui.validationErrorMessage.get()).toHaveTextContent('Something is wrong');
+}
+
+async function checkConfiguration(name: string) {
+  almSettings.setDefinitionErrorMessage('');
+  await userEvent.click(ui.checkConfigurationButton(name).get());
+  expect(ui.validationSuccessMessage.getAll()[0]).toHaveTextContent(
+    'alert.tooltip.successsettings.almintegration.configuration_valid'
+  );
+}
+
+async function deleteConfiguration(name: string) {
+  await userEvent.click(ui.deleteConfigurationButton(name).get());
+  await userEvent.click(ui.cancelButton.get());
+  expect(screen.getByRole('heading', { name })).toBeInTheDocument();
+
+  await userEvent.click(ui.deleteConfigurationButton(name).get());
+  await userEvent.click(ui.confirmDelete.get());
+  expect(screen.queryByRole('heading', { name })).not.toBeInTheDocument();
+}
+
+function renderAlmIntegration(features: Feature[] = []) {
+  return renderComponent(
+    <AvailableFeaturesContext.Provider value={features}>
+      <AlmIntegration />
+    </AvailableFeaturesContext.Provider>
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegration-test.tsx
deleted file mode 100644 (file)
index 8bc8780..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 {
-  countBindedProjects,
-  deleteConfiguration,
-  getAlmDefinitions,
-  validateAlmSettings,
-} from '../../../../../api/alm-settings';
-import { mockLocation, mockRouter } from '../../../../../helpers/testMocks';
-import { waitAndUpdate } from '../../../../../helpers/testUtils';
-import { AlmKeys, AlmSettingsBindingStatusType } from '../../../../../types/alm-settings';
-import { AlmIntegration } from '../AlmIntegration';
-import AlmIntegrationRenderer from '../AlmIntegrationRenderer';
-
-jest.mock('../../../../../api/alm-settings', () => ({
-  countBindedProjects: jest.fn().mockResolvedValue(0),
-  deleteConfiguration: jest.fn().mockResolvedValue(undefined),
-  getAlmDefinitions: jest
-    .fn()
-    .mockResolvedValue({ azure: [], bitbucket: [], bitbucketcloud: [], github: [], gitlab: [] }),
-  validateAlmSettings: jest.fn().mockResolvedValue(''),
-}));
-
-beforeEach(() => {
-  jest.clearAllMocks();
-});
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should validate existing configurations', async () => {
-  (getAlmDefinitions as jest.Mock).mockResolvedValueOnce({
-    [AlmKeys.Azure]: [{ key: 'a1' }],
-    [AlmKeys.BitbucketServer]: [{ key: 'b1' }],
-    [AlmKeys.BitbucketCloud]: [{ key: 'bc1' }],
-    [AlmKeys.GitHub]: [{ key: 'gh1' }, { key: 'gh2' }],
-    [AlmKeys.GitLab]: [{ key: 'gl1' }],
-  });
-
-  const wrapper = shallowRender();
-
-  await waitAndUpdate(wrapper);
-
-  expect(validateAlmSettings).toHaveBeenCalledTimes(6);
-  expect(validateAlmSettings).toHaveBeenCalledWith('a1');
-  expect(validateAlmSettings).toHaveBeenCalledWith('b1');
-  expect(validateAlmSettings).toHaveBeenCalledWith('bc1');
-  expect(validateAlmSettings).toHaveBeenCalledWith('gh1');
-  expect(validateAlmSettings).toHaveBeenCalledWith('gh2');
-  expect(validateAlmSettings).toHaveBeenCalledWith('gl1');
-});
-
-it('should handle alm selection', async () => {
-  const router = mockRouter();
-  const wrapper = shallowRender({ router });
-
-  wrapper.setState({ currentAlmTab: AlmKeys.Azure });
-
-  wrapper.instance().handleSelectAlm(AlmKeys.GitHub);
-
-  await waitAndUpdate(wrapper);
-
-  expect(wrapper.state().currentAlmTab).toBe(AlmKeys.GitHub);
-  expect(router.push).toHaveBeenCalled();
-});
-
-it('should handle delete', async () => {
-  const toBeDeleted = '45672';
-  (countBindedProjects as jest.Mock).mockResolvedValueOnce(7);
-  const wrapper = shallowRender();
-
-  wrapper.find(AlmIntegrationRenderer).props().onDelete(toBeDeleted);
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().projectCount).toBe(7);
-  expect(wrapper.state().definitionKeyForDeletion).toBe(toBeDeleted);
-
-  wrapper.find(AlmIntegrationRenderer).props().onCancelDelete();
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().projectCount).toBeUndefined();
-  expect(wrapper.state().definitionKeyForDeletion).toBeUndefined();
-});
-
-it('should delete configuration', async () => {
-  (deleteConfiguration as jest.Mock).mockResolvedValueOnce(undefined);
-  const wrapper = shallowRender();
-  wrapper.instance().handleConfirmDelete('8345678');
-
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().projectCount).toBeUndefined();
-  expect(wrapper.state().definitionKeyForDeletion).toBeUndefined();
-});
-
-it('should validate a configuration', async () => {
-  const definitionKey = 'validated-key';
-  const failureMessage = 'an error occured';
-
-  const wrapper = shallowRender();
-  await waitAndUpdate(wrapper);
-
-  (validateAlmSettings as jest.Mock)
-    .mockRejectedValueOnce(undefined)
-    .mockResolvedValueOnce(failureMessage)
-    .mockResolvedValueOnce('')
-    .mockResolvedValueOnce('');
-
-  await wrapper.instance().handleCheck(definitionKey);
-
-  expect(wrapper.state().definitionStatus[definitionKey]).toEqual({
-    alertSuccess: true,
-    failureMessage: '',
-    type: AlmSettingsBindingStatusType.Warning,
-  });
-
-  await wrapper.instance().handleCheck(definitionKey);
-
-  expect(wrapper.state().definitionStatus[definitionKey]).toEqual({
-    alertSuccess: true,
-    failureMessage,
-    type: AlmSettingsBindingStatusType.Failure,
-  });
-
-  await wrapper.instance().handleCheck(definitionKey);
-
-  expect(wrapper.state().definitionStatus[definitionKey]).toEqual({
-    alertSuccess: true,
-    failureMessage: '',
-    type: AlmSettingsBindingStatusType.Success,
-  });
-});
-
-it('should fetch settings', async () => {
-  const definitions = {
-    [AlmKeys.Azure]: [{ key: 'a1' }],
-    [AlmKeys.BitbucketServer]: [{ key: 'b1' }],
-    [AlmKeys.BitbucketCloud]: [{ key: 'bc1' }],
-    [AlmKeys.GitHub]: [{ key: 'gh1' }],
-    [AlmKeys.GitLab]: [{ key: 'gl1' }],
-  };
-
-  const wrapper = shallowRender();
-  await waitAndUpdate(wrapper);
-
-  (getAlmDefinitions as jest.Mock).mockResolvedValueOnce(definitions);
-
-  await wrapper.instance().fetchPullRequestDecorationSetting();
-
-  expect(getAlmDefinitions).toHaveBeenCalled();
-  expect(wrapper.state().definitions).toEqual(definitions);
-  expect(wrapper.state().loadingAlmDefinitions).toBe(false);
-});
-
-it('should detect the current ALM from the query', () => {
-  let wrapper = shallowRender({ location: mockLocation() });
-  expect(wrapper.state().currentAlmTab).toBe(AlmKeys.GitHub);
-
-  wrapper = shallowRender({ location: mockLocation({ query: { alm: AlmKeys.BitbucketCloud } }) });
-  expect(wrapper.state().currentAlmTab).toBe(AlmKeys.BitbucketServer);
-
-  wrapper.setProps({ location: mockLocation({ query: { alm: AlmKeys.GitLab } }) });
-  expect(wrapper.state().currentAlmTab).toBe(AlmKeys.GitLab);
-});
-
-function shallowRender(props: Partial<AlmIntegration['props']> = {}) {
-  return shallow<AlmIntegration>(
-    <AlmIntegration
-      hasFeature={jest.fn().mockReturnValue(true)}
-      location={mockLocation()}
-      router={mockRouter()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmIntegrationRenderer-test.tsx
deleted file mode 100644 (file)
index cb9802b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 AlmIntegrationRenderer, { AlmIntegrationRendererProps } from '../AlmIntegrationRenderer';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(shallowRender({ loadingAlmDefinitions: true, loadingProjectCount: true })).toMatchSnapshot(
-    'loading'
-  );
-  expect(shallowRender({ definitionKeyForDeletion: 'keyToDelete' })).toMatchSnapshot(
-    'delete modal'
-  );
-  expect(shallowRender({ currentAlmTab: AlmKeys.Azure })).toMatchSnapshot('azure');
-  expect(shallowRender({ currentAlmTab: AlmKeys.BitbucketServer })).toMatchSnapshot('bitbucket');
-  expect(shallowRender({ currentAlmTab: AlmKeys.GitLab })).toMatchSnapshot('gitlab');
-});
-
-function shallowRender(props: Partial<AlmIntegrationRendererProps> = {}) {
-  return shallow(
-    <AlmIntegrationRenderer
-      branchesEnabled={true}
-      currentAlmTab={AlmKeys.GitHub}
-      definitions={{ azure: [], bitbucket: [], bitbucketcloud: [], github: [], gitlab: [] }}
-      definitionStatus={{}}
-      loadingAlmDefinitions={false}
-      loadingProjectCount={false}
-      multipleAlmEnabled={false}
-      onCancelDelete={jest.fn()}
-      onCheckConfiguration={jest.fn()}
-      onConfirmDelete={jest.fn()}
-      onDelete={jest.fn()}
-      onSelectAlmTab={jest.fn()}
-      onUpdateDefinitions={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTab-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTab-test.tsx
deleted file mode 100644 (file)
index 0866022..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockAzureBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
-import { waitAndUpdate } from '../../../../../helpers/testUtils';
-import { AlmKeys } from '../../../../../types/alm-settings';
-import AlmTab from '../AlmTab';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should handle cancel', async () => {
-  const wrapper = shallowRender();
-
-  wrapper.setState({
-    editedDefinition: mockAzureBindingDefinition(),
-  });
-
-  wrapper.instance().handleCancel();
-
-  await waitAndUpdate(wrapper);
-
-  expect(wrapper.state().editedDefinition).toBeUndefined();
-});
-
-it('should handle edit', async () => {
-  const config = mockAzureBindingDefinition();
-  const wrapper = shallowRender({ definitions: [config] });
-
-  wrapper.instance().handleEdit(config.key);
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().editedDefinition).toEqual(config);
-});
-
-it('should handle create', async () => {
-  const wrapper = shallowRender();
-
-  wrapper.instance().handleCreate();
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().editedDefinition).toBeUndefined();
-});
-
-it('should handle afterSubmit', async () => {
-  const onUpdateDefinitions = jest.fn();
-  const onCheck = jest.fn();
-  const binding = mockAzureBindingDefinition();
-
-  const wrapper = shallowRender({ onUpdateDefinitions, onCheck });
-
-  wrapper.instance().handleAfterSubmit(binding);
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().editedDefinition).toBeUndefined();
-  expect(onUpdateDefinitions).toHaveBeenCalled();
-  expect(onCheck).toHaveBeenCalledWith(binding.key);
-});
-
-function shallowRender(props: Partial<AlmTab['props']> = {}) {
-  return shallow<AlmTab>(
-    <AlmTab
-      almTab={AlmKeys.Azure}
-      branchesEnabled={true}
-      definitions={[mockAzureBindingDefinition()]}
-      definitionStatus={{}}
-      loadingAlmDefinitions={false}
-      loadingProjectCount={false}
-      multipleAlmEnabled={true}
-      onCheck={jest.fn()}
-      onDelete={jest.fn()}
-      onUpdateDefinitions={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTabRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AlmTabRenderer-test.tsx
deleted file mode 100644 (file)
index 345d0b5..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 {
-  mockAzureBindingDefinition,
-  mockBitbucketCloudBindingDefinition,
-  mockGithubBindingDefinition,
-} from '../../../../../helpers/mocks/alm-settings';
-import { AlmKeys } from '../../../../../types/alm-settings';
-import AlmTabRenderer, { AlmTabRendererProps } from '../AlmTabRenderer';
-
-it('should render correctly for multi-ALM binding', () => {
-  expect(shallowRenderAzure({ loadingAlmDefinitions: true })).toMatchSnapshot(
-    'loading ALM definitions'
-  );
-  expect(shallowRenderAzure({ loadingProjectCount: true })).toMatchSnapshot(
-    'loading project count'
-  );
-  expect(shallowRenderAzure({})).toMatchSnapshot('loaded');
-  expect(shallowRenderAzure({ editedDefinition: mockAzureBindingDefinition() })).toMatchSnapshot(
-    'editing a definition'
-  );
-});
-
-it('should render correctly for single-ALM binding', () => {
-  expect(
-    shallowRenderAzure({ loadingAlmDefinitions: true, multipleAlmEnabled: false })
-  ).toMatchSnapshot();
-  expect(shallowRenderAzure({ multipleAlmEnabled: false })).toMatchSnapshot();
-  expect(
-    shallowRenderAzure({ definitions: [mockAzureBindingDefinition()], multipleAlmEnabled: false })
-  ).toMatchSnapshot();
-});
-
-it('should render correctly with validation', () => {
-  const githubProps = {
-    alm: AlmKeys.GitHub,
-    definitions: [mockGithubBindingDefinition()],
-  };
-  expect(shallowRender(githubProps)).toMatchSnapshot('default');
-  expect(shallowRender({ ...githubProps, definitions: [] })).toMatchSnapshot('empty');
-
-  expect(
-    shallowRender({
-      ...githubProps,
-      editedDefinition: mockGithubBindingDefinition(),
-    })
-  ).toMatchSnapshot('create a second');
-
-  expect(
-    shallowRender({
-      ...githubProps,
-      definitions: [],
-      editedDefinition: mockGithubBindingDefinition(),
-    })
-  ).toMatchSnapshot('create a first');
-
-  expect(
-    shallowRender({
-      almTab: AlmKeys.BitbucketServer, // BitbucketServer will be passed for both Bitbucket variants.
-      definitions: [mockBitbucketCloudBindingDefinition()],
-    })
-  ).toMatchSnapshot('pass the correct key for bitbucket cloud');
-});
-
-function shallowRenderAzure(props: Partial<AlmTabRendererProps>) {
-  return shallowRender({
-    definitions: [mockAzureBindingDefinition()],
-    ...props,
-  });
-}
-
-function shallowRender(props: Partial<AlmTabRendererProps> = {}) {
-  return shallow(
-    <AlmTabRenderer
-      almTab={AlmKeys.Azure}
-      branchesEnabled={true}
-      definitions={[]}
-      definitionStatus={{}}
-      loadingAlmDefinitions={false}
-      loadingProjectCount={false}
-      multipleAlmEnabled={true}
-      onCancel={jest.fn()}
-      onCheck={jest.fn()}
-      onCreate={jest.fn()}
-      onDelete={jest.fn()}
-      onEdit={jest.fn()}
-      afterSubmit={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/AzureForm-test.tsx
deleted file mode 100644 (file)
index c1c6a2e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockAzureBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
-import AzureForm, { AzureFormProps } from '../AzureForm';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('create');
-  expect(shallowRender({ formData: mockAzureBindingDefinition() })).toMatchSnapshot('edit');
-});
-
-function shallowRender(props: Partial<AzureFormProps> = {}) {
-  return shallow(
-    <AzureForm
-      formData={{ key: '', personalAccessToken: '' }}
-      onFieldChange={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketCloudForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketCloudForm-test.tsx
deleted file mode 100644 (file)
index 71f5774..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockBitbucketCloudBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
-import BitbucketCloudForm, { BitbucketCloudFormProps } from '../BitbucketCloudForm';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(
-    shallowRender({ formData: mockBitbucketCloudBindingDefinition({ workspace: 'my/workspace' }) })
-  ).toMatchSnapshot('invalid workspace ID');
-});
-
-function shallowRender(props: Partial<BitbucketCloudFormProps> = {}) {
-  return shallow<BitbucketCloudFormProps>(
-    <BitbucketCloudForm
-      onFieldChange={jest.fn()}
-      formData={mockBitbucketCloudBindingDefinition()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketForm-test.tsx
deleted file mode 100644 (file)
index 026caea..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 ButtonToggle from '../../../../../components/controls/ButtonToggle';
-import {
-  mockBitbucketCloudBindingDefinition,
-  mockBitbucketServerBindingDefinition,
-} from '../../../../../helpers/mocks/alm-settings';
-import { AlmKeys } from '../../../../../types/alm-settings';
-import BitbucketForm, { BitbucketFormProps } from '../BitbucketForm';
-
-it('should render correctly', () => {
-  let wrapper = shallowRender({
-    variant: AlmKeys.BitbucketServer,
-    formData: mockBitbucketServerBindingDefinition(),
-  });
-  expect(wrapper).toMatchSnapshot('bbs');
-
-  wrapper = shallowRender({
-    variant: AlmKeys.BitbucketCloud,
-    formData: mockBitbucketCloudBindingDefinition(),
-  });
-  expect(wrapper).toMatchSnapshot('bbc');
-
-  wrapper = shallowRender({
-    isUpdate: true,
-    variant: AlmKeys.BitbucketServer,
-    formData: mockBitbucketServerBindingDefinition(),
-  });
-  expect(wrapper).toMatchSnapshot('update bbs');
-
-  wrapper = shallowRender({
-    isUpdate: true,
-    variant: AlmKeys.BitbucketCloud,
-    formData: mockBitbucketCloudBindingDefinition(),
-  });
-  expect(wrapper).toMatchSnapshot('update bbc');
-});
-
-it('should render propagete variant properly', () => {
-  const onVariantChange = jest.fn();
-  const wrapper = shallowRender({ onVariantChange });
-
-  wrapper.find(ButtonToggle).props().onCheck(AlmKeys.BitbucketServer);
-
-  expect(onVariantChange).toHaveBeenCalledWith(AlmKeys.BitbucketServer);
-});
-
-function shallowRender(props: Partial<BitbucketFormProps> = {}) {
-  return shallow(
-    <BitbucketForm
-      formData={mockBitbucketServerBindingDefinition()}
-      isUpdate={false}
-      onFieldChange={jest.fn()}
-      variant={AlmKeys.BitbucketServer}
-      onVariantChange={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketServerForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/BitbucketServerForm-test.tsx
deleted file mode 100644 (file)
index 9e9f1bf..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockBitbucketServerBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
-import BitbucketServerForm, { BitbucketServerFormProps } from '../BitbucketServerForm';
-
-it('should render correctly', () => {
-  const wrapper = shallowRender();
-  expect(wrapper).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<BitbucketServerFormProps> = {}) {
-  return shallow<BitbucketServerFormProps>(
-    <BitbucketServerForm
-      onFieldChange={jest.fn()}
-      formData={mockBitbucketServerBindingDefinition()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/CreationTooltip-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/CreationTooltip-test.tsx
deleted file mode 100644 (file)
index f27de39..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockAppState } from '../../../../../helpers/testMocks';
-import { AlmKeys } from '../../../../../types/alm-settings';
-import { EditionKey } from '../../../../../types/editions';
-import { CreationTooltip, CreationTooltipProps } from '../CreationTooltip';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ preventCreation: false })).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<CreationTooltipProps> = {}) {
-  return shallow(
-    <CreationTooltip
-      alm={AlmKeys.Azure}
-      appState={mockAppState({ edition: EditionKey.community })}
-      preventCreation={true}
-      {...props}
-    >
-      <span>Child</span>
-    </CreationTooltip>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/DeleteModal-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/DeleteModal-test.tsx
deleted file mode 100644 (file)
index 50481dd..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 DeleteModal, { DeleteModalProps } from '../DeleteModal';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ projectCount: undefined })).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<DeleteModalProps> = {}) {
-  return shallow(
-    <DeleteModal id="1" onCancel={jest.fn()} onDelete={jest.fn()} projectCount={4} {...props} />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GithubForm-test.tsx
deleted file mode 100644 (file)
index ed1485a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockGithubBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
-import GithubForm, { GithubFormProps } from '../GithubForm';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ formData: mockGithubBindingDefinition() })).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<GithubFormProps> = {}) {
-  return shallow(
-    <GithubForm
-      formData={{
-        key: '',
-        appId: '',
-        clientId: '',
-        clientSecret: '',
-        privateKey: '',
-        url: '',
-        webhookSecret: '',
-      }}
-      onFieldChange={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/GitlabForm-test.tsx
deleted file mode 100644 (file)
index 9963245..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockGitlabBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
-import GitlabForm, { GitlabFormProps } from '../GitlabForm';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ formData: mockGitlabBindingDefinition() })).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<GitlabFormProps> = {}) {
-  return shallow(
-    <GitlabForm
-      formData={{ key: '', personalAccessToken: '' }}
-      onFieldChange={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionBox-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionBox-test.tsx.snap
deleted file mode 100644 (file)
index f72efa1..0000000
+++ /dev/null
@@ -1,679 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: Azure DevOps 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-  </div>
-  <i
-    className="spinner spacer-right"
-  />
-  settings.almintegration.checking_configuration
-</div>
-`;
-
-exports[`should render correctly: default 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-    <span>
-      http://github.enterprise.com
-    </span>
-  </div>
-  <i
-    className="spinner spacer-right"
-  />
-  settings.almintegration.checking_configuration
-</div>
-`;
-
-exports[`should render correctly: error 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-    <span>
-      http://github.enterprise.com
-    </span>
-  </div>
-  <div
-    className="display-flex-row spacer-bottom"
-  >
-    <div
-      className="huge-spacer-right"
-    >
-      <Tooltip
-        overlay="settings.almintegration.feature.status_reporting.description_pr_and_commits"
-      >
-        <span>
-          settings.almintegration.feature.status_reporting.title
-        </span>
-      </Tooltip>
-      <AlertErrorIcon
-        className="spacer-left"
-      />
-    </div>
-    <div>
-      <Tooltip
-        overlay="settings.almintegration.feature.alm_repo_import.description"
-      >
-        <span>
-          settings.almintegration.feature.alm_repo_import.title
-        </span>
-      </Tooltip>
-      <AlertErrorIcon
-        className="spacer-left"
-      />
-    </div>
-  </div>
-  <div
-    className="width-50"
-  >
-    <Alert
-      variant="error"
-    >
-      Oops, something went wrong
-    </Alert>
-  </div>
-  <Button
-    className="big-spacer-top"
-    onClick={[Function]}
-  >
-    settings.almintegration.check_configuration
-  </Button>
-</div>
-`;
-
-exports[`should render correctly: success 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-    <span>
-      http://github.enterprise.com
-    </span>
-  </div>
-  <div
-    className="display-flex-row spacer-bottom"
-  >
-    <div
-      className="huge-spacer-right"
-    >
-      <Tooltip
-        overlay="settings.almintegration.feature.status_reporting.description_pr_and_commits"
-      >
-        <span>
-          settings.almintegration.feature.status_reporting.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-    <div>
-      <Tooltip
-        overlay="settings.almintegration.feature.alm_repo_import.description"
-      >
-        <span>
-          settings.almintegration.feature.alm_repo_import.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-  </div>
-  <div
-    className="width-50"
-  />
-  <Button
-    className="big-spacer-top"
-    onClick={[Function]}
-  >
-    settings.almintegration.check_configuration
-  </Button>
-</div>
-`;
-
-exports[`should render correctly: success for Bitbucket Cloud 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-  </div>
-  <div
-    className="display-flex-row spacer-bottom"
-  >
-    <div
-      className="huge-spacer-right"
-    >
-      <Tooltip
-        overlay="settings.almintegration.feature.status_reporting.description_pr"
-      >
-        <span>
-          settings.almintegration.feature.status_reporting.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-    <div>
-      <Tooltip
-        overlay="settings.almintegration.feature.alm_repo_import.description"
-      >
-        <span>
-          settings.almintegration.feature.alm_repo_import.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-  </div>
-  <div
-    className="width-50"
-  />
-  <Button
-    className="big-spacer-top"
-    onClick={[Function]}
-  >
-    settings.almintegration.check_configuration
-  </Button>
-</div>
-`;
-
-exports[`should render correctly: success for GitLab 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      foo
-    </h3>
-  </div>
-  <div
-    className="display-flex-row spacer-bottom"
-  >
-    <div
-      className="huge-spacer-right"
-    >
-      <Tooltip
-        overlay="settings.almintegration.feature.status_reporting.description_mr"
-      >
-        <span>
-          settings.almintegration.feature.status_reporting.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-    <div>
-      <Tooltip
-        overlay="settings.almintegration.feature.alm_repo_import.description"
-      >
-        <span>
-          settings.almintegration.feature.alm_repo_import.title
-        </span>
-      </Tooltip>
-      <div
-        className="display-inline-flex-center"
-      >
-        <strong
-          className="spacer-left"
-        >
-          settings.almintegration.feature.alm_repo_import.disabled
-        </strong>
-        <HelpTooltip
-          className="little-spacer-left"
-          overlay="settings.almintegration.feature.alm_repo_import.disabled.no_url"
-        />
-      </div>
-    </div>
-  </div>
-  <div
-    className="width-50"
-  />
-  <Button
-    className="big-spacer-top"
-    onClick={[Function]}
-  >
-    settings.almintegration.check_configuration
-  </Button>
-</div>
-`;
-
-exports[`should render correctly: success with alert 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-    <span>
-      http://github.enterprise.com
-    </span>
-  </div>
-  <div
-    className="display-flex-row spacer-bottom"
-  >
-    <div
-      className="huge-spacer-right"
-    >
-      <Tooltip
-        overlay="settings.almintegration.feature.status_reporting.description_pr_and_commits"
-      >
-        <span>
-          settings.almintegration.feature.status_reporting.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-    <div>
-      <Tooltip
-        overlay="settings.almintegration.feature.alm_repo_import.description"
-      >
-        <span>
-          settings.almintegration.feature.alm_repo_import.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-  </div>
-  <div
-    className="width-50"
-  >
-    <Alert
-      variant="success"
-    >
-      settings.almintegration.configuration_valid
-    </Alert>
-    <Alert
-      variant="warning"
-    >
-      <FormattedMessage
-        defaultMessage="settings.almintegration.github.additional_permission"
-        id="settings.almintegration.github.additional_permission"
-        values={
-          {
-            "link": <withAppStateContext(DocLink)
-              to="/devops-platform-integration/github-integration/"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-          }
-        }
-      />
-    </Alert>
-  </div>
-  <Button
-    className="big-spacer-top"
-    onClick={[Function]}
-  >
-    settings.almintegration.check_configuration
-  </Button>
-</div>
-`;
-
-exports[`should render correctly: success with branches disabled 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-    <span>
-      http://github.enterprise.com
-    </span>
-  </div>
-  <div
-    className="display-flex-row spacer-bottom"
-  >
-    <div
-      className="huge-spacer-right"
-    >
-      <Tooltip
-        overlay="settings.almintegration.feature.status_reporting.description_pr_and_commits"
-      >
-        <span>
-          settings.almintegration.feature.status_reporting.title
-        </span>
-      </Tooltip>
-      <div
-        className="display-inline-flex-center"
-      >
-        <strong
-          className="spacer-left"
-        >
-          settings.almintegration.feature.pr_decoration.disabled
-        </strong>
-        <HelpTooltip
-          className="little-spacer-left"
-          overlay={
-            <FormattedMessage
-              defaultMessage="settings.almintegration.feature.pr_decoration.disabled.no_branches"
-              id="settings.almintegration.feature.pr_decoration.disabled.no_branches"
-              values={
-                {
-                  "link": <a
-                    href="https://www.sonarsource.com/plans-and-pricing/developer/?sourceEdition=community"
-                    rel="noopener noreferrer"
-                    target="_blank"
-                  >
-                    settings.almintegration.feature.pr_decoration.disabled.no_branches.link
-                  </a>,
-                }
-              }
-            />
-          }
-        />
-      </div>
-    </div>
-    <div>
-      <Tooltip
-        overlay="settings.almintegration.feature.alm_repo_import.description"
-      >
-        <span>
-          settings.almintegration.feature.alm_repo_import.title
-        </span>
-      </Tooltip>
-      <AlertSuccessIcon
-        className="spacer-left"
-      />
-    </div>
-  </div>
-  <div
-    className="width-50"
-  >
-    <Alert
-      variant="success"
-    >
-      settings.almintegration.configuration_valid
-    </Alert>
-    <Alert
-      variant="warning"
-    >
-      <FormattedMessage
-        defaultMessage="settings.almintegration.github.additional_permission"
-        id="settings.almintegration.github.additional_permission"
-        values={
-          {
-            "link": <withAppStateContext(DocLink)
-              to="/devops-platform-integration/github-integration/"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-          }
-        }
-      />
-    </Alert>
-  </div>
-  <Button
-    className="big-spacer-top"
-    onClick={[Function]}
-  >
-    settings.almintegration.check_configuration
-  </Button>
-</div>
-`;
-
-exports[`should render correctly: warning 1`] = `
-<div
-  className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
->
-  <div
-    className="actions pull-right"
-  >
-    <Button
-      onClick={[Function]}
-    >
-      <EditIcon
-        className="spacer-right"
-      />
-      edit
-    </Button>
-    <Button
-      className="button-red spacer-left"
-      onClick={[Function]}
-    >
-      <DeleteIcon
-        className="spacer-right"
-      />
-      delete
-    </Button>
-  </div>
-  <div
-    className="big-spacer-bottom"
-  >
-    <h3>
-      key
-    </h3>
-    <span>
-      http://github.enterprise.com
-    </span>
-  </div>
-  <div
-    className="width-50"
-  >
-    <Alert
-      variant="warning"
-    >
-      settings.almintegration.could_not_validate
-    </Alert>
-  </div>
-  <Button
-    className="big-spacer-top"
-    onClick={[Function]}
-  >
-    settings.almintegration.check_configuration
-  </Button>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionForm-test.tsx.snap
deleted file mode 100644 (file)
index f086eb3..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: create 1`] = `
-<AlmBindingDefinitionFormRenderer
-  alm="github"
-  canSubmit={false}
-  formData={
-    {
-      "appId": "",
-      "clientId": "",
-      "clientSecret": "",
-      "key": "",
-      "privateKey": "",
-      "url": "",
-      "webhookSecret": "",
-    }
-  }
-  isUpdate={false}
-  onBitbucketVariantChange={[Function]}
-  onCancel={[Function]}
-  onFieldChange={[Function]}
-  onSubmit={[Function]}
-  submitting={false}
-/>
-`;
-
-exports[`should render correctly: edit 1`] = `
-<AlmBindingDefinitionFormRenderer
-  alm="github"
-  canSubmit={false}
-  formData={
-    {
-      "appId": "123456",
-      "clientId": "client1",
-      "clientSecret": "**clientsecret**",
-      "key": "key",
-      "privateKey": "asdf1234",
-      "url": "http://github.enterprise.com",
-      "webhookSecret": "verySecretText!!",
-    }
-  }
-  isUpdate={true}
-  onBitbucketVariantChange={[Function]}
-  onCancel={[Function]}
-  onFieldChange={[Function]}
-  onSubmit={[Function]}
-  submitting={false}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormField-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormField-test.tsx.snap
deleted file mode 100644 (file)
index 2119386..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<div
-  className="settings-definition"
->
-  <div
-    className="settings-definition-left"
-  >
-    <label
-      className="h3"
-      htmlFor="key"
-    >
-      settings.almintegration.form.key
-    </label>
-    <MandatoryFieldMarker />
-  </div>
-  <div
-    className="settings-definition-right big-padded-top display-flex-column"
-  >
-    <ValidationInput
-      errorPlacement={1}
-      isInvalid={false}
-      isValid={false}
-    >
-      <input
-        className="width-100"
-        id="key"
-        maxLength={40}
-        name="key"
-        onChange={[Function]}
-        size={50}
-        type="text"
-        value="key"
-      />
-    </ValidationInput>
-  </div>
-</div>
-`;
-
-exports[`should render correctly: encryptable 1`] = `
-<div
-  className="settings-definition"
->
-  <div
-    className="settings-definition-left"
-  >
-    <label
-      className="h3"
-      htmlFor="key"
-    >
-      settings.almintegration.form.key
-    </label>
-    <MandatoryFieldMarker />
-  </div>
-  <div
-    className="settings-definition-right big-padded-top display-flex-column"
-  >
-    <ValidationInput
-      errorPlacement={1}
-      isInvalid={false}
-      isValid={false}
-    >
-      <input
-        className="width-100"
-        id="key"
-        maxLength={40}
-        name="key"
-        onChange={[Function]}
-        size={50}
-        type="text"
-        value="key"
-      />
-    </ValidationInput>
-    <Alert
-      className="spacer-top"
-      variant="info"
-    >
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.secret.can_encrypt"
-        id="settings.almintegration.form.secret.can_encrypt"
-        values={
-          {
-            "learn_more": <withAppStateContext(DocLink)
-              to="/instance-administration/security/#settings-encryption"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-          }
-        }
-      />
-    </Alert>
-  </div>
-</div>
-`;
-
-exports[`should render correctly: invalid with error 1`] = `
-<div
-  className="settings-definition"
->
-  <div
-    className="settings-definition-left"
-  >
-    <label
-      className="h3"
-      htmlFor="key"
-    >
-      settings.almintegration.form.key
-    </label>
-    <MandatoryFieldMarker />
-  </div>
-  <div
-    className="settings-definition-right big-padded-top display-flex-column"
-  >
-    <ValidationInput
-      error="some error message"
-      errorPlacement={1}
-      isInvalid={true}
-      isValid={false}
-    >
-      <input
-        className="width-100"
-        id="key"
-        maxLength={40}
-        name="key"
-        onChange={[Function]}
-        size={50}
-        type="text"
-        value="key"
-      />
-    </ValidationInput>
-  </div>
-</div>
-`;
-
-exports[`should render correctly: optional 1`] = `
-<div
-  className="settings-definition"
->
-  <div
-    className="settings-definition-left"
-  >
-    <label
-      className="h3"
-      htmlFor="key"
-    >
-      settings.almintegration.form.key
-    </label>
-  </div>
-  <div
-    className="settings-definition-right big-padded-top display-flex-column"
-  >
-    <ValidationInput
-      errorPlacement={1}
-      isInvalid={false}
-      isValid={false}
-    >
-      <input
-        className="width-100"
-        id="key"
-        maxLength={40}
-        name="key"
-        onChange={[Function]}
-        size={50}
-        type="text"
-        value="key"
-      />
-    </ValidationInput>
-  </div>
-</div>
-`;
-
-exports[`should render correctly: secret 1`] = `
-<div
-  className="settings-definition"
->
-  <div
-    className="settings-definition-left"
-  >
-    <label
-      className="h3"
-      htmlFor="key"
-    >
-      settings.almintegration.form.key
-    </label>
-    <MandatoryFieldMarker />
-  </div>
-  <div
-    className="settings-definition-right big-padded-top display-flex-column"
-  >
-    <div>
-      <p>
-        settings.almintegration.form.secret.field
-      </p>
-      <ButtonLink
-        onClick={[Function]}
-      >
-        settings.almintegration.form.secret.update_field
-      </ButtonLink>
-    </div>
-  </div>
-</div>
-`;
-
-exports[`should render correctly: textarea 1`] = `
-<div
-  className="settings-definition"
->
-  <div
-    className="settings-definition-left"
-  >
-    <label
-      className="h3"
-      htmlFor="key"
-    >
-      settings.almintegration.form.key
-    </label>
-    <MandatoryFieldMarker />
-  </div>
-  <div
-    className="settings-definition-right big-padded-top display-flex-column"
-  >
-    <textarea
-      className="width-100"
-      id="key"
-      maxLength={40}
-      onChange={[Function]}
-      required={true}
-      rows={5}
-      value="key"
-    />
-  </div>
-</div>
-`;
-
-exports[`should render correctly: with help 1`] = `
-<div
-  className="settings-definition"
->
-  <div
-    className="settings-definition-left"
-  >
-    <label
-      className="h3"
-      htmlFor="key"
-    >
-      settings.almintegration.form.key
-    </label>
-    <MandatoryFieldMarker />
-    <div
-      className="markdown small spacer-top"
-    >
-      help
-    </div>
-  </div>
-  <div
-    className="settings-definition-right big-padded-top display-flex-column"
-  >
-    <ValidationInput
-      errorPlacement={1}
-      isInvalid={false}
-      isValid={false}
-    >
-      <input
-        className="width-100"
-        id="key"
-        maxLength={40}
-        name="key"
-        onChange={[Function]}
-        size={50}
-        type="text"
-        value="key"
-      />
-    </ValidationInput>
-  </div>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmBindingDefinitionFormRenderer-test.tsx.snap
deleted file mode 100644 (file)
index 16e3977..0000000
+++ /dev/null
@@ -1,484 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.create"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.create
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <GithubForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        onFieldChange={[MockFunction]}
-      />
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={false}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
-
-exports[`should render correctly for azure 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.create"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.create
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <AzureForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        onFieldChange={[MockFunction]}
-      />
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={false}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
-
-exports[`should render correctly for bitbucket 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.create"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.create
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <BitbucketForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        isUpdate={false}
-        onFieldChange={[MockFunction]}
-        onVariantChange={[MockFunction]}
-        variant="bitbucket"
-      />
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={false}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
-
-exports[`should render correctly for github 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.create"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.create
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <GithubForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        onFieldChange={[MockFunction]}
-      />
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={false}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
-
-exports[`should render correctly for gitlab 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.create"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.create
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <GitlabForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        onFieldChange={[MockFunction]}
-      />
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={false}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
-
-exports[`should render correctly: editing 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.edit"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.edit
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <GithubForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        onFieldChange={[MockFunction]}
-      />
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={false}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
-
-exports[`should render correctly: submitting 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.create"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.create
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <GithubForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        onFieldChange={[MockFunction]}
-      />
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={true}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
-
-exports[`should render correctly: with validation error 1`] = `
-<Modal
-  contentLabel="settings.almintegration.form.header.create"
-  onRequestClose={[MockFunction]}
-  shouldCloseOnOverlayClick={false}
-  size="medium"
->
-  <form
-    className="views-form"
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-head"
-    >
-      <h2>
-        settings.almintegration.form.header.create
-      </h2>
-    </div>
-    <div
-      className="modal-body modal-container"
-    >
-      <GithubForm
-        formData={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        onFieldChange={[MockFunction]}
-      />
-      <Alert
-        variant="error"
-      >
-        <p
-          className="spacer-bottom"
-        >
-          settings.almintegration.configuration_invalid
-        </p>
-        <ul
-          className="list-styled"
-        >
-          <li>
-            this is a validation error
-          </li>
-        </ul>
-      </Alert>
-    </div>
-    <div
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={true}
-      >
-        settings.almintegration.form.save
-        <DeferredSpinner
-          className="spacer-left"
-          loading={false}
-        />
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </div>
-  </form>
-</Modal>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegration-test.tsx.snap
deleted file mode 100644 (file)
index 6833ad1..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<AlmIntegrationRenderer
-  branchesEnabled={true}
-  currentAlmTab="github"
-  definitionStatus={{}}
-  definitions={
-    {
-      "azure": [],
-      "bitbucket": [],
-      "bitbucketcloud": [],
-      "github": [],
-      "gitlab": [],
-    }
-  }
-  loadingAlmDefinitions={true}
-  loadingProjectCount={false}
-  multipleAlmEnabled={true}
-  onCancelDelete={[Function]}
-  onCheckConfiguration={[Function]}
-  onConfirmDelete={[Function]}
-  onDelete={[Function]}
-  onSelectAlmTab={[Function]}
-  onUpdateDefinitions={[Function]}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmIntegrationRenderer-test.tsx.snap
deleted file mode 100644 (file)
index f90ed60..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: azure 1`] = `
-<Fragment>
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      settings.almintegration.title
-    </h1>
-  </header>
-  <div
-    className="markdown small spacer-top big-spacer-bottom"
-  >
-    settings.almintegration.description
-  </div>
-  <BoxedTabs
-    onSelect={[MockFunction]}
-    selected="azure"
-    tabs={
-      [
-        {
-          "key": "github",
-          "label": <React.Fragment>
-            <img
-              alt="github"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/github.svg"
-            />
-            GitHub
-          </React.Fragment>,
-        },
-        {
-          "key": "bitbucket",
-          "label": <React.Fragment>
-            <img
-              alt="bitbucket"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/bitbucket.svg"
-            />
-            Bitbucket
-          </React.Fragment>,
-        },
-        {
-          "key": "azure",
-          "label": <React.Fragment>
-            <img
-              alt="azure"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/azure.svg"
-            />
-            Azure DevOps
-          </React.Fragment>,
-        },
-        {
-          "key": "gitlab",
-          "label": <React.Fragment>
-            <img
-              alt="gitlab"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/gitlab.svg"
-            />
-            GitLab
-          </React.Fragment>,
-        },
-      ]
-    }
-  />
-  <AlmTab
-    almTab="azure"
-    branchesEnabled={true}
-    definitionStatus={{}}
-    definitions={[]}
-    loadingAlmDefinitions={false}
-    loadingProjectCount={false}
-    multipleAlmEnabled={false}
-    onCheck={[MockFunction]}
-    onDelete={[MockFunction]}
-    onUpdateDefinitions={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: bitbucket 1`] = `
-<Fragment>
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      settings.almintegration.title
-    </h1>
-  </header>
-  <div
-    className="markdown small spacer-top big-spacer-bottom"
-  >
-    settings.almintegration.description
-  </div>
-  <BoxedTabs
-    onSelect={[MockFunction]}
-    selected="bitbucket"
-    tabs={
-      [
-        {
-          "key": "github",
-          "label": <React.Fragment>
-            <img
-              alt="github"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/github.svg"
-            />
-            GitHub
-          </React.Fragment>,
-        },
-        {
-          "key": "bitbucket",
-          "label": <React.Fragment>
-            <img
-              alt="bitbucket"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/bitbucket.svg"
-            />
-            Bitbucket
-          </React.Fragment>,
-        },
-        {
-          "key": "azure",
-          "label": <React.Fragment>
-            <img
-              alt="azure"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/azure.svg"
-            />
-            Azure DevOps
-          </React.Fragment>,
-        },
-        {
-          "key": "gitlab",
-          "label": <React.Fragment>
-            <img
-              alt="gitlab"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/gitlab.svg"
-            />
-            GitLab
-          </React.Fragment>,
-        },
-      ]
-    }
-  />
-  <AlmTab
-    almTab="bitbucket"
-    branchesEnabled={true}
-    definitionStatus={{}}
-    definitions={[]}
-    loadingAlmDefinitions={false}
-    loadingProjectCount={false}
-    multipleAlmEnabled={false}
-    onCheck={[MockFunction]}
-    onDelete={[MockFunction]}
-    onUpdateDefinitions={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: default 1`] = `
-<Fragment>
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      settings.almintegration.title
-    </h1>
-  </header>
-  <div
-    className="markdown small spacer-top big-spacer-bottom"
-  >
-    settings.almintegration.description
-  </div>
-  <BoxedTabs
-    onSelect={[MockFunction]}
-    selected="github"
-    tabs={
-      [
-        {
-          "key": "github",
-          "label": <React.Fragment>
-            <img
-              alt="github"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/github.svg"
-            />
-            GitHub
-          </React.Fragment>,
-        },
-        {
-          "key": "bitbucket",
-          "label": <React.Fragment>
-            <img
-              alt="bitbucket"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/bitbucket.svg"
-            />
-            Bitbucket
-          </React.Fragment>,
-        },
-        {
-          "key": "azure",
-          "label": <React.Fragment>
-            <img
-              alt="azure"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/azure.svg"
-            />
-            Azure DevOps
-          </React.Fragment>,
-        },
-        {
-          "key": "gitlab",
-          "label": <React.Fragment>
-            <img
-              alt="gitlab"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/gitlab.svg"
-            />
-            GitLab
-          </React.Fragment>,
-        },
-      ]
-    }
-  />
-  <AlmTab
-    almTab="github"
-    branchesEnabled={true}
-    definitionStatus={{}}
-    definitions={[]}
-    loadingAlmDefinitions={false}
-    loadingProjectCount={false}
-    multipleAlmEnabled={false}
-    onCheck={[MockFunction]}
-    onDelete={[MockFunction]}
-    onUpdateDefinitions={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: delete modal 1`] = `
-<Fragment>
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      settings.almintegration.title
-    </h1>
-  </header>
-  <div
-    className="markdown small spacer-top big-spacer-bottom"
-  >
-    settings.almintegration.description
-  </div>
-  <BoxedTabs
-    onSelect={[MockFunction]}
-    selected="github"
-    tabs={
-      [
-        {
-          "key": "github",
-          "label": <React.Fragment>
-            <img
-              alt="github"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/github.svg"
-            />
-            GitHub
-          </React.Fragment>,
-        },
-        {
-          "key": "bitbucket",
-          "label": <React.Fragment>
-            <img
-              alt="bitbucket"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/bitbucket.svg"
-            />
-            Bitbucket
-          </React.Fragment>,
-        },
-        {
-          "key": "azure",
-          "label": <React.Fragment>
-            <img
-              alt="azure"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/azure.svg"
-            />
-            Azure DevOps
-          </React.Fragment>,
-        },
-        {
-          "key": "gitlab",
-          "label": <React.Fragment>
-            <img
-              alt="gitlab"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/gitlab.svg"
-            />
-            GitLab
-          </React.Fragment>,
-        },
-      ]
-    }
-  />
-  <AlmTab
-    almTab="github"
-    branchesEnabled={true}
-    definitionStatus={{}}
-    definitions={[]}
-    loadingAlmDefinitions={false}
-    loadingProjectCount={false}
-    multipleAlmEnabled={false}
-    onCheck={[MockFunction]}
-    onDelete={[MockFunction]}
-    onUpdateDefinitions={[MockFunction]}
-  />
-  <DeleteModal
-    id="keyToDelete"
-    onCancel={[MockFunction]}
-    onDelete={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: gitlab 1`] = `
-<Fragment>
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      settings.almintegration.title
-    </h1>
-  </header>
-  <div
-    className="markdown small spacer-top big-spacer-bottom"
-  >
-    settings.almintegration.description
-  </div>
-  <BoxedTabs
-    onSelect={[MockFunction]}
-    selected="gitlab"
-    tabs={
-      [
-        {
-          "key": "github",
-          "label": <React.Fragment>
-            <img
-              alt="github"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/github.svg"
-            />
-            GitHub
-          </React.Fragment>,
-        },
-        {
-          "key": "bitbucket",
-          "label": <React.Fragment>
-            <img
-              alt="bitbucket"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/bitbucket.svg"
-            />
-            Bitbucket
-          </React.Fragment>,
-        },
-        {
-          "key": "azure",
-          "label": <React.Fragment>
-            <img
-              alt="azure"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/azure.svg"
-            />
-            Azure DevOps
-          </React.Fragment>,
-        },
-        {
-          "key": "gitlab",
-          "label": <React.Fragment>
-            <img
-              alt="gitlab"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/gitlab.svg"
-            />
-            GitLab
-          </React.Fragment>,
-        },
-      ]
-    }
-  />
-  <AlmTab
-    almTab="gitlab"
-    branchesEnabled={true}
-    definitionStatus={{}}
-    definitions={[]}
-    loadingAlmDefinitions={false}
-    loadingProjectCount={false}
-    multipleAlmEnabled={false}
-    onCheck={[MockFunction]}
-    onDelete={[MockFunction]}
-    onUpdateDefinitions={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: loading 1`] = `
-<Fragment>
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      settings.almintegration.title
-    </h1>
-  </header>
-  <div
-    className="markdown small spacer-top big-spacer-bottom"
-  >
-    settings.almintegration.description
-  </div>
-  <BoxedTabs
-    onSelect={[MockFunction]}
-    selected="github"
-    tabs={
-      [
-        {
-          "key": "github",
-          "label": <React.Fragment>
-            <img
-              alt="github"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/github.svg"
-            />
-            GitHub
-          </React.Fragment>,
-        },
-        {
-          "key": "bitbucket",
-          "label": <React.Fragment>
-            <img
-              alt="bitbucket"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/bitbucket.svg"
-            />
-            Bitbucket
-          </React.Fragment>,
-        },
-        {
-          "key": "azure",
-          "label": <React.Fragment>
-            <img
-              alt="azure"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/azure.svg"
-            />
-            Azure DevOps
-          </React.Fragment>,
-        },
-        {
-          "key": "gitlab",
-          "label": <React.Fragment>
-            <img
-              alt="gitlab"
-              className="spacer-right"
-              height={16}
-              src="/images/alm/gitlab.svg"
-            />
-            GitLab
-          </React.Fragment>,
-        },
-      ]
-    }
-  />
-  <AlmTab
-    almTab="github"
-    branchesEnabled={true}
-    definitionStatus={{}}
-    definitions={[]}
-    loadingAlmDefinitions={true}
-    loadingProjectCount={true}
-    multipleAlmEnabled={false}
-    onCheck={[MockFunction]}
-    onDelete={[MockFunction]}
-    onUpdateDefinitions={[MockFunction]}
-  />
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTab-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTab-test.tsx.snap
deleted file mode 100644 (file)
index 97725f0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<AlmTabRenderer
-  afterSubmit={[Function]}
-  almTab="azure"
-  branchesEnabled={true}
-  definitionStatus={{}}
-  definitions={
-    [
-      {
-        "key": "key",
-        "personalAccessToken": "asdf1234",
-      },
-    ]
-  }
-  loadingAlmDefinitions={false}
-  loadingProjectCount={false}
-  multipleAlmEnabled={true}
-  onCancel={[Function]}
-  onCheck={[MockFunction]}
-  onCreate={[Function]}
-  onDelete={[MockFunction]}
-  onEdit={[Function]}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AlmTabRenderer-test.tsx.snap
deleted file mode 100644 (file)
index 209cc55..0000000
+++ /dev/null
@@ -1,594 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly for multi-ALM binding: editing a definition 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "key": "key",
-            "personalAccessToken": "asdf1234",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly for multi-ALM binding: loaded 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "key": "key",
-            "personalAccessToken": "asdf1234",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly for multi-ALM binding: loading ALM definitions 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={true}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "key": "key",
-            "personalAccessToken": "asdf1234",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly for multi-ALM binding: loading project count 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={true}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={true}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "key": "key",
-            "personalAccessToken": "asdf1234",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly for single-ALM binding 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={true}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={true}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={true}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "key": "key",
-            "personalAccessToken": "asdf1234",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly for single-ALM binding 2`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={true}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={true}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "key": "key",
-            "personalAccessToken": "asdf1234",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly for single-ALM binding 3`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={true}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={true}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "key": "key",
-            "personalAccessToken": "asdf1234",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly with validation: create a first 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <p
-        className="spacer-top"
-      >
-        settings.almintegration.empty.azure
-      </p>
-      <div
-        className="big-spacer-top"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly with validation: create a second 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly with validation: default 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="azure"
-        branchesEnabled={true}
-        definition={
-          {
-            "appId": "123456",
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "privateKey": "asdf1234",
-            "url": "http://github.enterprise.com",
-            "webhookSecret": "verySecretText!!",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly with validation: empty 1`] = `
-<div
-  aria-labelledby="tab-azure"
-  className="bordered"
-  id="tabpanel-azure"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <p
-        className="spacer-top"
-      >
-        settings.almintegration.empty.azure
-      </p>
-      <div
-        className="big-spacer-top"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="azure"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-    </DeferredSpinner>
-  </div>
-</div>
-`;
-
-exports[`should render correctly with validation: pass the correct key for bitbucket cloud 1`] = `
-<div
-  aria-labelledby="tab-bitbucket"
-  className="bordered"
-  id="tabpanel-bitbucket"
-  role="tabpanel"
->
-  <div
-    className="big-padded"
-  >
-    <DeferredSpinner
-      loading={false}
-    >
-      <div
-        className="spacer-bottom text-right"
-      >
-        <withAppStateContext(CreationTooltip)
-          alm="bitbucket"
-          preventCreation={false}
-        >
-          <Button
-            data-test="settings__alm-create"
-            disabled={false}
-            onClick={[MockFunction]}
-          >
-            settings.almintegration.create
-          </Button>
-        </withAppStateContext(CreationTooltip)>
-      </div>
-      <AlmBindingDefinitionBox
-        alm="bitbucketcloud"
-        branchesEnabled={true}
-        definition={
-          {
-            "clientId": "client1",
-            "clientSecret": "**clientsecret**",
-            "key": "key",
-            "workspace": "workspace",
-          }
-        }
-        key="key"
-        onCheck={[MockFunction]}
-        onDelete={[MockFunction]}
-        onEdit={[MockFunction]}
-      />
-    </DeferredSpinner>
-  </div>
-  <Alert
-    className="spacer"
-    variant="info"
-  >
-    <FormattedMessage
-      defaultMessage="settings.almintegration.tabs.authentication_moved"
-      id="settings.almintegration.tabs.authentication-moved"
-      values={
-        {
-          "link": <ForwardRef(Link)
-            to={
-              {
-                "pathname": "/admin/settings",
-                "search": "category=authentication&tab=bitbucket",
-              }
-            }
-          >
-            property.category.authentication
-          </ForwardRef(Link)>,
-        }
-      }
-    />
-  </Alert>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/AzureForm-test.tsx.snap
deleted file mode 100644 (file)
index c2c39f8..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: create 1`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.azure.help"
-    id="name.azure"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <React.Fragment>
-        settings.almintegration.form.url.azure.help1
-        <br />
-        <em>
-          https://ado.your-company.com/your_collection
-        </em>
-        <br />
-        <br />
-        settings.almintegration.form.url.azure.help2
-        <br />
-        <em>
-          https://dev.azure.com/your_organization
-        </em>
-      </React.Fragment>
-    }
-    id="url.azure"
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    propKey="url"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.personal_access_token.azure.help"
-        id="settings.almintegration.form.personal_access_token.azure.help"
-        values={
-          {
-            "doc_link": <withAppStateContext(DocLink)
-              to="/devops-platform-integration/azure-devops-integration/"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-            "pat": <ForwardRef(Link)
-              target="_blank"
-              to="https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate"
-            >
-              settings.almintegration.form.personal_access_token.azure.help.url
-            </ForwardRef(Link)>,
-            "permission": <strong>
-              Code &gt; Read & Write
-            </strong>,
-          }
-        }
-      />
-    }
-    id="personal_access_token"
-    isSecret={true}
-    isTextArea={true}
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={false}
-    propKey="personalAccessToken"
-    value=""
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: edit 1`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.azure.help"
-    id="name.azure"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value="key"
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <React.Fragment>
-        settings.almintegration.form.url.azure.help1
-        <br />
-        <em>
-          https://ado.your-company.com/your_collection
-        </em>
-        <br />
-        <br />
-        settings.almintegration.form.url.azure.help2
-        <br />
-        <em>
-          https://dev.azure.com/your_organization
-        </em>
-      </React.Fragment>
-    }
-    id="url.azure"
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    propKey="url"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.personal_access_token.azure.help"
-        id="settings.almintegration.form.personal_access_token.azure.help"
-        values={
-          {
-            "doc_link": <withAppStateContext(DocLink)
-              to="/devops-platform-integration/azure-devops-integration/"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-            "pat": <ForwardRef(Link)
-              target="_blank"
-              to="https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate"
-            >
-              settings.almintegration.form.personal_access_token.azure.help.url
-            </ForwardRef(Link)>,
-            "permission": <strong>
-              Code &gt; Read & Write
-            </strong>,
-          }
-        }
-      />
-    }
-    id="personal_access_token"
-    isSecret={true}
-    isTextArea={true}
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={true}
-    propKey="personalAccessToken"
-    value="asdf1234"
-  />
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketCloudForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketCloudForm-test.tsx.snap
deleted file mode 100644 (file)
index fd82e19..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.bitbucketcloud.help"
-    id="name.bitbucket"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value="key"
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.workspace.bitbucketcloud.help"
-        id="settings.almintegration.form.workspace.bitbucketcloud.help"
-        values={
-          {
-            "example": <React.Fragment>
-              https://bitbucket.org/
-              <strong>
-                {workspace}
-              </strong>
-              /{repository}
-            </React.Fragment>,
-          }
-        }
-      />
-    }
-    id="workspace.bitbucketcloud"
-    isInvalid={false}
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="workspace"
-    value="workspace"
-  />
-  <Alert
-    className="big-spacer-top"
-    variant="info"
-  >
-    <FormattedMessage
-      defaultMessage="settings.almintegration.bitbucketcloud.info"
-      id="settings.almintegration.bitbucketcloud.info"
-      values={
-        {
-          "doc_link": <withAppStateContext(DocLink)
-            to="/devops-platform-integration/bitbucket-integration/bitbucket-cloud-integration/"
-          >
-            learn_more
-          </withAppStateContext(DocLink)>,
-          "oauth": <ForwardRef(Link)
-            target="_blank"
-            to="https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/"
-          >
-            settings.almintegration.bitbucketcloud.oauth
-          </ForwardRef(Link)>,
-          "permission": <strong>
-            Pull Requests: Read
-          </strong>,
-        }
-      }
-    />
-  </Alert>
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.oauth_key.bitbucketcloud.help"
-    id="client_id.bitbucketcloud"
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="clientId"
-    value="client1"
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.oauth_secret.bitbucketcloud.help"
-    id="client_secret.bitbucketcloud"
-    isSecret={true}
-    maxLength={160}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={true}
-    propKey="clientSecret"
-    value="**clientsecret**"
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: invalid workspace ID 1`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.bitbucketcloud.help"
-    id="name.bitbucket"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value="key"
-  />
-  <AlmBindingDefinitionFormField
-    error="settings.almintegration.form.workspace.bitbucketcloud.error"
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.workspace.bitbucketcloud.help"
-        id="settings.almintegration.form.workspace.bitbucketcloud.help"
-        values={
-          {
-            "example": <React.Fragment>
-              https://bitbucket.org/
-              <strong>
-                {workspace}
-              </strong>
-              /{repository}
-            </React.Fragment>,
-          }
-        }
-      />
-    }
-    id="workspace.bitbucketcloud"
-    isInvalid={true}
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="workspace"
-    value="my/workspace"
-  />
-  <Alert
-    className="big-spacer-top"
-    variant="info"
-  >
-    <FormattedMessage
-      defaultMessage="settings.almintegration.bitbucketcloud.info"
-      id="settings.almintegration.bitbucketcloud.info"
-      values={
-        {
-          "doc_link": <withAppStateContext(DocLink)
-            to="/devops-platform-integration/bitbucket-integration/bitbucket-cloud-integration/"
-          >
-            learn_more
-          </withAppStateContext(DocLink)>,
-          "oauth": <ForwardRef(Link)
-            target="_blank"
-            to="https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/"
-          >
-            settings.almintegration.bitbucketcloud.oauth
-          </ForwardRef(Link)>,
-          "permission": <strong>
-            Pull Requests: Read
-          </strong>,
-        }
-      }
-    />
-  </Alert>
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.oauth_key.bitbucketcloud.help"
-    id="client_id.bitbucketcloud"
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="clientId"
-    value="client1"
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.oauth_secret.bitbucketcloud.help"
-    id="client_secret.bitbucketcloud"
-    isSecret={true}
-    maxLength={160}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={true}
-    propKey="clientSecret"
-    value="**clientsecret**"
-  />
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketForm-test.tsx.snap
deleted file mode 100644 (file)
index 37f52f7..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: bbc 1`] = `
-<Fragment>
-  <div
-    className="display-flex-column"
-  >
-    <strong>
-      settings.almintegration.form.choose_bitbucket_variant
-    </strong>
-    <div
-      className="little-spacer-top big-spacer-bottom"
-    >
-      <ButtonToggle
-        label="settings.almintegration.form.choose_bitbucket_variant"
-        onCheck={[MockFunction]}
-        options={
-          [
-            {
-              "label": "Bitbucket Server",
-              "value": "bitbucket",
-            },
-            {
-              "label": "Bitbucket Cloud",
-              "value": "bitbucketcloud",
-            },
-          ]
-        }
-        value="bitbucketcloud"
-      />
-    </div>
-  </div>
-  <BitbucketCloudForm
-    formData={
-      {
-        "clientId": "client1",
-        "clientSecret": "**clientsecret**",
-        "key": "key",
-        "workspace": "workspace",
-      }
-    }
-    onFieldChange={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: bbs 1`] = `
-<Fragment>
-  <div
-    className="display-flex-column"
-  >
-    <strong>
-      settings.almintegration.form.choose_bitbucket_variant
-    </strong>
-    <div
-      className="little-spacer-top big-spacer-bottom"
-    >
-      <ButtonToggle
-        label="settings.almintegration.form.choose_bitbucket_variant"
-        onCheck={[MockFunction]}
-        options={
-          [
-            {
-              "label": "Bitbucket Server",
-              "value": "bitbucket",
-            },
-            {
-              "label": "Bitbucket Cloud",
-              "value": "bitbucketcloud",
-            },
-          ]
-        }
-        value="bitbucket"
-      />
-    </div>
-  </div>
-  <BitbucketServerForm
-    formData={
-      {
-        "key": "key",
-        "personalAccessToken": "asdf1234",
-        "url": "http://bbs.enterprise.com",
-      }
-    }
-    onFieldChange={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: update bbc 1`] = `
-<Fragment>
-  <BitbucketCloudForm
-    formData={
-      {
-        "clientId": "client1",
-        "clientSecret": "**clientsecret**",
-        "key": "key",
-        "workspace": "workspace",
-      }
-    }
-    onFieldChange={[MockFunction]}
-  />
-</Fragment>
-`;
-
-exports[`should render correctly: update bbs 1`] = `
-<Fragment>
-  <BitbucketServerForm
-    formData={
-      {
-        "key": "key",
-        "personalAccessToken": "asdf1234",
-        "url": "http://bbs.enterprise.com",
-      }
-    }
-    onFieldChange={[MockFunction]}
-  />
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketServerForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/BitbucketServerForm-test.tsx.snap
deleted file mode 100644 (file)
index c937fdb..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.bitbucket.help"
-    id="name.bitbucket"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value="key"
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.url.bitbucket.help"
-        id="settings.almintegration.form.url.bitbucket.help"
-        values={
-          {
-            "example": "https://bitbucket-server.your-company.com",
-          }
-        }
-      />
-    }
-    id="url.bitbucket"
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    propKey="url"
-    value="http://bbs.enterprise.com"
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.personal_access_token.bitbucket.help"
-        id="settings.almintegration.form.personal_access_token.bitbucket.help"
-        values={
-          {
-            "doc_link": <withAppStateContext(DocLink)
-              to="/devops-platform-integration/bitbucket-integration/bitbucket-server-integration/"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-            "pat": <ForwardRef(Link)
-              target="_blank"
-              to="https://confluence.atlassian.com/bitbucketserver0515/personal-access-tokens-961275199.html"
-            >
-              settings.almintegration.form.personal_access_token.bitbucket.help.url
-            </ForwardRef(Link)>,
-            "permission": <strong>
-              Read
-            </strong>,
-          }
-        }
-      />
-    }
-    id="personal_access_token"
-    isSecret={true}
-    isTextArea={true}
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={true}
-    propKey="personalAccessToken"
-    value="asdf1234"
-  />
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/CreationTooltip-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/CreationTooltip-test.tsx.snap
deleted file mode 100644 (file)
index 59011f4..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Tooltip
-  mouseLeaveDelay={0.25}
-  overlay={
-    <FormattedMessage
-      defaultMessage="settings.almintegration.create.tooltip"
-      id="settings.almintegration.create.tooltip"
-      values={
-        {
-          "alm": "alm.azure",
-          "link": <a
-            href="https://www.sonarsource.com/plans-and-pricing/enterprise/?sourceEdition=community"
-            rel="noopener noreferrer"
-            target="_blank"
-          >
-            settings.almintegration.create.tooltip.link
-          </a>,
-        }
-      }
-    />
-  }
->
-  <span>
-    Child
-  </span>
-</Tooltip>
-`;
-
-exports[`should render correctly 2`] = `
-<Tooltip
-  mouseLeaveDelay={0.25}
-  overlay={null}
->
-  <span>
-    Child
-  </span>
-</Tooltip>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/DeleteModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/DeleteModal-test.tsx.snap
deleted file mode 100644 (file)
index 48f49ab..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<ConfirmModal
-  confirmButtonText="delete"
-  confirmData="1"
-  header="settings.almintegration.delete.header"
-  isDestructive={true}
-  onClose={[MockFunction]}
-  onConfirm={[MockFunction]}
->
-  <p
-    className="spacer-bottom"
-  >
-    <FormattedMessage
-      defaultMessage="settings.almintegration.delete.message"
-      id="settings.almintegration.delete.message"
-      values={
-        {
-          "id": <b>
-            1
-          </b>,
-        }
-      }
-    />
-  </p>
-  <p>
-    settings.almintegration.delete.info.4
-     
-  </p>
-</ConfirmModal>
-`;
-
-exports[`should render correctly 2`] = `
-<ConfirmModal
-  confirmButtonText="delete"
-  confirmData="1"
-  header="settings.almintegration.delete.header"
-  isDestructive={true}
-  onClose={[MockFunction]}
-  onConfirm={[MockFunction]}
->
-  <p
-    className="spacer-bottom"
-  >
-    <FormattedMessage
-      defaultMessage="settings.almintegration.delete.message"
-      id="settings.almintegration.delete.message"
-      values={
-        {
-          "id": <b>
-            1
-          </b>,
-        }
-      }
-    />
-  </p>
-  <p>
-    settings.almintegration.delete.no_info
-  </p>
-</ConfirmModal>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GithubForm-test.tsx.snap
deleted file mode 100644 (file)
index 1abc6ba..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.github.help"
-    id="name.github"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <React.Fragment>
-        settings.almintegration.form.url.github.help1
-        <br />
-        <em>
-          https://github.company.com/api/v3
-        </em>
-        <br />
-        <br />
-        settings.almintegration.form.url.github.help2
-        <br />
-        <em>
-          https://api.github.com/
-        </em>
-      </React.Fragment>
-    }
-    id="url.github"
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    propKey="url"
-    value=""
-  />
-  <Alert
-    className="big-spacer-top"
-    variant="info"
-  >
-    <FormattedMessage
-      defaultMessage="settings.almintegration.github.info"
-      id="settings.almintegration.github.info"
-      values={
-        {
-          "link": <withAppStateContext(DocLink)
-            to="/devops-platform-integration/github-integration/"
-          >
-            learn_more
-          </withAppStateContext(DocLink)>,
-        }
-      }
-    />
-  </Alert>
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.app_id.github.help"
-    id="app_id"
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="appId"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.client_id.github.help"
-    id="client_id.github"
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="clientId"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.client_secret.github.help"
-    id="client_secret.github"
-    isSecret={true}
-    maxLength={160}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={false}
-    propKey="clientSecret"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.private_key.github.help"
-    id="private_key"
-    isSecret={true}
-    isTextArea={true}
-    maxLength={2500}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={false}
-    propKey="privateKey"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.webhook_secret.github.help"
-    id="webhook_secret.github"
-    isSecret={true}
-    maxLength={160}
-    onFieldChange={[MockFunction]}
-    optional={true}
-    overwriteOnly={false}
-    propKey="webhookSecret"
-    value=""
-  />
-</Fragment>
-`;
-
-exports[`should render correctly 2`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.github.help"
-    id="name.github"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value="key"
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <React.Fragment>
-        settings.almintegration.form.url.github.help1
-        <br />
-        <em>
-          https://github.company.com/api/v3
-        </em>
-        <br />
-        <br />
-        settings.almintegration.form.url.github.help2
-        <br />
-        <em>
-          https://api.github.com/
-        </em>
-      </React.Fragment>
-    }
-    id="url.github"
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    propKey="url"
-    value="http://github.enterprise.com"
-  />
-  <Alert
-    className="big-spacer-top"
-    variant="info"
-  >
-    <FormattedMessage
-      defaultMessage="settings.almintegration.github.info"
-      id="settings.almintegration.github.info"
-      values={
-        {
-          "link": <withAppStateContext(DocLink)
-            to="/devops-platform-integration/github-integration/"
-          >
-            learn_more
-          </withAppStateContext(DocLink)>,
-        }
-      }
-    />
-  </Alert>
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.app_id.github.help"
-    id="app_id"
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="appId"
-    value="123456"
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.client_id.github.help"
-    id="client_id.github"
-    maxLength={80}
-    onFieldChange={[MockFunction]}
-    propKey="clientId"
-    value="client1"
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.client_secret.github.help"
-    id="client_secret.github"
-    isSecret={true}
-    maxLength={160}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={true}
-    propKey="clientSecret"
-    value="**clientsecret**"
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.private_key.github.help"
-    id="private_key"
-    isSecret={true}
-    isTextArea={true}
-    maxLength={2500}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={true}
-    propKey="privateKey"
-    value="asdf1234"
-  />
-  <AlmBindingDefinitionFormField
-    help="settings.almintegration.form.webhook_secret.github.help"
-    id="webhook_secret.github"
-    isSecret={true}
-    maxLength={160}
-    onFieldChange={[MockFunction]}
-    optional={true}
-    overwriteOnly={true}
-    propKey="webhookSecret"
-    value="verySecretText!!"
-  />
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/almIntegration/__tests__/__snapshots__/GitlabForm-test.tsx.snap
deleted file mode 100644 (file)
index c7707c9..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.gitlab.help"
-    id="name.gitlab"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <React.Fragment>
-        settings.almintegration.form.url.gitlab.help
-        <br />
-        <em>
-          https://gitlab.com/api/v4
-        </em>
-      </React.Fragment>
-    }
-    id="url.gitlab"
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    propKey="url"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.personal_access_token.gitlab.help"
-        id="settings.almintegration.form.personal_access_token.gitlab.help"
-        values={
-          {
-            "doc_link": <withAppStateContext(DocLink)
-              to="/devops-platform-integration/gitlab-integration/"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-            "pat": <ForwardRef(Link)
-              target="_blank"
-              to="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html"
-            >
-              settings.almintegration.form.personal_access_token.gitlab.help.url
-            </ForwardRef(Link)>,
-            "permission": <strong>
-              Reporter
-            </strong>,
-            "scope": <strong>
-              api
-            </strong>,
-          }
-        }
-      />
-    }
-    id="personal_access_token"
-    isSecret={true}
-    isTextArea={true}
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={false}
-    propKey="personalAccessToken"
-    value=""
-  />
-</Fragment>
-`;
-
-exports[`should render correctly 2`] = `
-<Fragment>
-  <AlmBindingDefinitionFormField
-    autoFocus={true}
-    help="settings.almintegration.form.name.gitlab.help"
-    id="name.gitlab"
-    maxLength={200}
-    onFieldChange={[MockFunction]}
-    propKey="key"
-    value="foo"
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <React.Fragment>
-        settings.almintegration.form.url.gitlab.help
-        <br />
-        <em>
-          https://gitlab.com/api/v4
-        </em>
-      </React.Fragment>
-    }
-    id="url.gitlab"
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    propKey="url"
-    value=""
-  />
-  <AlmBindingDefinitionFormField
-    help={
-      <FormattedMessage
-        defaultMessage="settings.almintegration.form.personal_access_token.gitlab.help"
-        id="settings.almintegration.form.personal_access_token.gitlab.help"
-        values={
-          {
-            "doc_link": <withAppStateContext(DocLink)
-              to="/devops-platform-integration/gitlab-integration/"
-            >
-              learn_more
-            </withAppStateContext(DocLink)>,
-            "pat": <ForwardRef(Link)
-              target="_blank"
-              to="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html"
-            >
-              settings.almintegration.form.personal_access_token.gitlab.help.url
-            </ForwardRef(Link)>,
-            "permission": <strong>
-              Reporter
-            </strong>,
-            "scope": <strong>
-              api
-            </strong>,
-          }
-        }
-      />
-    }
-    id="personal_access_token"
-    isSecret={true}
-    isTextArea={true}
-    maxLength={2000}
-    onFieldChange={[MockFunction]}
-    overwriteOnly={true}
-    propKey="personalAccessToken"
-    value="foobar"
-  />
-</Fragment>
-`;
index b5ceb37de1375b41700e1767aeb2c876b3df05b3..b594853b10d2c99074e12c2f3dbd34ecce2124af 100644 (file)
@@ -107,7 +107,9 @@ export default class EncryptionForm extends React.PureComponent<Props, State> {
 
         {encryptedValue && (
           <div>
-            <span className="little-spacer-right">{translate('encryption.encrypted_value')}</span>
+            <label className="little-spacer-right" htmlFor="encrypted-value">
+              {translate('encryption.encrypted_value')}
+            </label>
             <input
               className="input-clear input-code input-super-large"
               id="encrypted-value"
index 9e833802baa8e97b9990bbd7359be71cd53a3732..92af36c8ff94539ac0346270c7ff13bb8af893c1 100644 (file)
@@ -66,8 +66,11 @@ export default class GenerateSecretKeyForm extends React.PureComponent<Props, St
         {secretKey ? (
           <>
             <div className="big-spacer-bottom">
-              <h3 className="spacer-bottom">{translate('encryption.secret_key')}</h3>
+              <h3 className="spacer-bottom" id="secret-key-title">
+                {translate('encryption.secret_key')}
+              </h3>
               <input
+                aria-labelledby="secret-key-title"
                 className="input-clear input-code input-large"
                 id="secret-key"
                 readOnly={true}
diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-it.tsx b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-it.tsx
new file mode 100644 (file)
index 0000000..e40db8f
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 userEvent from '@testing-library/user-event';
+import React from 'react';
+import { byRole } from 'testing-library-selector';
+import SettingsServiceMock from '../../../../api/mocks/SettingsServiceMock';
+import { renderComponent } from '../../../../helpers/testReactTestingUtils';
+import EncryptionApp from '../EncryptionApp';
+
+jest.mock('../../../../api/settings');
+
+let settingsMock: SettingsServiceMock;
+
+beforeAll(() => {
+  settingsMock = new SettingsServiceMock();
+});
+
+afterEach(() => {
+  settingsMock.reset();
+});
+
+const ui = {
+  appHeading: byRole('heading', { name: 'property.category.security.encryption' }),
+  generateSecretButton: byRole('button', { name: 'encryption.generate_secret_key' }),
+  secretKeyHeading: byRole('heading', { name: 'encryption.secret_key' }),
+  copyToClipboard: byRole('button', { name: 'copy_to_clipboard' }),
+  encryptTextarea: byRole('textbox'),
+  encryptButton: byRole('button', { name: 'encryption.encrypt' }),
+  generateNewSecretButton: byRole('button', { name: 'encryption.generate_new_secret_key' }),
+};
+
+it('should be able to generate new key', async () => {
+  renderEncryptionApp();
+
+  expect(await ui.appHeading.find()).toBeInTheDocument();
+  await userEvent.click(ui.generateSecretButton.get());
+  expect(ui.copyToClipboard.get()).toHaveAttribute('data-clipboard-text', 'secretKey');
+});
+
+it('should be able to encrypt property value when secret is registered', async () => {
+  settingsMock.setSecretKeyAvailable(true);
+  renderEncryptionApp();
+
+  expect(await ui.appHeading.find()).toBeInTheDocument();
+  await userEvent.type(ui.encryptTextarea.get(), 'sonar.announcement.message');
+  await userEvent.click(ui.encryptButton.get());
+  expect(ui.copyToClipboard.get()).toHaveAttribute('data-clipboard-text', 'encryptedValue');
+
+  // can generate new secret in view
+  await userEvent.click(ui.generateNewSecretButton.get());
+  expect(ui.copyToClipboard.get()).toHaveAttribute('data-clipboard-text', 'secretKey');
+});
+
+function renderEncryptionApp() {
+  return renderComponent(<EncryptionApp />);
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx
deleted file mode 100644 (file)
index ae415f2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { checkSecretKey, generateSecretKey } from '../../../../api/settings';
-import { waitAndUpdate } from '../../../../helpers/testUtils';
-import EncryptionApp from '../EncryptionApp';
-
-jest.mock('../../../../api/settings', () => ({
-  checkSecretKey: jest.fn().mockResolvedValue({ secretKeyAvailable: true }),
-  generateSecretKey: jest.fn().mockResolvedValue({ secretKey: 'secret' }),
-}));
-
-it('should render correctly', () => {
-  const wrapper = shallowRender();
-  expect(wrapper).toMatchSnapshot('loading');
-  expect(wrapper.setState({ loading: false, secretKeyAvailable: false })).toMatchSnapshot(
-    'generate form'
-  );
-  expect(wrapper.setState({ secretKeyAvailable: true })).toMatchSnapshot('encryption form');
-});
-
-it('should correctly check a key', async () => {
-  const wrapper = shallowRender();
-  wrapper.instance().checkSecretKey();
-  await waitAndUpdate(wrapper);
-  expect(checkSecretKey).toHaveBeenCalled();
-  expect(wrapper.state().secretKeyAvailable).toBe(true);
-});
-
-it('should correctly generate a key', async () => {
-  const wrapper = shallowRender();
-  wrapper.instance().generateSecretKey();
-  await waitAndUpdate(wrapper);
-  expect(generateSecretKey).toHaveBeenCalled();
-  expect(wrapper.state().secretKey).toBe('secret');
-  expect(wrapper.state().secretKeyAvailable).toBe(false);
-});
-
-function shallowRender(props: Partial<EncryptionApp['props']> = {}) {
-  return shallow<EncryptionApp>(<EncryptionApp {...props} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionForm-test.tsx
deleted file mode 100644 (file)
index 7d938a4..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 EncryptionForm from '../EncryptionForm';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender() {
-  return shallow(<EncryptionForm generateSecretKey={jest.fn()} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/GenerateSecretKeyForm-test.tsx b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/GenerateSecretKeyForm-test.tsx
deleted file mode 100644 (file)
index d588369..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 GenerateSecretKeyForm from '../GenerateSecretKeyForm';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender() {
-  return shallow(<GenerateSecretKeyForm generateSecretKey={jest.fn()} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap
deleted file mode 100644 (file)
index 654034b..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: encryption form 1`] = `
-<div
-  className="page page-limited"
-  id="encryption-page"
->
-  <Helmet
-    defer={false}
-    encodeSpecialCharacters={true}
-    prioritizeSeoTags={false}
-    title="property.category.security.encryption"
-  />
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      property.category.security.encryption
-    </h1>
-    <DeferredSpinner
-      loading={false}
-    />
-  </header>
-  <EncryptionForm
-    generateSecretKey={[Function]}
-  />
-</div>
-`;
-
-exports[`should render correctly: generate form 1`] = `
-<div
-  className="page page-limited"
-  id="encryption-page"
->
-  <Helmet
-    defer={false}
-    encodeSpecialCharacters={true}
-    prioritizeSeoTags={false}
-    title="property.category.security.encryption"
-  />
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      property.category.security.encryption
-    </h1>
-    <DeferredSpinner
-      loading={false}
-    />
-  </header>
-  <GenerateSecretKeyForm
-    generateSecretKey={[Function]}
-  />
-</div>
-`;
-
-exports[`should render correctly: loading 1`] = `
-<div
-  className="page page-limited"
-  id="encryption-page"
->
-  <Helmet
-    defer={false}
-    encodeSpecialCharacters={true}
-    prioritizeSeoTags={false}
-    title="property.category.security.encryption"
-  />
-  <header
-    className="page-header"
-  >
-    <h1
-      className="page-title"
-    >
-      property.category.security.encryption
-    </h1>
-    <DeferredSpinner
-      loading={true}
-    />
-  </header>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionForm-test.tsx.snap
deleted file mode 100644 (file)
index cac7af8..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<div
-  id="encryption-form-container"
->
-  <div
-    className="spacer-bottom"
-  >
-    encryption.form_intro
-  </div>
-  <form
-    className="big-spacer-bottom"
-    id="encryption-form"
-    onSubmit={[Function]}
-  >
-    <textarea
-      autoFocus={true}
-      className="abs-width-600"
-      id="encryption-form-value"
-      onChange={[Function]}
-      required={true}
-      rows={5}
-      value=""
-    />
-    <div
-      className="spacer-top"
-    >
-      <SubmitButton
-        disabled={false}
-      >
-        encryption.encrypt
-      </SubmitButton>
-      <DeferredSpinner
-        className="spacer-left"
-        loading={false}
-      />
-    </div>
-  </form>
-  <form
-    className="huge-spacer-top bordered-top"
-    id="encryption-new-key-form"
-    onSubmit={[Function]}
-  >
-    <p
-      className="big-spacer-top spacer-bottom"
-    >
-      <FormattedMessage
-        defaultMessage="encryption.form_note"
-        id="encryption.form_note"
-        values={
-          {
-            "moreInformationLink": <withAppStateContext(DocLink)
-              to="/instance-administration/security/"
-            >
-              more_information
-            </withAppStateContext(DocLink)>,
-          }
-        }
-      />
-    </p>
-    <SubmitButton
-      disabled={false}
-    >
-      encryption.generate_new_secret_key
-       
-    </SubmitButton>
-    <DeferredSpinner
-      className="spacer-left"
-      loading={false}
-    />
-  </form>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/GenerateSecretKeyForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/GenerateSecretKeyForm-test.tsx.snap
deleted file mode 100644 (file)
index 2249cde..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<div
-  id="generate-secret-key-form-container"
->
-  <form
-    id="generate-secret-key-form"
-    onSubmit={[Function]}
-  >
-    <p
-      className="spacer-bottom"
-    >
-      <FormattedMessage
-        defaultMessage="encryption.secret_key_description"
-        id="encryption.secret_key_description"
-        values={
-          {
-            "moreInformationLink": <withAppStateContext(DocLink)
-              to="/instance-administration/security/"
-            >
-              more_information
-            </withAppStateContext(DocLink)>,
-          }
-        }
-      />
-    </p>
-    <SubmitButton
-      disabled={false}
-    >
-      encryption.generate_secret_key
-    </SubmitButton>
-    <DeferredSpinner
-      className="spacer-left"
-      loading={false}
-    />
-  </form>
-</div>
-`;
index e40fb501af7cef420bc6a757c4c0f755e95125b1..f54dcdad6aefb6e0a85d4c3ad24a8cdbc6142585 100644 (file)
@@ -1207,6 +1207,10 @@ settings.projects.change_visibility_form.submit=Change Default Visibility
 
 settings.almintegration.title=DevOps Platform Integrations
 settings.almintegration.description=DevOps Platform integrations allow SonarQube to interact with your DevOps Platform. This enables things like authentication, or providing analysis details and a Quality Gate to your Pull Requests directly in your DevOps Platform's interface.
+settings.almintegration.tab.github=GitHub
+settings.almintegration.tab.bitbucket=Bitbucket
+settings.almintegration.tab.azure=Azure DevOps
+settings.almintegration.tab.gitlab=GitLab
 settings.almintegration.github.info=You need to install a GitHub App with specific settings and permissions to enable Pull Request Decoration on your Organization or Repository. {link}
 settings.almintegration.github.additional_permission=If Quality Gate status reporting fails on private projects, you might need to add an additional permission to the GitHub App. {link}
 settings.almintegration.bitbucketcloud.info=SonarQube needs you to create an {oauth} in your Bitbucket Cloud workspace settings to report the Quality Gate status on Pull Requests. It needs to be a private consumer with {permission} permission. An OAuth callback URL is required by Bitbucket Cloud but not used by SonarQube so any URL works. {doc_link}
@@ -1220,6 +1224,9 @@ settings.almintegration.create=Create configuration
 settings.almintegration.create.tooltip=Upgrade to {link} to integrate with multiple {alm} instances.
 settings.almintegration.create.tooltip.link=Enterprise Edition
 settings.almintegration.check_configuration=Check configuration
+settings.almintegration.check_configuration_x=Check configuration '{0}'
+settings.almintegration.edit_configuration=Edit configuration '{0}'
+settings.almintegration.delete_configuration=Delete configuration '{0}'
 settings.almintegration.checking_configuration=Checking configuration
 settings.almintegration.configuration_valid=Configuration valid
 settings.almintegration.configuration_invalid=You have the following errors in your configuration:
@@ -1279,6 +1286,7 @@ settings.almintegration.form.save=Save configuration
 settings.almintegration.form.cancel=Cancel
 settings.almintegration.form.secret.field=This field is hidden for security reasons.
 settings.almintegration.form.secret.update_field=Update field value
+settings.almintegration.form.secret.update_field_x=Update {0} value
 settings.almintegration.form.secret.can_encrypt=You can encrypt this value. {learn_more}
 settings.almintegration.feature.status_reporting.title=Quality Gate status reporting
 settings.almintegration.feature.status_reporting.description_pr=Add analysis and a Quality Gate to your Pull Requests directly in your DevOps Platform's interface.