]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10053 Display error message when entering license of unknown edition in marketplace
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Thu, 22 Feb 2018 16:35:02 +0000 (17:35 +0100)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Fri, 23 Feb 2018 15:34:13 +0000 (16:34 +0100)
server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionSet.tsx
server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionSet-test.tsx
server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionSet-test.tsx.snap
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 6be68c1aa3194ca32973bf91f036f7854e18d819..b8099a65079abc61240cd912cb49f3b25f4ed720 100644 (file)
@@ -37,14 +37,15 @@ export interface Props {
 
 interface State {
   acceptTerms: boolean;
-  license: string;
-  licenseEdition?: Edition;
-  loading: boolean;
-  previewStatus?: string;
   formData?: {
     serverId?: string;
     ncloc?: number;
   };
+  license: string;
+  licenseEdition?: Edition;
+  loading: boolean;
+  previewStatus?: string;
+  wrongEdition: boolean;
 }
 
 export default class LicenseEditionSet extends React.PureComponent<Props, State> {
@@ -52,7 +53,7 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
 
   constructor(props: Props) {
     super(props);
-    this.state = { acceptTerms: false, license: '', loading: false };
+    this.state = { acceptTerms: false, license: '', loading: false, wrongEdition: false };
     this.fetchLicensePreview = debounce(this.fetchLicensePreview, 100);
   }
 
@@ -71,16 +72,18 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
       ({ previewStatus, nextEditionKey }) => {
         if (this.mounted) {
           const { edition } = this.props;
-          this.updateLicense(
-            license,
-            this.props.editions.find(edition => edition.key === nextEditionKey),
-            edition && edition.key !== nextEditionKey ? undefined : previewStatus
+          const licenseEdition = this.props.editions.find(
+            edition => edition.key === nextEditionKey
+          );
+          const wrongEdition = Boolean(
+            !licenseEdition || (edition && edition.key !== nextEditionKey)
           );
+          this.setLicense({ license, loading: false, licenseEdition, previewStatus, wrongEdition });
         }
       },
       () => {
         if (this.mounted) {
-          this.updateLicense(license, undefined, undefined);
+          this.resetLicense({ license, loading: false });
         }
       }
     );
@@ -114,42 +117,59 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
       this.fetchLicensePreview(license);
       this.setState({ license });
     } else {
-      this.updateLicense(license, undefined, undefined);
+      this.resetLicense({});
     }
   };
 
-  handleTermsCheck = (checked: boolean) =>
-    this.setState({ acceptTerms: checked }, () =>
-      this.updateLicense(this.state.license, this.state.licenseEdition, this.state.previewStatus)
+  handleTermsCheck = (checked: boolean) => {
+    this.setLicense({ acceptTerms: checked });
+  };
+
+  resetLicense<K extends keyof State>(state: Pick<State, K>) {
+    this.setLicense(
+      Object.assign(
+        {
+          license: '',
+          licenseEdition: undefined,
+          previewStatus: undefined,
+          wrongEdition: false
+        },
+        state
+      )
     );
+  }
+
+  setLicense<K extends keyof State>(state: Pick<State, K>) {
+    this.setState(state, this.updateParentLicense);
+  }
 
-  updateLicense = (license: string, licenseEdition?: Edition, previewStatus?: string) => {
-    this.setState({ license, licenseEdition, loading: false, previewStatus });
+  updateParentLicense = () => {
+    const { acceptTerms, license, previewStatus, wrongEdition } = this.state;
     this.props.updateLicense(
-      previewStatus !== 'NO_INSTALL' && !this.state.acceptTerms ? undefined : license,
-      previewStatus
+      previewStatus !== 'NO_INSTALL' && !acceptTerms ? undefined : license,
+      wrongEdition ? undefined : previewStatus
     );
   };
 
   renderAlert() {
-    const { licenseEdition, previewStatus } = this.state;
-    if (!previewStatus) {
+    const { licenseEdition, previewStatus, wrongEdition } = this.state;
+    if (!previewStatus || wrongEdition) {
       const { edition } = this.props;
-      if (!edition) {
-        return undefined;
-      }
 
       return (
         <div className="spacer-top">
-          {licenseEdition !== undefined &&
-            edition.key !== licenseEdition.key && (
-              <p className="alert alert-danger">
-                {translateWithParameters('marketplace.wrong_license_type_x', edition.name)}
-              </p>
-            )}
-          <a href={this.getLicenseFormUrl(edition)} target="_blank">
-            {translate('marketplace.i_need_a_license')}
-          </a>
+          {wrongEdition && (
+            <p className="alert alert-danger">
+              {edition
+                ? translateWithParameters('marketplace.wrong_license_type_x', edition.name)
+                : translate('marketplace.wrong_license_type')}
+            </p>
+          )}
+          {edition && (
+            <a href={this.getLicenseFormUrl(edition)} target="_blank">
+              {translate('marketplace.i_need_a_license')}
+            </a>
+          )}
         </div>
       );
     }
@@ -177,6 +197,7 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
                     url: (
                       <a
                         href="https://redirect.sonarsource.com/doc/data-center-edition.html"
+                        rel="noopener noreferrer"
                         target="_blank">
                         {licenseEdition.name}
                       </a>
@@ -199,6 +220,7 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
             <a
               className="nowrap little-spacer-left"
               href="http://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf"
+              rel="noopener noreferrer"
               target="_blank">
               {translate('marketplace.terms_and_conditions')}
             </a>
@@ -222,8 +244,8 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
         )}
         <textarea
           autoFocus={true}
-          id="set-license"
           className="display-block input-super-large"
+          id="set-license"
           onChange={this.handleLicenseChange}
           required={true}
           rows={8}
@@ -232,13 +254,13 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State>
         />
 
         <DeferredSpinner
-          loading={loading}
           customSpinner={
             <p className="spacer-top">
               <i className="spinner spacer-right text-bottom" />
               {translate('marketplace.checking_license')}
             </p>
-          }>
+          }
+          loading={loading}>
           {this.renderAlert()}
         </DeferredSpinner>
       </div>
index 158a52befeda7891f77c1b4c91b339d6cee84993..691f9c3613f770f38dab54744b65d19c34871ac4 100644 (file)
@@ -64,11 +64,15 @@ it('should display the get license link with parameters', async () => {
 });
 
 it('should correctly display status message after checking license', async () => {
-  let wrapper = await testLicenseStatus('NO_INSTALL', jest.fn());
+  let wrapper = await testLicenseStatus('NO_INSTALL');
   expect(wrapper.find('p.alert')).toMatchSnapshot();
-  wrapper = await testLicenseStatus('AUTOMATIC_INSTALL', jest.fn());
+  wrapper = await testLicenseStatus('AUTOMATIC_INSTALL');
   expect(wrapper.find('p.alert')).toMatchSnapshot();
-  wrapper = await testLicenseStatus('MANUAL_INSTALL', jest.fn());
+  wrapper = await testLicenseStatus('MANUAL_INSTALL');
+  expect(wrapper.find('p.alert')).toMatchSnapshot();
+  wrapper = await testLicenseStatus('AUTOMATIC_INSTALL', jest.fn(), 'bar');
+  expect(wrapper.find('p.alert')).toMatchSnapshot();
+  wrapper = await testLicenseStatus('AUTOMATIC_INSTALL', jest.fn(), 'bar', { edition: undefined });
   expect(wrapper.find('p.alert')).toMatchSnapshot();
 });
 
@@ -103,11 +107,16 @@ function getWrapper(props = {}) {
   );
 }
 
-async function testLicenseStatus(status: string, updateLicense: jest.Mock<any>) {
+async function testLicenseStatus(
+  status: string,
+  updateLicense = jest.fn(),
+  nextEditionKey = 'foo',
+  props = {}
+) {
   getLicensePreview.mockImplementation(() =>
-    Promise.resolve({ nextEditionKey: 'foo', previewStatus: status })
+    Promise.resolve({ nextEditionKey, previewStatus: status })
   );
-  const wrapper = getWrapper({ updateLicense });
+  const wrapper = getWrapper({ updateLicense, ...props });
   change(wrapper.find('textarea'), 'mylicense');
   expect(getLicensePreview).toHaveBeenCalled();
   await new Promise(setImmediate);
index 8631ff5d7d4370fbaa65f67ce17a624b198ae2f7..5ff0d2f7d376717afef2b9d69df98c8f1e1f8807 100644 (file)
@@ -24,6 +24,22 @@ exports[`should correctly display status message after checking license 3`] = `
 </p>
 `;
 
+exports[`should correctly display status message after checking license 4`] = `
+<p
+  className="alert alert-danger"
+>
+  marketplace.wrong_license_type_x.Foo
+</p>
+`;
+
+exports[`should correctly display status message after checking license 5`] = `
+<p
+  className="alert alert-danger"
+>
+  marketplace.wrong_license_type
+</p>
+`;
+
 exports[`should display correctly 1`] = `
 <div>
   <label
index ac534cbda9e2cdce95f6bc211e3845d1d5c58ccf..96ad44def59e2bf329f2f9b0772b2f63caa6dd35 100644 (file)
@@ -2171,6 +2171,7 @@ marketplace.how_to_install=How to install it?
 marketplace.see_documentation_to_enable_cluster=See {url} documentation to set up a cluster.
 marketplace.how_to_setup_cluster_url=Further configuration is required to set up a cluster. See {url} documentation.
 marketplace.enter_license_for_x=Enter your license key for {0}
+marketplace.wrong_license_type=Your license is not compatible with any existing editions. Please provide a valid license.
 marketplace.wrong_license_type_x=Your license is not compatible with the selected edition. Please provide a valid license for {0}.
 marketplace.i_need_a_license=I need a license key
 marketplace.download_package=Download package