diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-11-06 16:31:09 +0100 |
---|---|---|
committer | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-11-06 16:31:09 +0100 |
commit | 2a2dc6f30e574058065019aeb637b71b30661568 (patch) | |
tree | ee530e4eaab4c3643256d4e95acba03bda82c048 /server | |
parent | 7b64b5d27664c32bcca218cfbd2f89eb2dff845f (diff) | |
parent | 76accff06136fe38497ab843476134bb00855f34 (diff) | |
download | sonarqube-2a2dc6f30e574058065019aeb637b71b30661568.tar.gz sonarqube-2a2dc6f30e574058065019aeb637b71b30661568.zip |
Merge remote-tracking branch 'origin/branch-6.7'
Diffstat (limited to 'server')
6 files changed, 143 insertions, 105 deletions
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx index 414a768e485..f94c85cd727 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionForm.tsx @@ -81,7 +81,7 @@ export default class LicenseEditionForm extends React.PureComponent<Props, State render() { const { edition, isDowngrade } = this.props; - const { submitting, status } = this.state; + const { license, submitting, status } = this.state; const header = isDowngrade ? translateWithParameters('marketplace.downgrade_to_x', edition.name) @@ -102,7 +102,10 @@ export default class LicenseEditionForm extends React.PureComponent<Props, State <footer className="modal-foot"> {submitting && <i className="spinner spacer-right" />} {status && ( - <button className="js-confirm" onClick={this.handleConfirmClick} disabled={submitting}> + <button + className="js-confirm" + onClick={this.handleConfirmClick} + disabled={!license || submitting}> {status === 'AUTOMATIC_INSTALL' ? translate('marketplace.install') : translate('save')} diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionSet.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionSet.tsx index f33cb6a3911..919a6aac0c1 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionSet.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/components/LicenseEditionSet.tsx @@ -22,6 +22,7 @@ import * as React from 'react'; import * as classNames from 'classnames'; import { FormattedMessage } from 'react-intl'; import { debounce } from 'lodash'; +import Checkbox from '../../../components/controls/Checkbox'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; import { omitNil } from '../../../helpers/request'; import { Edition, getFormData, getLicensePreview } from '../../../api/marketplace'; @@ -35,6 +36,7 @@ export interface Props { } interface State { + acceptTerms: boolean; license: string; licenseEdition?: Edition; loading: boolean; @@ -50,7 +52,7 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State> constructor(props: Props) { super(props); - this.state = { license: '', loading: false }; + this.state = { acceptTerms: false, license: '', loading: false }; this.fetchLicensePreview = debounce(this.fetchLicensePreview, 100); } @@ -116,57 +118,93 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State> } }; + handleTermsCheck = (checked: boolean) => + this.setState({ acceptTerms: checked }, () => + this.updateLicense(this.state.license, this.state.licenseEdition, this.state.previewStatus) + ); + updateLicense = (license: string, licenseEdition?: Edition, previewStatus?: string) => { this.setState({ license, licenseEdition, loading: false, previewStatus }); - this.props.updateLicense(license, previewStatus); + this.props.updateLicense( + previewStatus !== 'NO_INSTALL' && !this.state.acceptTerms ? undefined : license, + previewStatus + ); }; renderAlert() { const { licenseEdition, previewStatus } = this.state; if (!previewStatus) { const { edition } = this.props; - if (edition && licenseEdition && edition.key !== licenseEdition.key) { - return ( - <p className="alert alert-danger spacer-top"> - {translateWithParameters('marketplace.wrong_license_type_x', edition.name)} - </p> - ); + if (!edition) { + return undefined; } - 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> + </div> + ); } return ( - <p - className={classNames('alert spacer-top', { - 'alert-warning': previewStatus === 'AUTOMATIC_INSTALL', - 'alert-success': previewStatus === 'NO_INSTALL', - 'alert-danger': previewStatus === 'MANUAL_INSTALL' - })}> - {translateWithParameters( - 'marketplace.license_preview_status.' + previewStatus, - licenseEdition ? licenseEdition.name : translate('marketplace.commercial_edition') - )} - {licenseEdition && - licenseEdition.key === 'datacenter' && - previewStatus !== 'NO_INSTALL' && ( - <span className="little-spacer-left"> - <FormattedMessage - defaultMessage={translate('marketplace.how_to_setup_cluster_url')} - id="marketplace.how_to_setup_cluster_url" - values={{ - url: ( - <a - href="https://redirect.sonarsource.com/doc/data-center-edition.html" - target="_blank"> - {licenseEdition.name} - </a> - ) - }} - /> - </span> + <div className="spacer-top"> + <p + className={classNames('alert', { + 'alert-warning': previewStatus === 'AUTOMATIC_INSTALL', + 'alert-success': previewStatus === 'NO_INSTALL', + 'alert-danger': previewStatus === 'MANUAL_INSTALL' + })}> + {translateWithParameters( + 'marketplace.license_preview_status.' + previewStatus, + licenseEdition ? licenseEdition.name : translate('marketplace.commercial_edition') )} - </p> + {licenseEdition && + licenseEdition.key === 'datacenter' && + previewStatus !== 'NO_INSTALL' && ( + <span className="little-spacer-left"> + <FormattedMessage + defaultMessage={translate('marketplace.how_to_setup_cluster_url')} + id="marketplace.how_to_setup_cluster_url" + values={{ + url: ( + <a + href="https://redirect.sonarsource.com/doc/data-center-edition.html" + target="_blank"> + {licenseEdition.name} + </a> + ) + }} + /> + </span> + )} + </p> + {previewStatus !== 'NO_INSTALL' && ( + <span className="js-edition-tos"> + <Checkbox + checked={this.state.acceptTerms} + id="edition-terms" + onCheck={this.handleTermsCheck}> + <label className="little-spacer-left" htmlFor="edition-terms"> + {translate('marketplace.i_accept_the')} + </label> + </Checkbox> + <a + className="nowrap little-spacer-left" + href="http://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf" + target="_blank"> + {translate('marketplace.terms_and_conditions')} + </a> + </span> + )} + </div> ); } @@ -194,7 +232,6 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State> /> <DeferredSpinner - className="spacer-top" loading={loading} customSpinner={ <p className="spacer-top"> @@ -204,15 +241,6 @@ export default class LicenseEditionSet extends React.PureComponent<Props, State> }> {this.renderAlert()} </DeferredSpinner> - - {edition && ( - <a - className="display-inline-block spacer-top" - href={this.getLicenseFormUrl(edition)} - target="_blank"> - {translate('marketplace.i_need_a_license')} - </a> - )} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx index 029cb562059..aff09744528 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionForm-test.tsx @@ -48,15 +48,28 @@ it('should display correctly', () => { expect(getWrapper()).toMatchSnapshot(); }); -it('should correctly change the button based on the status', () => { +it('should correctly change the button based on the status and license', () => { const wrapper = getWrapper(); + let button; (wrapper.instance() as LicenseEditionForm).mounted = true; - wrapper.setState({ status: 'NO_INSTALL' }); - expect(wrapper.find('button')).toMatchSnapshot(); + + wrapper.setState({ license: 'mylicense', status: 'NO_INSTALL' }); + button = wrapper.find('button'); + expect(button.text()).toBe('save'); + expect(button.prop('disabled')).toBeFalsy(); + + wrapper.setState({ license: undefined, status: 'MANUAL_INSTALL' }); + button = wrapper.find('button'); + expect(button.text()).toBe('save'); + expect(button.prop('disabled')).toBeTruthy(); + wrapper.setState({ status: 'AUTOMATIC_INSTALL' }); - expect(wrapper.find('button')).toMatchSnapshot(); - wrapper.setState({ status: 'MANUAL_INSTALL' }); - expect(wrapper.find('button')).toMatchSnapshot(); + button = wrapper.find('button'); + expect(button.text()).toContain('install'); + expect(button.prop('disabled')).toBeTruthy(); + + wrapper.setState({ license: 'mylicense' }); + expect(wrapper.find('button').prop('disabled')).toBeFalsy(); }); it('should update the edition status after install', async () => { diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionSet-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionSet-test.tsx index 5efe571d861..846f65e191d 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionSet-test.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/LicenseEditionSet-test.tsx @@ -32,7 +32,7 @@ jest.mock('../../../../api/marketplace', () => ({ jest.mock('lodash', () => { const lodash = require.requireActual('lodash'); - lodash.debounce = (fn: Function) => (...args: any[]) => fn(args); + lodash.debounce = (fn: Function) => (...args: any[]) => fn(...args); return lodash; }); @@ -65,9 +65,32 @@ it('should display the get license link with parameters', async () => { }); it('should correctly display status message after checking license', async () => { - await testLicenseStatus('NO_INSTALL'); - await testLicenseStatus('AUTOMATIC_INSTALL'); - await testLicenseStatus('MANUAL_INSTALL'); + let wrapper = await testLicenseStatus('NO_INSTALL', jest.fn()); + expect(wrapper.find('p.alert')).toMatchSnapshot(); + wrapper = await testLicenseStatus('AUTOMATIC_INSTALL', jest.fn()); + expect(wrapper.find('p.alert')).toMatchSnapshot(); + wrapper = await testLicenseStatus('MANUAL_INSTALL', jest.fn()); + expect(wrapper.find('p.alert')).toMatchSnapshot(); +}); + +it('should display terms of license checkbox', async () => { + let updateLicense = jest.fn(); + let wrapper = await testLicenseStatus('NO_INSTALL', updateLicense); + expect(wrapper.find('.js-edition-tos').exists()).toBeFalsy(); + expect(updateLicense).toHaveBeenCalledWith('mylicense', 'NO_INSTALL'); + + updateLicense = jest.fn(); + wrapper = await testLicenseStatus('AUTOMATIC_INSTALL', updateLicense); + const tosCheckbox = wrapper.find('.js-edition-tos'); + expect(tosCheckbox.find('a').exists()).toBeTruthy(); + expect(updateLicense).toHaveBeenLastCalledWith(undefined, 'AUTOMATIC_INSTALL'); + (tosCheckbox.find('Checkbox').prop('onCheck') as Function)(true); + expect(updateLicense).toHaveBeenLastCalledWith('mylicense', 'AUTOMATIC_INSTALL'); + + updateLicense = jest.fn(); + wrapper = await testLicenseStatus('MANUAL_INSTALL', updateLicense); + expect(wrapper.find('.js-edition-tos').exists()).toBeTruthy(); + expect(updateLicense).toHaveBeenLastCalledWith(undefined, 'MANUAL_INSTALL'); }); function getWrapper(props = {}) { @@ -81,16 +104,15 @@ function getWrapper(props = {}) { ); } -async function testLicenseStatus(status: string) { +async function testLicenseStatus(status: string, updateLicense: jest.Mock<any>) { getLicensePreview.mockImplementation(() => Promise.resolve({ nextEditionKey: 'foo', previewStatus: status }) ); - const updateLicense = jest.fn(); const wrapper = getWrapper({ updateLicense }); change(wrapper.find('textarea'), 'mylicense'); expect(getLicensePreview).toHaveBeenCalled(); await new Promise(setImmediate); expect(updateLicense).toHaveBeenCalled(); wrapper.update(); - expect(wrapper.find('p.alert')).toMatchSnapshot(); + return wrapper; } diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap index 6e1defbecd0..c70a6a6abb0 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionForm-test.tsx.snap @@ -1,35 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should correctly change the button based on the status 1`] = ` -<button - className="js-confirm" - disabled={false} - onClick={[Function]} -> - save -</button> -`; - -exports[`should correctly change the button based on the status 2`] = ` -<button - className="js-confirm" - disabled={false} - onClick={[Function]} -> - marketplace.install -</button> -`; - -exports[`should correctly change the button based on the status 3`] = ` -<button - className="js-confirm" - disabled={false} - onClick={[Function]} -> - save -</button> -`; - exports[`should display correctly 1`] = ` <Modal contentLabel="marketplace.upgrade_to_x.Foo" diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionSet-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionSet-test.tsx.snap index 6026ff03d97..8631ff5d7d4 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionSet-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/LicenseEditionSet-test.tsx.snap @@ -2,7 +2,7 @@ exports[`should correctly display status message after checking license 1`] = ` <p - className="alert spacer-top alert-success" + className="alert alert-success" > marketplace.license_preview_status.NO_INSTALL.Foo </p> @@ -10,7 +10,7 @@ exports[`should correctly display status message after checking license 1`] = ` exports[`should correctly display status message after checking license 2`] = ` <p - className="alert spacer-top alert-warning" + className="alert alert-warning" > marketplace.license_preview_status.AUTOMATIC_INSTALL.Foo </p> @@ -18,7 +18,7 @@ exports[`should correctly display status message after checking license 2`] = ` exports[`should correctly display status message after checking license 3`] = ` <p - className="alert spacer-top alert-danger" + className="alert alert-danger" > marketplace.license_preview_status.MANUAL_INSTALL.Foo </p> @@ -52,7 +52,6 @@ exports[`should display correctly 1`] = ` value="" /> <DeferredSpinner - className="spacer-top" customSpinner={ <p className="spacer-top" @@ -65,20 +64,23 @@ exports[`should display correctly 1`] = ` } loading={false} timeout={100} - /> - <a - className="display-inline-block spacer-top" - href="license_url" - target="_blank" > - marketplace.i_need_a_license - </a> + <div + className="spacer-top" + > + <a + href="license_url" + target="_blank" + > + marketplace.i_need_a_license + </a> + </div> + </DeferredSpinner> </div> `; exports[`should display the get license link with parameters 1`] = ` <a - className="display-inline-block spacer-top" href="license_url?serverId=foo&ncloc=1000" target="_blank" > |