]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21506 Migrating github and gitlab test config to adopt new UI
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>
Thu, 25 Jan 2024 10:21:39 +0000 (11:21 +0100)
committersonartech <sonartech@sonarsource.com>
Tue, 30 Jan 2024 15:02:03 +0000 (15:02 +0000)
server/sonar-web/src/main/js/apps/settings/components/authentication/GitHubConfigurationValidity.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabConfigurationValidity.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/TestConfiguration.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Github-it.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/__tests__/Authentication-Gitlab-it.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index b03c9c6e488519ebbb51d64ece19dff4c046406f..50e1e3a6a6ddb42f2a83b96dc5e28022bfe1387e 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 { TextMuted } from 'design-system';
+import {
+  ButtonLink,
+  FlagErrorIcon,
+  FlagMessage,
+  FlagSuccessIcon,
+  HelperHintIcon,
+  Modal,
+  TextMuted,
+  UnorderedList,
+  Variant,
+} from 'design-system';
 import React, { useEffect, useState } from 'react';
-import theme, { colors } from '../../../../app/theme';
-import Modal from '../../../../components/controls/Modal';
-import { Button } from '../../../../components/controls/buttons';
-import CheckIcon from '../../../../components/icons/CheckIcon';
-import ClearIcon from '../../../../components/icons/ClearIcon';
-import HelpIcon from '../../../../components/icons/HelpIcon';
-import { Alert, AlertVariant } from '../../../../components/ui/Alert';
 import { translate, translateWithParameters } from '../../../../helpers/l10n';
 import { useCheckGitHubConfigQuery } from '../../../../queries/identity-provider/github';
 import { GitHubProvisioningStatus } from '../../../../types/provisioning';
+import TestConfiguration from './TestConfiguration';
 
 const intlPrefix = 'settings.authentication.github.configuration.validation';
 
 function ValidityIcon({ valid }: { valid: boolean }) {
-  const color = valid ? theme.colors.success500 : theme.colors.error500;
-
   return valid ? (
-    <CheckIcon fill={color} label={translate(`${intlPrefix}.details.valid_label`)} />
+    <FlagSuccessIcon aria-label={translate(`${intlPrefix}.details.valid_label`)} />
   ) : (
-    <ClearIcon fill={color} label={translate(`${intlPrefix}.details.invalid_label`)} />
+    <FlagErrorIcon aria-label={translate(`${intlPrefix}.details.invalid_label`)} />
   );
 }
 
@@ -53,7 +55,7 @@ export default function GitHubConfigurationValidity({
 }: Props) {
   const [openDetails, setOpenDetails] = useState(false);
   const [messages, setMessages] = useState<string[]>([]);
-  const [alertVariant, setAlertVariant] = useState<AlertVariant>('loading');
+  const [alertVariant, setAlertVariant] = useState<Variant>('info');
   const { data, isFetching, refetch } = useCheckGitHubConfigQuery(true);
   const modalHeader = translate(`${intlPrefix}.details.title`);
 
@@ -67,12 +69,6 @@ export default function GitHubConfigurationValidity({
   });
 
   useEffect(() => {
-    if (isFetching) {
-      setMessages([translate(`${intlPrefix}.loading`)]);
-      setAlertVariant('loading');
-      return;
-    }
-
     const invalidOrgs =
       isValidApp && data
         ? data.installations.filter(
@@ -116,78 +112,81 @@ export default function GitHubConfigurationValidity({
     }
   }, [isFetching, isValidApp, isAutoProvisioning, applicationField, data]);
 
+  const message = (
+    <div className="sw-flex sw-items-center">
+      <div>
+        {messages.map((msg) => (
+          <p key={msg}>{msg}</p>
+        ))}
+      </div>
+      <div>
+        <ButtonLink
+          onClick={() => setOpenDetails(true)}
+          disabled={isFetching}
+          className="sw-mx-2 sw-whitespace-nowrap sw-text-center"
+        >
+          {translate(`${intlPrefix}.details`)}
+        </ButtonLink>
+      </div>
+    </div>
+  );
+
   return (
     <>
-      <Alert
-        title={messages[0]}
-        variant={alertVariant}
-        aria-live="polite"
-        role="status"
-        aria-atomic
-        aria-busy={isFetching}
-      >
-        <div className="sw-flex sw-justify-between sw-items-center">
-          <div>
-            {messages.map((msg) => (
-              <div key={msg}>{msg}</div>
-            ))}
-          </div>
-          <div className="sw-flex">
-            <Button
-              onClick={() => setOpenDetails(true)}
-              disabled={isFetching}
-              className="sw-mr-2 sw-whitespace-nowrap sw-text-center"
-            >
-              {translate(`${intlPrefix}.details`)}
-            </Button>
-            <Button
-              onClick={() => refetch()}
-              disabled={isFetching}
-              className="sw-whitespace-nowrap sw-text-center"
-            >
-              {translate(`${intlPrefix}.test`)}
-            </Button>
-          </div>
-        </div>
-      </Alert>
+      <TestConfiguration
+        loading={isFetching}
+        onTestConf={() => refetch()}
+        flagMessageVariant={alertVariant}
+        flagMessageContent={message}
+        flagMessageTitle={messages[0]}
+      />
+
       {openDetails && (
-        <Modal size="small" contentLabel={modalHeader} onRequestClose={() => setOpenDetails(false)}>
-          <header className="modal-head">
-            <h2>
-              {modalHeader} <ValidityIcon valid={isValidApp} />
-            </h2>
-          </header>
-          <div className="modal-body modal-container">
-            {!isValidApp && (
-              <Alert variant="error">{data?.application[applicationField].errorMessage}</Alert>
-            )}
-            <ul className="sw-pl-5">
-              {data?.installations.map((inst) => (
-                <li key={inst.organization}>
-                  <ValidityIcon
-                    valid={inst[applicationField].status === GitHubProvisioningStatus.Success}
-                  />
-                  <span className="sw-ml-2">{inst.organization}</span>
-                  {inst[applicationField].status === GitHubProvisioningStatus.Failed && (
-                    <span> - {inst[applicationField].errorMessage}</span>
+        <Modal
+          headerTitle={modalHeader}
+          onClose={() => setOpenDetails(false)}
+          body={
+            <>
+              {isValidApp ? (
+                <FlagMessage variant="success" className="sw-w-full sw-mb-2">
+                  {translate(`${intlPrefix}.valid.short`)}
+                </FlagMessage>
+              ) : (
+                <FlagMessage variant="error" className="sw-w-full sw-mb-2">
+                  {translateWithParameters(
+                    `${intlPrefix}.invalid`,
+                    data?.application[applicationField].errorMessage ?? '',
                   )}
-                </li>
-              ))}
-              {failedOrgs.map((fo) => (
-                <li key={fo}>
-                  <HelpIcon fillInner={colors.gray60} fill={colors.white} role="img" />
-                  <TextMuted
-                    className="sw-ml-2"
-                    text={translateWithParameters(`${intlPrefix}.details.org_not_found`, fo)}
-                  />
-                </li>
-              ))}
-            </ul>
-          </div>
-          <footer className="modal-foot">
-            <Button onClick={() => setOpenDetails(false)}>{translate('close')}</Button>
-          </footer>
-        </Modal>
+                </FlagMessage>
+              )}
+              <UnorderedList className="sw-pl-5 sw-m-0">
+                {data?.installations.map((inst) => (
+                  <li key={inst.organization} className="sw-flex sw-items-center">
+                    <ValidityIcon
+                      valid={inst[applicationField].status === GitHubProvisioningStatus.Success}
+                    />
+                    <div>
+                      <span className="sw-ml-2">{inst.organization}</span>
+                      {inst[applicationField].status === GitHubProvisioningStatus.Failed && (
+                        <span> - {inst[applicationField].errorMessage}</span>
+                      )}
+                    </div>
+                  </li>
+                ))}
+                {failedOrgs.map((fo) => (
+                  <li key={fo} className="sw-flex sw-items-center">
+                    <HelperHintIcon />
+                    <TextMuted
+                      className="sw-ml-2"
+                      text={translateWithParameters(`${intlPrefix}.details.org_not_found`, fo)}
+                    />
+                  </li>
+                ))}
+              </UnorderedList>
+            </>
+          }
+          secondaryButtonLabel={translate('close')}
+        />
       )}
     </>
   );
index d9b00983b16f9c0757da6a2ca8e35f42031f6a98..30c12786759592a7286fab00a8c117413eda1b6b 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 React from 'react';
-import { Button } from '../../../../components/controls/buttons';
-import { Alert } from '../../../../components/ui/Alert';
 import { translate } from '../../../../helpers/l10n';
 import { GitlabConfiguration } from '../../../../types/provisioning';
+import TestConfiguration from './TestConfiguration';
 
 const intlPrefix = 'settings.authentication.gitlab.configuration';
 
@@ -33,33 +33,18 @@ interface Props {
 
 export default function GitLabConfigurationValidity(props: Readonly<Props>) {
   const { configuration, loading } = props;
-  const message = loading
-    ? translate(`${intlPrefix}.validity_check_loading`)
-    : configuration?.errorMessage ??
-      translate(`${intlPrefix}.valid.${configuration?.provisioningType}`);
+  const message =
+    configuration?.errorMessage ??
+    translate(`${intlPrefix}.valid.${configuration?.provisioningType}`);
   const variant = configuration?.errorMessage ? 'error' : 'success';
 
   return (
-    <Alert
-      title={message}
-      variant={loading ? 'loading' : variant}
-      aria-live="polite"
-      role="status"
-      aria-atomic
-      aria-busy={loading}
-    >
-      <div className="sw-flex sw-justify-between sw-items-center">
-        <div>{message}</div>
-        <div className="sw-flex">
-          <Button
-            onClick={props.onRecheck}
-            disabled={loading}
-            className="sw-whitespace-nowrap sw-text-center"
-          >
-            {translate(`${intlPrefix}.test`)}
-          </Button>
-        </div>
-      </div>
-    </Alert>
+    <TestConfiguration
+      loading={loading}
+      onTestConf={props.onRecheck}
+      flagMessageVariant={variant}
+      flagMessageContent={message}
+      flagMessageTitle={message}
+    />
   );
 }
diff --git a/server/sonar-web/src/main/js/apps/settings/components/authentication/TestConfiguration.tsx b/server/sonar-web/src/main/js/apps/settings/components/authentication/TestConfiguration.tsx
new file mode 100644 (file)
index 0000000..91bbc07
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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 { ButtonSecondary, FlagMessage, Spinner, Variant } from 'design-system';
+import React from 'react';
+import { translate } from '../../../../helpers/l10n';
+
+const intlPrefix = 'settings.authentication.configuration';
+
+interface Props {
+  loading: boolean;
+  onTestConf: () => void;
+  flagMessageVariant: Variant;
+  flagMessageContent: React.ReactNode;
+  flagMessageTitle: string;
+}
+
+export default function GitLabConfigurationValidity(props: Readonly<Props>) {
+  const { loading, flagMessageContent, flagMessageTitle, flagMessageVariant, onTestConf } = props;
+
+  return (
+    <>
+      <div className="sw-flex sw-items-center">
+        <Spinner className="sw-mr-2 sw-my-2" loading={loading} />
+        {loading && <p>{translate(`${intlPrefix}.validity_check_loading`)}</p>}
+      </div>
+      <FlagMessage
+        className="sw-w-full"
+        title={flagMessageTitle}
+        variant={flagMessageVariant}
+        aria-live="polite"
+        role="status"
+        aria-atomic
+        aria-busy={loading}
+      >
+        {loading ? undefined : flagMessageContent}
+      </FlagMessage>
+      <ButtonSecondary
+        onClick={onTestConf}
+        disabled={loading}
+        className="sw-whitespace-nowrap sw-text-center sw-my-4"
+      >
+        {translate(`${intlPrefix}.test`)}
+      </ButtonSecondary>
+    </>
+  );
+}
index df3e3652f1fdb3cba75814747c17ebb114388e5d..121c39908a74b204cbfb56e629488a14e65d60b5 100644 (file)
@@ -28,7 +28,7 @@ import SystemServiceMock from '../../../../../api/mocks/SystemServiceMock';
 import { AvailableFeaturesContext } from '../../../../../app/components/available-features/AvailableFeaturesContext';
 import { definitions } from '../../../../../helpers/mocks/definitions-list';
 import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
-import { byRole, byText } from '../../../../../helpers/testSelector';
+import { byLabelText, byRole, byText } from '../../../../../helpers/testSelector';
 import { AlmKeys } from '../../../../../types/alm-settings';
 import { Feature } from '../../../../../types/features';
 import { GitHubProvisioningStatus } from '../../../../../types/provisioning';
@@ -162,7 +162,7 @@ const ui = {
     name: /github.configuration.validation.valid.short/,
   }),
   checkConfigButton: ghContainer.byRole('button', {
-    name: 'settings.authentication.github.configuration.validation.test',
+    name: 'settings.authentication.configuration.test',
   }),
   viewConfigValidityDetailsButton: ghContainer.byRole('button', {
     name: 'settings.authentication.github.configuration.validation.details',
@@ -179,8 +179,9 @@ const ui = {
   consentDialog: byRole('dialog', {
     name: 'settings.authentication.github.confirm_auto_provisioning.header',
   }),
-  getConfigDetailsTitle: () => within(ui.configDetailsDialog.get()).getByRole('heading'),
-  getOrgs: () => within(ui.configDetailsDialog.get()).getAllByRole('listitem'),
+  getConfigDetailsTitle: () => ui.configDetailsDialog.byRole('heading').get(),
+  getOrgs: () => ui.configDetailsDialog.byRole('listitem').getAll(),
+  getIconForOrg: (text: string, org: HTMLElement) => byLabelText(text).get(org),
   fillForm: async (user: UserEvent) => {
     await user.type(await ui.clientId.find(), 'Awsome GITHUB config');
     await user.type(ui.clientSecret.get(), 'Client shut');
@@ -423,15 +424,20 @@ describe('Github tab', () => {
       expect(ui.configurationValiditySuccess.get()).toHaveTextContent('2');
 
       await user.click(ui.viewConfigValidityDetailsButton.get());
-      expect(ui.getConfigDetailsTitle()).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_label',
-      );
-      expect(ui.getOrgs()[0]).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_labelorg1',
-      );
-      expect(ui.getOrgs()[1]).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_labelorg2',
-      );
+      expect(ui.getConfigDetailsTitle()).toBeInTheDocument();
+      expect(ui.getOrgs()).toHaveLength(3);
+      expect(
+        ui.getIconForOrg(
+          'settings.authentication.github.configuration.validation.details.valid_label',
+          ui.getOrgs()[0],
+        ),
+      ).toBeInTheDocument();
+      expect(
+        ui.getIconForOrg(
+          'settings.authentication.github.configuration.validation.details.valid_label',
+          ui.getOrgs()[1],
+        ),
+      ).toBeInTheDocument();
     });
 
     it('should display that config is invalid for autoprovisioning if some apps are suspended but valid for jit', async () => {
@@ -461,12 +467,19 @@ describe('Github tab', () => {
       expect(ui.configurationValidityWarning.get()).toHaveTextContent(errorMessage);
 
       await user.click(ui.viewConfigValidityDetailsButton.get());
-      expect(ui.getConfigDetailsTitle()).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_label',
-      );
-      expect(ui.getOrgs()[0]).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.invalid_labelorg1 - Installation suspended',
-      );
+      expect(ui.getConfigDetailsTitle()).toBeInTheDocument();
+      expect(
+        ui.configDetailsDialog
+          .byText('settings.authentication.github.configuration.validation.valid.short')
+          .get(),
+      ).toBeInTheDocument();
+      expect(ui.getOrgs()[0]).toHaveTextContent('org1 - Installation suspended');
+      expect(
+        ui.getIconForOrg(
+          'settings.authentication.github.configuration.validation.details.invalid_label',
+          ui.getOrgs()[0],
+        ),
+      ).toBeInTheDocument();
 
       await user.click(ui.configDetailsDialog.byRole('button', { name: 'close' }).get());
 
@@ -495,12 +508,19 @@ describe('Github tab', () => {
       expect(ui.configurationValiditySuccess.get()).toHaveTextContent('1');
 
       await user.click(ui.viewConfigValidityDetailsButton.get());
-      expect(ui.getConfigDetailsTitle()).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_label',
-      );
-      expect(ui.getOrgs()[0]).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_labelorg1',
-      );
+      expect(ui.getConfigDetailsTitle()).toBeInTheDocument();
+      expect(
+        ui.configDetailsDialog
+          .byText('settings.authentication.github.configuration.validation.valid.short')
+          .get(),
+      ).toBeInTheDocument();
+      expect(ui.getOrgs()[0]).toHaveTextContent('org1');
+      expect(
+        ui.getIconForOrg(
+          'settings.authentication.github.configuration.validation.details.valid_label',
+          ui.getOrgs()[0],
+        ),
+      ).toBeInTheDocument();
       expect(ui.getOrgs()[1]).toHaveTextContent(
         'settings.authentication.github.configuration.validation.details.org_not_found.organization1',
       );
@@ -529,9 +549,12 @@ describe('Github tab', () => {
       expect(ui.configurationValidityError.get()).toHaveTextContent(errorMessage);
 
       await user.click(ui.viewConfigValidityDetailsButton.get());
-      expect(ui.getConfigDetailsTitle()).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.invalid_label',
-      );
+      expect(ui.getConfigDetailsTitle()).toBeInTheDocument();
+      expect(
+        ui.configDetailsDialog
+          .byText(/settings.authentication.github.configuration.validation.invalid/)
+          .get(),
+      ).toBeInTheDocument();
       expect(ui.configDetailsDialog.get()).toHaveTextContent(errorMessage);
     });
 
@@ -557,9 +580,12 @@ describe('Github tab', () => {
       expect(ui.configurationValiditySuccess.get()).not.toHaveTextContent(errorMessage);
 
       await user.click(ui.viewConfigValidityDetailsButton.get());
-      expect(ui.getConfigDetailsTitle()).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_label',
-      );
+      expect(ui.getConfigDetailsTitle()).toBeInTheDocument();
+      expect(
+        ui.configDetailsDialog
+          .byText('settings.authentication.github.configuration.validation.valid.short')
+          .get(),
+      ).toBeInTheDocument();
       await user.click(ui.configDetailsDialog.byRole('button', { name: 'close' }).get());
 
       await user.click(ui.githubProvisioningButton.get());
@@ -568,9 +594,11 @@ describe('Github tab', () => {
       expect(ui.configurationValidityError.get()).toHaveTextContent(errorMessage);
 
       await user.click(ui.viewConfigValidityDetailsButton.get());
-      expect(ui.getConfigDetailsTitle()).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.invalid_label',
-      );
+      expect(
+        ui.configDetailsDialog
+          .byText(/settings.authentication.github.configuration.validation.invalid/)
+          .get(),
+      ).toBeInTheDocument();
     });
 
     it('should display that config is invalid because of orgs', async () => {
@@ -598,12 +626,20 @@ describe('Github tab', () => {
 
       await user.click(ui.viewConfigValidityDetailsButton.get());
 
-      expect(ui.getOrgs()[0]).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.valid_labelorg1',
-      );
-      expect(ui.getOrgs()[1]).toHaveTextContent(
-        'settings.authentication.github.configuration.validation.details.invalid_labelorg2 - Test error',
-      );
+      expect(ui.getOrgs()[0]).toHaveTextContent('org1');
+      expect(
+        ui.getIconForOrg(
+          'settings.authentication.github.configuration.validation.details.valid_label',
+          ui.getOrgs()[0],
+        ),
+      ).toBeInTheDocument();
+      expect(ui.getOrgs()[1]).toHaveTextContent('org2 - Test error');
+      expect(
+        ui.getIconForOrg(
+          'settings.authentication.github.configuration.validation.details.invalid_label',
+          ui.getOrgs()[1],
+        ),
+      ).toBeInTheDocument();
 
       await user.click(ui.configDetailsDialog.byRole('button', { name: 'close' }).get());
 
@@ -614,9 +650,15 @@ describe('Github tab', () => {
         `settings.authentication.github.configuration.validation.invalid_org.org2.${errorMessage}`,
       );
       await user.click(ui.viewConfigValidityDetailsButton.get());
-      expect(ui.getOrgs()[1]).toHaveTextContent(
-        `settings.authentication.github.configuration.validation.details.invalid_labelorg2 - ${errorMessage}`,
-      );
+
+      expect(
+        ui.configDetailsDialog
+          .byLabelText(
+            'settings.authentication.github.configuration.validation.details.invalid_label',
+          )
+          .getAll(),
+      ).toHaveLength(1);
+      expect(ui.getOrgs()[1]).toHaveTextContent(`org2 - ${errorMessage}`);
     });
 
     it('should update provisioning validity after clicking Test Configuration', async () => {
index 3cc5ca6050f25316cc281e26f250a089c536c4ff..432e781aa0e601584db8fe5be2b5208b1d7fb607 100644 (file)
@@ -128,7 +128,7 @@ const ui = {
   gitlabProvisioningAlert: glContainer.byText(/synchronization_failed/),
   gitlabConfigurationStatus: glContainer.byRole('status'),
   testConfiguration: glContainer.byRole('button', {
-    name: 'settings.authentication.gitlab.configuration.test',
+    name: 'settings.authentication.configuration.test',
   }),
 };
 
@@ -464,21 +464,20 @@ describe('Gitlab Provisioning', () => {
     const user = userEvent.setup();
     renderAuthentication([Feature.GitlabProvisioning]);
 
-    expect(await ui.gitlabConfigurationStatus.find()).toBeInTheDocument();
-    expect(ui.gitlabConfigurationStatus.get()).toHaveTextContent(
+    expect((await ui.gitlabConfigurationStatus.findAll())[1]).toHaveTextContent(
       'settings.authentication.gitlab.configuration.valid.AUTO_PROVISIONING',
     );
     await user.click(ui.jitProvisioningRadioButton.get());
     await user.click(ui.saveProvisioning.get());
     await user.click(ui.confirmProvisioningChange.get());
-    expect(ui.gitlabConfigurationStatus.get()).toHaveTextContent(
+    expect(ui.gitlabConfigurationStatus.getAll()[1]).toHaveTextContent(
       'settings.authentication.gitlab.configuration.valid.JIT',
     );
     handler.setGitlabConfigurations([
       mockGitlabConfiguration({ ...handler.gitlabConfigurations[0], errorMessage: 'ERROR' }),
     ]);
     await user.click(ui.testConfiguration.get());
-    expect(ui.gitlabConfigurationStatus.get()).toHaveTextContent('ERROR');
+    expect(ui.gitlabConfigurationStatus.getAll()[1]).toHaveTextContent('ERROR');
     await user.click(ui.disableConfigButton.get());
     expect(ui.gitlabConfigurationStatus.query()).not.toBeInTheDocument();
   });
index 80754c1d07518d3bc16c2a02c4b15dcd177205e9..3fdcc71687d548bee8b6a0e639c6bf1c6eb306d9 100644 (file)
@@ -1555,14 +1555,12 @@ settings.authentication.github.synchronization_failed=Last synchronization faile
 settings.authentication.github.synchronization_failed_short=Last synchronization failed. {details}
 settings.authentication.github.synchronization_details_link=More details
 settings.authentication.github.configuration.validation.details=View details
-settings.authentication.github.configuration.validation.test=Test configuration
-settings.authentication.github.configuration.validation.loading=Checking the configuration
 settings.authentication.github.configuration.validation.valid.short=Configuration is valid.
 settings.authentication.github.configuration.validation.valid=Configuration is valid for {0}. {1} organizations will be synced.
 settings.authentication.github.configuration.validation.valid_one=Configuration is valid for {0}. Organization '{1}' will be synced.
 settings.authentication.github.configuration.validation.invalid=Configuration is invalid. {0}
 settings.authentication.github.configuration.validation.invalid_org=Organization "{0}" has the following error: {1}
-settings.authentication.github.configuration.validation.details.title=Configuration validity:
+settings.authentication.github.configuration.validation.details.title=Configuration validity
 settings.authentication.github.configuration.validation.details.valid_label=Valid
 settings.authentication.github.configuration.validation.details.invalid_label=Invalid
 settings.authentication.github.configuration.validation.details.org_not_found={0} (not found or app not installed)
@@ -1612,11 +1610,13 @@ settings.authentication.gitlab.form.provisioning_with_gitlab=Automatic user and
 settings.authentication.gitlab.form.provisioning_with_gitlab.description=Users and groups are automatically provisioned from GitLab. Once activated, users and groups can only be created and modified from GitLab. Existing local users will be kept and can only be deactivated.
 settings.authentication.gitlab.form.provisioning.disabled=Your current edition does not support provisioning with GitLab. See the {documentation} for more information.
 settings.authentication.gitlab.configuration.unsaved_changes=You have unsaved changes.
-settings.authentication.gitlab.configuration.validity_check_loading=Checking the configuration
-settings.authentication.gitlab.configuration.test=Test configuration
 settings.authentication.gitlab.configuration.valid.JIT=Configuration is valid for Just-in-Time provisioning.
 settings.authentication.gitlab.configuration.valid.AUTO_PROVISIONING=Configuration is valid for Automatic provisioning.
 
+# COMMON
+settings.authentication.configuration.validity_check_loading=Checking the configuration
+settings.authentication.configuration.test=Test configuration
+
 # SAML
 settings.authentication.form.create.saml=New SAML configuration
 settings.authentication.form.edit.saml=Edit SAML configuration