]> source.dussan.org Git - sonarqube.git/commitdiff
SONARCLOUD-138 Make forms clearer when upgrading an organization (#761)
authorStas Vilchik <stas.vilchik@sonarsource.com>
Fri, 28 Sep 2018 14:49:25 +0000 (16:49 +0200)
committerSonarTech <sonartech@sonarsource.com>
Fri, 12 Oct 2018 18:20:58 +0000 (20:20 +0200)
21 files changed:
server/sonar-docs/src/tooltips/billing/coupon.md [deleted file]
server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts
server/sonar-web/src/main/js/apps/create/organization/BillingFormShim.tsx
server/sonar-web/src/main/js/apps/create/organization/CardForm.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/CouponForm.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/PaymentMethodSelect.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/PlanStep.tsx
server/sonar-web/src/main/js/apps/create/organization/__mocks__/BillingFormShim.tsx
server/sonar-web/src/main/js/apps/create/organization/__tests__/BillingFormShim-test.tsx
server/sonar-web/src/main/js/apps/create/organization/__tests__/CardForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/CouponForm-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/PaymentMethodSelect-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/PlanStep-test.tsx
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/BillingFormShim-test.tsx.snap
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CardForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CouponForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PaymentMethodSelect-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PlanStep-test.tsx.snap
server/sonar-web/src/main/js/apps/tutorials/styles.css
server/sonar-web/src/main/js/components/controls/HelpTooltip.tsx
sonar-core/src/main/resources/org/sonar/l10n/core.properties

diff --git a/server/sonar-docs/src/tooltips/billing/coupon.md b/server/sonar-docs/src/tooltips/billing/coupon.md
deleted file mode 100644 (file)
index 50319db..0000000
+++ /dev/null
@@ -1 +0,0 @@
-A coupon is a way to pay for yearly subscriptions or to use other payment methods than card. Contact us for more information.
index 3198accbe067ed6657a939581948aead7d82c441..c4fc23fa0db95afffa70b7728bc4e64d00bd0da8 100644 (file)
@@ -62,6 +62,7 @@ import ActionsDropdown, { ActionsDropdownItem } from '../../../components/contro
 import ConfirmButton from '../../../components/controls/ConfirmButton';
 import SimpleModal from '../../../components/controls/SimpleModal';
 import SearchSelect from '../../../components/controls/SearchSelect';
+import RadioToggle from '../../../components/controls/RadioToggle';
 
 const exposeLibraries = () => {
   const global = window as any;
@@ -103,6 +104,7 @@ const exposeLibraries = () => {
     Modal,
     PullRequestIcon,
     QualifierIcon,
+    RadioToggle,
     Rating,
     ReloadButton,
     ResetButtonLink,
index f08e3ffc80e9f4c95fe229c9a084e342f20421c8..df4a59ebce67b0fc310f831207bfafe5f8a3f267 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import { CurrentUser, SubscriptionPlan, Coupon } from '../../../app/types';
+import { CurrentUser, SubscriptionPlan } from '../../../app/types';
 
 interface ChildrenProps {
-  alertError: string | undefined;
-  couponValue: string;
   onSubmit: React.FormEventHandler;
-  renderAdditionalInfo: () => React.ReactNode;
-  renderBillingNameInput: () => React.ReactNode;
-  renderBraintreeClient: () => React.ReactNode;
-  renderCountrySelect: () => React.ReactNode;
-  renderCouponInput: (children?: React.ReactNode) => React.ReactNode;
-  renderEmailInput: () => React.ReactNode;
-  renderNextCharge: () => React.ReactNode;
-  renderPlanSelect: () => React.ReactNode;
-  renderResetButton: () => React.ReactNode;
-  renderSpinner: () => React.ReactNode;
-  renderSubmitButton: (text?: string) => React.ReactNode;
-  renderTermsOfService: () => React.ReactNode;
-  renderTypeOfUseSelect: () => React.ReactNode;
+  renderFormFields: () => React.ReactElement<any>;
+  renderSubmitGroup: (submitText?: string) => React.ReactElement<any>;
 }
 
 interface Props {
   children: (props: ChildrenProps) => React.ReactElement<any>;
-  country?: string;
+  initialCountry?: string;
   currentUser: CurrentUser;
-  onClose: () => void;
   onCommit: () => void;
-  onCouponUpdate?: (coupon?: Coupon) => void;
   onFailToUpgrade?: () => void;
   organizationKey: string | (() => Promise<string>);
-  skipBraintreeInit?: boolean;
   subscriptionPlans: SubscriptionPlan[];
 }
 
diff --git a/server/sonar-web/src/main/js/apps/create/organization/CardForm.tsx b/server/sonar-web/src/main/js/apps/create/organization/CardForm.tsx
deleted file mode 100644 (file)
index 39a739f..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import * as classNames from 'classnames';
-import BillingFormShim from './BillingFormShim';
-import { withCurrentUser } from './withCurrentUser';
-import { CurrentUser, SubscriptionPlan } from '../../../app/types';
-import { translate } from '../../../helpers/l10n';
-
-interface Props {
-  createOrganization: () => Promise<string>;
-  currentUser: CurrentUser;
-  onFailToUpgrade: () => void;
-  onSubmit: () => void;
-  subscriptionPlans: SubscriptionPlan[];
-}
-
-export class CardForm extends React.PureComponent<Props> {
-  handleClose = () => {
-    // do nothing
-  };
-
-  render() {
-    return (
-      <div className="huge-spacer-top">
-        <BillingFormShim
-          currentUser={this.props.currentUser}
-          onClose={this.handleClose}
-          onCommit={this.props.onSubmit}
-          onFailToUpgrade={this.props.onFailToUpgrade}
-          organizationKey={this.props.createOrganization}
-          subscriptionPlans={this.props.subscriptionPlans}>
-          {form => (
-            <form onSubmit={form.onSubmit}>
-              <div className="columns column-show-overflow">
-                <div className="column-half">
-                  <h3>{translate('billing.upgrade.billing_info')}</h3>
-                  {form.renderEmailInput()}
-                  {form.renderTypeOfUseSelect()}
-                  {form.renderBillingNameInput()}
-                  {form.renderCountrySelect()}
-                  {form.renderAdditionalInfo()}
-                </div>
-                <div className="column-half">
-                  <h3>{translate('billing.upgrade.plan')}</h3>
-                  {form.renderPlanSelect()}
-                  <h3>{translate('billing.upgrade.card_info')}</h3>
-                  {form.renderBraintreeClient()}
-                </div>
-              </div>
-              <div className="upgrade-footer big-spacer-top">
-                {form.renderNextCharge()}
-                <hr className="big-spacer-bottom" />
-                {form.alertError && <p className="alert alert-danger">{form.alertError}</p>}
-              </div>
-              <div
-                className={classNames({
-                  'big-spacer-top': form.alertError !== undefined
-                })}>
-                {form.renderSpinner()}
-                {form.renderSubmitButton(
-                  translate('onboarding.create_organization.create_and_upgrade')
-                )}
-              </div>
-              {form.renderTermsOfService()}
-            </form>
-          )}
-        </BillingFormShim>
-      </div>
-    );
-  }
-}
-
-export default withCurrentUser(CardForm);
diff --git a/server/sonar-web/src/main/js/apps/create/organization/CouponForm.tsx b/server/sonar-web/src/main/js/apps/create/organization/CouponForm.tsx
deleted file mode 100644 (file)
index fc0a7ab..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import * as classNames from 'classnames';
-import BillingFormShim from './BillingFormShim';
-import { withCurrentUser } from './withCurrentUser';
-import { CurrentUser, Coupon } from '../../../app/types';
-import { translate } from '../../../helpers/l10n';
-import DocTooltip from '../../../components/docs/DocTooltip';
-
-interface Props {
-  createOrganization: () => Promise<string>;
-  currentUser: CurrentUser;
-  onFailToUpgrade: () => void;
-  onSubmit: () => void;
-}
-
-interface State {
-  coupon?: Coupon;
-}
-
-export class CouponForm extends React.PureComponent<Props, State> {
-  state: State = {};
-
-  handleClose = () => {
-    // do nothing
-  };
-
-  handleCouponUpdate = (coupon?: Coupon) => {
-    this.setState({ coupon });
-  };
-
-  renderBillingInformation() {
-    if (!this.state.coupon || !this.state.coupon.billing) {
-      return null;
-    }
-    const { billing } = this.state.coupon;
-    return (
-      <div className="big-spacer-top big-spacer-bottom" id="coupon-billing-information">
-        <h3 className="note">{translate('billing.upgrade.billing_info')}</h3>
-        <ul className="note">
-          {Boolean(billing.name) && <li>{billing.name}</li>}
-          {Boolean(billing.address) && <li>{billing.address}</li>}
-          {Boolean(billing.country) && <li>{billing.country}</li>}
-          {Boolean(billing.email) && <li>{billing.email}</li>}
-        </ul>
-      </div>
-    );
-  }
-
-  render() {
-    return (
-      <div className="huge-spacer-top">
-        <BillingFormShim
-          currentUser={this.props.currentUser}
-          onClose={this.handleClose}
-          onCommit={this.props.onSubmit}
-          onCouponUpdate={this.handleCouponUpdate}
-          onFailToUpgrade={this.props.onFailToUpgrade}
-          organizationKey={this.props.createOrganization}
-          skipBraintreeInit={true}
-          subscriptionPlans={[]}>
-          {form => (
-            <form onSubmit={form.onSubmit}>
-              {form.renderCouponInput(
-                <label htmlFor="coupon">
-                  {translate('billing.upgrade.coupon')}
-                  <DocTooltip
-                    className="little-spacer-left"
-                    doc={import(/* webpackMode: "eager" */ 'Docs/tooltips/billing/coupon.md')}
-                  />
-                </label>
-              )}
-              {this.renderBillingInformation()}
-              {this.state.coupon &&
-                !this.state.coupon.billing && (
-                  <>
-                    <h3 className="big-spacer-top">{translate('billing.upgrade.billing_info')}</h3>
-                    {form.renderEmailInput()}
-                    {form.renderTypeOfUseSelect()}
-                    {form.renderBillingNameInput()}
-                    {form.renderCountrySelect()}
-                    {form.renderAdditionalInfo()}
-                  </>
-                )}
-              {this.state.coupon && (
-                <div className="big-spacer-bottom">{form.renderNextCharge()}</div>
-              )}
-              {form.alertError && <p className="alert alert-danger">{form.alertError}</p>}
-              <div className={classNames({ 'big-spacer-top': form.alertError !== undefined })}>
-                {form.renderSpinner()}
-                {form.renderSubmitButton(
-                  translate('onboarding.create_organization.create_and_upgrade')
-                )}
-              </div>
-              {form.renderTermsOfService()}
-            </form>
-          )}
-        </BillingFormShim>
-      </div>
-    );
-  }
-}
-
-export default withCurrentUser(CouponForm);
diff --git a/server/sonar-web/src/main/js/apps/create/organization/PaymentMethodSelect.tsx b/server/sonar-web/src/main/js/apps/create/organization/PaymentMethodSelect.tsx
deleted file mode 100644 (file)
index ddf5372..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import RadioToggle from '../../../components/controls/RadioToggle';
-import { translate } from '../../../helpers/l10n';
-
-export enum PaymentMethod {
-  Card = 'card',
-  Coupon = 'coupon'
-}
-
-interface Props {
-  onChange: (paymentMethod: PaymentMethod) => void;
-  paymentMethod: PaymentMethod | undefined;
-}
-
-export default class PaymentMethodSelect extends React.PureComponent<Props> {
-  render() {
-    const options = Object.values(PaymentMethod).map(value => ({
-      label: translate('billing', value),
-      value
-    }));
-
-    return (
-      <div>
-        <label className="spacer-bottom">
-          {translate('onboarding.create_organization.choose_payment_method')}
-        </label>
-        <div className="little-spacer-top">
-          <RadioToggle
-            name="payment-method"
-            onCheck={this.props.onChange}
-            options={options}
-            value={this.props.paymentMethod}
-          />
-        </div>
-      </div>
-    );
-  }
-}
index f715a4f4d48ec7610c57adbe1992c3a6c68384cf..5118540ce8184b16aa8d8cea73c5bc8157867a21 100644 (file)
@@ -18,9 +18,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import PaymentMethodSelect, { PaymentMethod } from './PaymentMethodSelect';
-import CardForm from './CardForm';
-import CouponForm from './CouponForm';
+import BillingFormShim from './BillingFormShim';
+import { withCurrentUser } from './withCurrentUser';
 import PlanSelect, { Plan } from './PlanSelect';
 import Step from '../../tutorials/components/Step';
 import { translate } from '../../../helpers/l10n';
@@ -29,6 +28,8 @@ import { SubscriptionPlan } from '../../../app/types';
 import { SubmitButton } from '../../../components/ui/buttons';
 import DeferredSpinner from '../../../components/common/DeferredSpinner';
 
+const BillingForm = withCurrentUser(BillingFormShim);
+
 interface Props {
   createOrganization: () => Promise<string>;
   deleteOrganization: () => void;
@@ -41,7 +42,6 @@ interface Props {
 }
 
 interface State {
-  paymentMethod?: PaymentMethod;
   plan: Plan;
   ready: boolean;
   submitting: boolean;
@@ -79,10 +79,6 @@ export default class PlanStep extends React.PureComponent<Props, State> {
     this.setState({ plan });
   };
 
-  handlePaymentMethodChange = (paymentMethod: PaymentMethod) => {
-    this.setState({ paymentMethod });
-  };
-
   stopSubmitting = () => {
     if (this.mounted) {
       this.setState({ submitting: false });
@@ -108,27 +104,22 @@ export default class PlanStep extends React.PureComponent<Props, State> {
             )}
 
             {this.state.plan === Plan.Paid ? (
-              <>
-                <PaymentMethodSelect
-                  onChange={this.handlePaymentMethodChange}
-                  paymentMethod={this.state.paymentMethod}
-                />
-                {this.state.paymentMethod === PaymentMethod.Card && (
-                  <CardForm
-                    createOrganization={this.props.createOrganization}
-                    onFailToUpgrade={this.props.deleteOrganization}
-                    onSubmit={this.props.onPaidPlanChoose}
-                    subscriptionPlans={this.props.subscriptionPlans}
-                  />
-                )}
-                {this.state.paymentMethod === PaymentMethod.Coupon && (
-                  <CouponForm
-                    createOrganization={this.props.createOrganization}
-                    onFailToUpgrade={this.props.deleteOrganization}
-                    onSubmit={this.props.onPaidPlanChoose}
-                  />
+              <BillingForm
+                onCommit={this.props.onPaidPlanChoose}
+                onFailToUpgrade={this.props.deleteOrganization}
+                organizationKey={this.props.createOrganization}
+                subscriptionPlans={this.props.subscriptionPlans}>
+                {({ onSubmit, renderFormFields, renderSubmitGroup }) => (
+                  <form onSubmit={onSubmit}>
+                    {renderFormFields()}
+                    <div className="billing-input-large big-spacer-top">
+                      {renderSubmitGroup(
+                        translate('onboarding.create_organization.create_and_upgrade')
+                      )}
+                    </div>
+                  </form>
                 )}
-              </>
+              </BillingForm>
             ) : (
               <div className="display-flex-center big-spacer-top">
                 <SubmitButton disabled={this.state.submitting} onClick={this.handleFreePlanSubmit}>
index 4c9b4e3596ae97bc179abcf987ec290b33a3d296..48f5e0dc984d291f5e84b2104f84e63ec902ab0f 100644 (file)
@@ -24,22 +24,9 @@ export default class BillingFormShim extends React.Component<{ children: any }>
     return (
       <div id="BillingFormShim">
         {this.props.children({
-          alertError: undefined,
-          couponValue: '',
           onSubmit: jest.fn(),
-          renderAdditionalInfo: () => <div id="additional-info" />,
-          renderBillingNameInput: () => <div id="billing-name" />,
-          renderBraintreeClient: () => <div id="braintree-client" />,
-          renderCountrySelect: () => <div id="country-select" />,
-          renderCouponInput: () => <div id="coupon-input" />,
-          renderEmailInput: () => <div id="email-input" />,
-          renderNextCharge: () => <div id="next-charge" />,
-          renderPlanSelect: () => <div id="plan-select" />,
-          renderResetButton: () => <div id="reset-button" />,
-          renderSpinner: () => <div id="spinner" />,
-          renderSubmitButton: () => <div id="submit-button" />,
-          renderTermsOfService: () => <div id="terms-of-service" />,
-          renderTypeOfUseSelect: () => <div id="type-of-use-select" />
+          renderFormFields: () => <div id="form-fields" />,
+          renderSubmitGroup: () => <div id="submit-group" />
         })}
       </div>
     );
index 91e2eb8a4ef9cc617aaca00e3543f02727f2ba50..71119febaf6eb3b0b994900fdd000c2fbc607673 100644 (file)
@@ -38,7 +38,6 @@ it('should render', () => {
     shallow(
       <BillingFormShim
         currentUser={{ isLoggedIn: false }}
-        onClose={jest.fn()}
         onCommit={jest.fn()}
         organizationKey="org"
         subscriptionPlans={[]}>
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/CardForm-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/CardForm-test.tsx
deleted file mode 100644 (file)
index 0d8c015..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import { CardForm } from '../CardForm';
-
-jest.mock('../BillingFormShim');
-
-it('should render', () => {
-  const wrapper = shallow(
-    <CardForm
-      createOrganization={jest.fn()}
-      currentUser={{ isLoggedIn: false }}
-      onFailToUpgrade={jest.fn()}
-      onSubmit={jest.fn()}
-      subscriptionPlans={[{ maxNcloc: 100000, price: 10 }, { maxNcloc: 250000, price: 75 }]}
-    />
-  );
-  expect(wrapper).toMatchSnapshot();
-  expect(wrapper.find('BillingFormShim').dive()).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/CouponForm-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/CouponForm-test.tsx
deleted file mode 100644 (file)
index 110e213..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import { CouponForm } from '../CouponForm';
-
-jest.mock('../BillingFormShim');
-
-it('should render', () => {
-  const wrapper = shallow(
-    <CouponForm
-      createOrganization={jest.fn()}
-      currentUser={{ isLoggedIn: false }}
-      onFailToUpgrade={jest.fn()}
-      onSubmit={jest.fn()}
-    />
-  );
-  expect(wrapper).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/PaymentMethodSelect-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/PaymentMethodSelect-test.tsx
deleted file mode 100644 (file)
index fea97e7..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as React from 'react';
-import { shallow } from 'enzyme';
-import PaymentMethodSelect, { PaymentMethod } from '../PaymentMethodSelect';
-
-it('should render and change', () => {
-  const onChange = jest.fn();
-  const wrapper = shallow(<PaymentMethodSelect onChange={onChange} paymentMethod={undefined} />);
-  expect(wrapper).toMatchSnapshot();
-
-  wrapper.find('RadioToggle').prop<Function>('onCheck')(PaymentMethod.Card);
-  expect(onChange).toBeCalledWith(PaymentMethod.Card);
-
-  wrapper.setProps({ paymentMethod: PaymentMethod.Card });
-  expect(wrapper).toMatchSnapshot();
-});
index ff6937f0014395924a1fbf35df5a5bc5ae690ea7..876a20f0bfd19e1d905c5afc9bb318ea5302700e 100644 (file)
@@ -22,7 +22,6 @@ import { shallow } from 'enzyme';
 import PlanStep from '../PlanStep';
 import { waitAndUpdate, click } from '../../../../helpers/testUtils';
 import { Plan } from '../PlanSelect';
-import { PaymentMethod } from '../PaymentMethodSelect';
 
 jest.mock('../../../../app/components/extensions/utils', () => ({
   getExtensionStart: jest.fn().mockResolvedValue(undefined)
@@ -49,7 +48,7 @@ it('should render and use free plan', async () => {
   expect(onFreePlanChoose).toBeCalled();
 });
 
-it('should upgrade using card', async () => {
+it('should upgrade', async () => {
   const onPaidPlanChoose = jest.fn();
   const wrapper = shallow(
     <PlanStep
@@ -72,48 +71,8 @@ it('should upgrade using card', async () => {
 
   wrapper
     .dive()
-    .find('PaymentMethodSelect')
-    .prop<Function>('onChange')(PaymentMethod.Card);
-  expect(wrapper.dive()).toMatchSnapshot();
-
-  wrapper
-    .dive()
-    .find('Connect(withCurrentUser(CardForm))')
-    .prop<Function>('onSubmit')();
-  expect(onPaidPlanChoose).toBeCalled();
-});
-
-it('should upgrade using coupon', async () => {
-  const onPaidPlanChoose = jest.fn();
-  const wrapper = shallow(
-    <PlanStep
-      createOrganization={jest.fn().mockResolvedValue('org')}
-      deleteOrganization={jest.fn().mockResolvedValue(undefined)}
-      onFreePlanChoose={jest.fn().mockResolvedValue(undefined)}
-      onPaidPlanChoose={onPaidPlanChoose}
-      open={true}
-      startingPrice="10"
-      subscriptionPlans={[]}
-    />
-  );
-  await waitAndUpdate(wrapper);
-
-  wrapper
-    .dive()
-    .find('PlanSelect')
-    .prop<Function>('onChange')(Plan.Paid);
-  expect(wrapper.dive()).toMatchSnapshot();
-
-  wrapper
-    .dive()
-    .find('PaymentMethodSelect')
-    .prop<Function>('onChange')(PaymentMethod.Coupon);
-  expect(wrapper.dive()).toMatchSnapshot();
-
-  wrapper
-    .dive()
-    .find('Connect(withCurrentUser(CouponForm))')
-    .prop<Function>('onSubmit')();
+    .find('Connect(withCurrentUser(BillingFormShim))')
+    .prop<Function>('onCommit')();
   expect(onPaidPlanChoose).toBeCalled();
 });
 
index 5ed8a8cf9209571c907e87943fd50033f25789f7..3ab9b1995c64e6600596db885c5aedf05a204075 100644 (file)
@@ -7,7 +7,6 @@ exports[`should render 1`] = `
       "isLoggedIn": false,
     }
   }
-  onClose={[MockFunction]}
   onCommit={[MockFunction]}
   organizationKey="org"
   subscriptionPlans={Array []}
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CardForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CardForm-test.tsx.snap
deleted file mode 100644 (file)
index 6d8afde..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<div
-  className="huge-spacer-top"
->
-  <BillingFormShim
-    currentUser={
-      Object {
-        "isLoggedIn": false,
-      }
-    }
-    onClose={[Function]}
-    onCommit={[MockFunction]}
-    onFailToUpgrade={[MockFunction]}
-    organizationKey={[MockFunction]}
-    subscriptionPlans={
-      Array [
-        Object {
-          "maxNcloc": 100000,
-          "price": 10,
-        },
-        Object {
-          "maxNcloc": 250000,
-          "price": 75,
-        },
-      ]
-    }
-  />
-</div>
-`;
-
-exports[`should render 2`] = `
-<div
-  id="BillingFormShim"
->
-  <form
-    onSubmit={[MockFunction]}
-  >
-    <div
-      className="columns column-show-overflow"
-    >
-      <div
-        className="column-half"
-      >
-        <h3>
-          billing.upgrade.billing_info
-        </h3>
-        <div
-          id="email-input"
-        />
-        <div
-          id="type-of-use-select"
-        />
-        <div
-          id="billing-name"
-        />
-        <div
-          id="country-select"
-        />
-        <div
-          id="additional-info"
-        />
-      </div>
-      <div
-        className="column-half"
-      >
-        <h3>
-          billing.upgrade.plan
-        </h3>
-        <div
-          id="plan-select"
-        />
-        <h3>
-          billing.upgrade.card_info
-        </h3>
-        <div
-          id="braintree-client"
-        />
-      </div>
-    </div>
-    <div
-      className="upgrade-footer big-spacer-top"
-    >
-      <div
-        id="next-charge"
-      />
-      <hr
-        className="big-spacer-bottom"
-      />
-    </div>
-    <div
-      className=""
-    >
-      <div
-        id="spinner"
-      />
-      <div
-        id="submit-button"
-      />
-    </div>
-    <div
-      id="terms-of-service"
-    />
-  </form>
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CouponForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/CouponForm-test.tsx.snap
deleted file mode 100644 (file)
index b6a054b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render 1`] = `
-<div
-  className="huge-spacer-top"
->
-  <BillingFormShim
-    currentUser={
-      Object {
-        "isLoggedIn": false,
-      }
-    }
-    onClose={[Function]}
-    onCommit={[MockFunction]}
-    onCouponUpdate={[Function]}
-    onFailToUpgrade={[MockFunction]}
-    organizationKey={[MockFunction]}
-    skipBraintreeInit={true}
-    subscriptionPlans={Array []}
-  />
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PaymentMethodSelect-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/PaymentMethodSelect-test.tsx.snap
deleted file mode 100644 (file)
index 101582f..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render and change 1`] = `
-<div>
-  <label
-    className="spacer-bottom"
-  >
-    onboarding.create_organization.choose_payment_method
-  </label>
-  <div
-    className="little-spacer-top"
-  >
-    <RadioToggle
-      disabled={false}
-      name="payment-method"
-      onCheck={[MockFunction]}
-      options={
-        Array [
-          Object {
-            "label": "billing.card",
-            "value": "card",
-          },
-          Object {
-            "label": "billing.coupon",
-            "value": "coupon",
-          },
-        ]
-      }
-      value={null}
-    />
-  </div>
-</div>
-`;
-
-exports[`should render and change 2`] = `
-<div>
-  <label
-    className="spacer-bottom"
-  >
-    onboarding.create_organization.choose_payment_method
-  </label>
-  <div
-    className="little-spacer-top"
-  >
-    <RadioToggle
-      disabled={false}
-      name="payment-method"
-      onCheck={
-        [MockFunction] {
-          "calls": Array [
-            Array [
-              "card",
-            ],
-          ],
-          "results": Array [
-            Object {
-              "isThrow": false,
-              "value": undefined,
-            },
-          ],
-        }
-      }
-      options={
-        Array [
-          Object {
-            "label": "billing.card",
-            "value": "card",
-          },
-          Object {
-            "label": "billing.coupon",
-            "value": "coupon",
-          },
-        ]
-      }
-      value="card"
-    />
-  </div>
-</div>
-`;
index 099c34d7256f79c2f1f40ff087cc36751caed19a..d727d30c24bb80cb02648b7ce8497b388b3c08f5 100644 (file)
@@ -35,11 +35,12 @@ exports[`should preselect paid plan 2`] = `
       className="boxed-group-inner"
     >
       <React.Fragment>
-        <React.Fragment>
-          <PaymentMethodSelect
-            onChange={[Function]}
-          />
-        </React.Fragment>
+        <Connect(withCurrentUser(BillingFormShim))
+          onCommit={[MockFunction]}
+          onFailToUpgrade={[MockFunction]}
+          organizationKey={[MockFunction]}
+          subscriptionPlans={Array []}
+        />
       </React.Fragment>
     </div>
   </div>
@@ -102,46 +103,7 @@ exports[`should render and use free plan 2`] = `
 </div>
 `;
 
-exports[`should upgrade using card 1`] = `
-<div
-  className="boxed-group onboarding-step is-open"
->
-  <div
-    className="onboarding-step-number"
-  >
-    2
-  </div>
-  <div
-    className="boxed-group-header"
-  >
-    <h2>
-      onboarding.create_organization.choose_plan
-    </h2>
-  </div>
-  <div
-    className=""
-  >
-    <div
-      className="boxed-group-inner"
-    >
-      <React.Fragment>
-        <PlanSelect
-          onChange={[Function]}
-          plan="paid"
-          startingPrice="10"
-        />
-        <React.Fragment>
-          <PaymentMethodSelect
-            onChange={[Function]}
-          />
-        </React.Fragment>
-      </React.Fragment>
-    </div>
-  </div>
-</div>
-`;
-
-exports[`should upgrade using card 2`] = `
+exports[`should upgrade 1`] = `
 <div
   className="boxed-group onboarding-step is-open"
 >
@@ -169,102 +131,12 @@ exports[`should upgrade using card 2`] = `
           plan="paid"
           startingPrice="10"
         />
-        <React.Fragment>
-          <PaymentMethodSelect
-            onChange={[Function]}
-            paymentMethod="card"
-          />
-          <Connect(withCurrentUser(CardForm))
-            createOrganization={[MockFunction]}
-            onFailToUpgrade={[MockFunction]}
-            onSubmit={[MockFunction]}
-            subscriptionPlans={Array []}
-          />
-        </React.Fragment>
-      </React.Fragment>
-    </div>
-  </div>
-</div>
-`;
-
-exports[`should upgrade using coupon 1`] = `
-<div
-  className="boxed-group onboarding-step is-open"
->
-  <div
-    className="onboarding-step-number"
-  >
-    2
-  </div>
-  <div
-    className="boxed-group-header"
-  >
-    <h2>
-      onboarding.create_organization.choose_plan
-    </h2>
-  </div>
-  <div
-    className=""
-  >
-    <div
-      className="boxed-group-inner"
-    >
-      <React.Fragment>
-        <PlanSelect
-          onChange={[Function]}
-          plan="paid"
-          startingPrice="10"
-        />
-        <React.Fragment>
-          <PaymentMethodSelect
-            onChange={[Function]}
-          />
-        </React.Fragment>
-      </React.Fragment>
-    </div>
-  </div>
-</div>
-`;
-
-exports[`should upgrade using coupon 2`] = `
-<div
-  className="boxed-group onboarding-step is-open"
->
-  <div
-    className="onboarding-step-number"
-  >
-    2
-  </div>
-  <div
-    className="boxed-group-header"
-  >
-    <h2>
-      onboarding.create_organization.choose_plan
-    </h2>
-  </div>
-  <div
-    className=""
-  >
-    <div
-      className="boxed-group-inner"
-    >
-      <React.Fragment>
-        <PlanSelect
-          onChange={[Function]}
-          plan="paid"
-          startingPrice="10"
+        <Connect(withCurrentUser(BillingFormShim))
+          onCommit={[MockFunction]}
+          onFailToUpgrade={[MockFunction]}
+          organizationKey={[MockFunction]}
+          subscriptionPlans={Array []}
         />
-        <React.Fragment>
-          <PaymentMethodSelect
-            onChange={[Function]}
-            paymentMethod="coupon"
-          />
-          <Connect(withCurrentUser(CouponForm))
-            createOrganization={[MockFunction]}
-            onFailToUpgrade={[MockFunction]}
-            onSubmit={[MockFunction]}
-          />
-        </React.Fragment>
       </React.Fragment>
     </div>
   </div>
index e7cc5a727f6ac902de83f712f67741a99d9de583..86f633a3a3b1c61f8be9ad7a8b9afb4f7c6f17c6 100644 (file)
   line-height: var(--controlHeight);
 }
 
+.onboarding-step hr {
+  margin-left: -54px;
+}
+
 .onboarding-step-number {
   position: absolute;
   top: 15px;
index bc68b868f4d3823d3d93c923843ec0241ef39d1e..0cba9b66e124088dff7b473a7907cb9e805519cf 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as React from 'react';
 import * as classNames from 'classnames';
-import Tooltip from './Tooltip';
+import Tooltip, { Placement } from './Tooltip';
 import HelpIcon from '../icons-components/HelpIcon';
 import * as theme from '../../app/theme';
 import './HelpTooltip.css';
@@ -29,6 +29,7 @@ interface Props {
   children?: React.ReactNode;
   onShow?: () => void;
   overlay: React.ReactNode;
+  placement?: Placement;
   tagName?: string;
 }
 
@@ -38,7 +39,11 @@ export default function HelpTooltip(props: Props) {
   return React.createElement(
     tagName,
     { className: classNames('help-tooltip', props.className) },
-    <Tooltip mouseLeaveDelay={0.25} onShow={props.onShow} overlay={props.overlay}>
+    <Tooltip
+      mouseLeaveDelay={0.25}
+      onShow={props.onShow}
+      overlay={props.overlay}
+      placement={props.placement}>
       <span className="display-inline-flex-center">{children}</span>
     </Tooltip>
   );
index 8efcf61cb777271ca482669fdd94049389751108..c92d918297638017b93fb380ea2fa6d0fe69b179 100644 (file)
@@ -2736,7 +2736,6 @@ onboarding.create_organization.description=Description
 onboarding.create_organization.enter_org_details=Enter your organization details
 onboarding.create_organization.enter_payment_details=Enter payment details
 onboarding.create_organization.choose_plan=Choose a plan
-onboarding.create_organization.choose_payment_method=Choose payment solution
 onboarding.create_organization.enter_your_coupon=Enter your coupon
 onboarding.create_organization.create_and_upgrade=Create Organization and Upgrade
 onboarding.create_organization.ready=All set! Your organization is now ready to go