@@ -33,7 +33,7 @@ | |||
"@types/react": "16.8.23", | |||
"@types/react-dom": "16.8.4", | |||
"@types/react-helmet": "5.0.8", | |||
"@typescript-eslint/parser": "1.5.0", | |||
"@typescript-eslint/parser": "2.6.0", | |||
"babel-jest": "24.8.0", | |||
"enzyme": "3.10.0", | |||
"enzyme-adapter-react-16": "1.14.0", | |||
@@ -55,7 +55,7 @@ | |||
"react-test-renderer": "16.8.5", | |||
"remark": "10.0.1", | |||
"ts-jest": "24.0.2", | |||
"typescript": "3.3.3333", | |||
"typescript": "3.6.4", | |||
"unist-util-visit": "1.4.0" | |||
}, | |||
"scripts": { |
@@ -1110,6 +1110,11 @@ | |||
"@types/cheerio" "*" | |||
"@types/react" "*" | |||
"@types/eslint-visitor-keys@^1.0.0": | |||
version "1.0.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" | |||
integrity sha1-HuMNeVRMqE1o1LPNsK9PIFZj3S0= | |||
"@types/events@*": | |||
version "3.0.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" | |||
@@ -1175,6 +1180,11 @@ | |||
dependencies: | |||
"@types/jest-diff" "*" | |||
"@types/json-schema@^7.0.3": | |||
version "7.0.3" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" | |||
integrity sha1-vf1p1h5GTcyBslFZwnDXWnPBpjY= | |||
"@types/lodash@4.14.138": | |||
version "4.14.138" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/lodash/-/lodash-4.14.138.tgz#34f52640d7358230308344e579c15b378d91989e" | |||
@@ -1289,22 +1299,35 @@ | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" | |||
integrity sha1-Rd0dBjjoyPFT6H0paQdlkpaHORY= | |||
"@typescript-eslint/parser@1.5.0": | |||
version "1.5.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/parser/-/parser-1.5.0.tgz#a96114d195dff2a49534e4c4850fb676f905a072" | |||
integrity sha1-qWEU0ZXf8qSVNOTEhQ+2dvkFoHI= | |||
"@typescript-eslint/experimental-utils@2.6.0": | |||
version "2.6.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/experimental-utils/-/experimental-utils-2.6.0.tgz#ed70bef72822bff54031ff0615fc888b9e2b6e8a" | |||
integrity sha1-7XC+9ygiv/VAMf8GFfyIi54rboo= | |||
dependencies: | |||
"@typescript-eslint/typescript-estree" "1.5.0" | |||
eslint-scope "^4.0.0" | |||
eslint-visitor-keys "^1.0.0" | |||
"@types/json-schema" "^7.0.3" | |||
"@typescript-eslint/typescript-estree" "2.6.0" | |||
eslint-scope "^5.0.0" | |||
"@typescript-eslint/typescript-estree@1.5.0": | |||
version "1.5.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/typescript-estree/-/typescript-estree-1.5.0.tgz#986b356ecdf5a0c3bc9889d221802149cf5dbd4e" | |||
integrity sha1-mGs1bs31oMO8mInSIYAhSc9dvU4= | |||
"@typescript-eslint/parser@2.6.0": | |||
version "2.6.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/parser/-/parser-2.6.0.tgz#5106295c6a7056287b4719e24aae8d6293d5af49" | |||
integrity sha1-UQYpXGpwVih7RxniSq6NYpPVr0k= | |||
dependencies: | |||
"@types/eslint-visitor-keys" "^1.0.0" | |||
"@typescript-eslint/experimental-utils" "2.6.0" | |||
"@typescript-eslint/typescript-estree" "2.6.0" | |||
eslint-visitor-keys "^1.1.0" | |||
"@typescript-eslint/typescript-estree@2.6.0": | |||
version "2.6.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/typescript-estree/-/typescript-estree-2.6.0.tgz#d3e9d8e001492e2b9124c4d4bd4e7f03c0fd7254" | |||
integrity sha1-0+nY4AFJLiuRJMTUvU5/A8D9clQ= | |||
dependencies: | |||
debug "^4.1.1" | |||
glob "^7.1.4" | |||
is-glob "^4.0.1" | |||
lodash.unescape "4.0.1" | |||
semver "5.5.0" | |||
semver "^6.3.0" | |||
"@webassemblyjs/ast@1.7.11": | |||
version "1.7.11" | |||
@@ -4444,6 +4467,14 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: | |||
esrecurse "^4.1.0" | |||
estraverse "^4.1.1" | |||
eslint-scope@^5.0.0: | |||
version "5.0.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" | |||
integrity sha1-6HyIh8c+jR7ITxylkWRcNYv8j7k= | |||
dependencies: | |||
esrecurse "^4.1.0" | |||
estraverse "^4.1.1" | |||
eslint-utils@^1.3.1: | |||
version "1.3.1" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" | |||
@@ -4454,6 +4485,11 @@ eslint-visitor-keys@^1.0.0: | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" | |||
integrity sha1-PzGA+y4pEBdxastMnW1bXDSmqB0= | |||
eslint-visitor-keys@^1.1.0: | |||
version "1.1.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" | |||
integrity sha1-4qgs6oT/JGrW+1f5veW0ZiFFnsI= | |||
eslint@5.16.0, eslint@^5.6.0: | |||
version "5.16.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" | |||
@@ -6689,7 +6725,7 @@ is-glob@^3.1.0: | |||
dependencies: | |||
is-extglob "^2.1.0" | |||
is-glob@^4.0.0: | |||
is-glob@^4.0.0, is-glob@^4.0.1: | |||
version "4.0.1" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" | |||
integrity sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw= | |||
@@ -10829,16 +10865,16 @@ semver-diff@^2.0.0: | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" | |||
integrity sha1-eQp89v6lRZuslhELKbYEEtyP+Ws= | |||
semver@5.5.0: | |||
version "5.5.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" | |||
integrity sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs= | |||
semver@^6.0.0, semver@^6.1.1: | |||
version "6.2.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" | |||
integrity sha1-TYE9lZCq+KkZJpPWyFuTRN5ZAds= | |||
semver@^6.3.0: | |||
version "6.3.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" | |||
integrity sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0= | |||
send@0.17.1: | |||
version "0.17.1" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" | |||
@@ -11894,10 +11930,10 @@ typedarray@^0.0.6: | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" | |||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= | |||
typescript@3.3.3333: | |||
version "3.3.3333" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/typescript/-/typescript-3.3.3333.tgz#171b2c5af66c59e9431199117a3bcadc66fdcfd6" | |||
integrity sha1-FxssWvZsWelDEZkRejvK3Gb9z9Y= | |||
typescript@3.6.4: | |||
version "3.6.4" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d" | |||
integrity sha1-sYdSuzeSvBoCgTNff26/G7/FuR0= | |||
typography-normalize@^0.16.19: | |||
version "0.16.19" |
@@ -73,7 +73,7 @@ | |||
"@types/react-virtualized": "9.21.0", | |||
"@types/sanitize-html": "1.20.0", | |||
"@types/valid-url": "1.0.2", | |||
"@typescript-eslint/parser": "1.5.0", | |||
"@typescript-eslint/parser": "2.6.0", | |||
"autoprefixer": "9.5.0", | |||
"babel-core": "7.0.0-bridge.0", | |||
"babel-jest": "24.8.0", | |||
@@ -118,7 +118,7 @@ | |||
"style-loader": "0.23.1", | |||
"ts-jest": "24.0.2", | |||
"ts-loader": "5.3.3", | |||
"typescript": "3.3.3333", | |||
"typescript": "3.6.4", | |||
"webpack": "4.29.6", | |||
"webpack-bundle-analyzer": "3.3.2", | |||
"webpack-dev-server": "3.2.1" |
@@ -194,20 +194,12 @@ export default function startReactApp( | |||
<Route path="issues" component={IssuesPageSelector} /> | |||
<RouteWithChildRoutes path="onboarding" childRoutes={onboardingRoutes} /> | |||
{isSonarCloud() && ( | |||
<> | |||
<Route | |||
path="create-organization" | |||
component={lazyLoad(() => | |||
import('../../apps/create/organization/CreateOrganization') | |||
)} | |||
/> | |||
<Route | |||
path="feedback/downgrade" | |||
component={lazyLoad(() => | |||
import('../../apps/feedback/downgrade/DowngradeFeedback') | |||
)} | |||
/> | |||
</> | |||
<Route | |||
path="create-organization" | |||
component={lazyLoad(() => | |||
import('../../apps/create/organization/CreateOrganization') | |||
)} | |||
/> | |||
)} | |||
<RouteWithChildRoutes path="organizations" childRoutes={organizationsRoutes} /> | |||
<RouteWithChildRoutes path="projects" childRoutes={projectsRoutes} /> |
@@ -1,80 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 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. | |||
*/ | |||
.billing-downgrade-feedback > .alert { | |||
max-width: 400px; | |||
margin: 30px auto 50px auto; | |||
} | |||
.billing-downgrade-feedback .boxed-group { | |||
margin-top: 5vh; | |||
} | |||
.billing-downgrade-feedback .boxed-group-header { | |||
padding-top: 40px; | |||
text-align: center; | |||
} | |||
.billing-downgrade-feedback .boxed-group-inner { | |||
padding: 50px 50px 40px 50px; | |||
} | |||
.billing-downgrade-feedback h2 { | |||
font-weight: bold; | |||
font-size: 18px; | |||
margin-bottom: 20px; | |||
} | |||
.billing-downgrade-feedback .boxed-group-list li { | |||
margin-left: 0; | |||
padding-left: 0; | |||
} | |||
.billing-downgrade-feedback input[type='radio'] { | |||
margin-right: 1em; | |||
} | |||
.billing-downgrade-feedback-form-actions { | |||
margin-top: 36px; | |||
} | |||
.billing-downgrade-feedback-explain-wrapper { | |||
margin-left: 25px; | |||
padding-top: 20px; | |||
} | |||
.billing-downgrade-feedback-explain-wrapper label { | |||
display: block; | |||
margin-bottom: 4px; | |||
font-weight: bold; | |||
} | |||
.billing-downgrade-feedback-explain-wrapper label .note { | |||
font-weight: normal; | |||
margin-left: 0.5em; | |||
} | |||
.billing-downgrade-feedback-explain-wrapper textarea { | |||
display: block; | |||
min-height: 70px; | |||
width: 100%; | |||
padding: 6px 8px; | |||
border: 1px solid #cdcdcd; | |||
border-radius: 2px; | |||
} |
@@ -1,170 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 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 { WithRouterProps } from 'react-router'; | |||
import { SubmitButton } from 'sonar-ui-common/components/controls/buttons'; | |||
import Radio from 'sonar-ui-common/components/controls/Radio'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getBaseUrl } from 'sonar-ui-common/helpers/urls'; | |||
import { giveDowngradeFeedback } from '../../../api/billing'; | |||
import addGlobalSuccessMessage from '../../../app/utils/addGlobalSuccessMessage'; | |||
import './DowngradeFeedback.css'; | |||
enum Reason { | |||
doesntWork = 'did_not_work', | |||
doesntMeetExpectations = 'did_not_match_expectations', | |||
doesntMeetCompanyPolicy = 'company_policy', | |||
onlyTesting = 'just_testing', | |||
other = 'other' | |||
} | |||
interface State { | |||
additionalFeedback: string; | |||
feedback?: Reason; | |||
} | |||
export interface LocationState { | |||
confirmationMessage?: string; | |||
organization?: T.Organization; | |||
returnTo?: string; | |||
title: string; | |||
} | |||
export default class DowngradeFeedback extends React.PureComponent<WithRouterProps, State> { | |||
state: State = { | |||
additionalFeedback: '' | |||
}; | |||
handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => { | |||
this.setState({ | |||
additionalFeedback: event.currentTarget.value | |||
}); | |||
}; | |||
handleChoice = (value: string) => { | |||
this.setState({ | |||
feedback: value as Reason | |||
}); | |||
}; | |||
handleSkip = (event: React.MouseEvent<HTMLAnchorElement>) => { | |||
event.preventDefault(); | |||
this.navigateAway(); | |||
}; | |||
handleSubmit = (event: React.FormEvent) => { | |||
event.preventDefault(); | |||
const { organization } = this.getLocationState(); | |||
if (!organization) { | |||
return; | |||
} | |||
giveDowngradeFeedback({ | |||
organization: organization.key, | |||
feedback: this.state.feedback as string, | |||
additionalFeedback: this.state.additionalFeedback | |||
}); | |||
this.navigateAway(translate('billing.downgrade.thankyou_for_feedback')); | |||
}; | |||
getLocationState = (): LocationState => { | |||
const { location } = this.props; | |||
return location.state || {}; | |||
}; | |||
navigateAway = (message?: string) => { | |||
if (message) { | |||
addGlobalSuccessMessage(message); | |||
} | |||
const { returnTo } = this.getLocationState(); | |||
this.props.router.replace({ | |||
pathname: returnTo || getBaseUrl() | |||
}); | |||
}; | |||
render() { | |||
const { organization, confirmationMessage, title } = this.getLocationState(); | |||
if (!organization) { | |||
return null; | |||
} | |||
return ( | |||
<div className="billing-downgrade-feedback"> | |||
{confirmationMessage && <Alert variant="success">{confirmationMessage}</Alert>} | |||
<div className="boxed-group boxed-group-centered"> | |||
<div className="boxed-group-header"> | |||
<h2>{title}</h2> | |||
<div>{translate('billing.downgrade.reason.explanation')}</div> | |||
</div> | |||
<div className="boxed-group-inner"> | |||
<form className="billing-downgrade-feedback-form" onSubmit={this.handleSubmit}> | |||
<ul className="boxed-group-list"> | |||
{Object.keys(Reason).map(key => { | |||
const reason = Reason[key as any]; | |||
return ( | |||
<li key={reason}> | |||
<Radio | |||
checked={this.state.feedback === reason} | |||
onCheck={this.handleChoice} | |||
value={reason}> | |||
{translate('billing.downgrade.reason.option', reason, 'label')} | |||
</Radio> | |||
{this.state.feedback === reason && ( | |||
<div className="billing-downgrade-feedback-explain-wrapper"> | |||
<label htmlFor={`reason_text_${reason}`}> | |||
{translate('billing.why')} | |||
<span className="note">{translate('billing.optional')}</span> | |||
</label> | |||
<textarea | |||
id={`reason_text_${reason}`} | |||
name={`reason_text_${reason}`} | |||
onChange={this.handleChange} | |||
placeholder={translate( | |||
'billing.downgrade.reason.option', | |||
reason, | |||
'placeholder' | |||
)} | |||
value={this.state.additionalFeedback} | |||
/> | |||
</div> | |||
)} | |||
</li> | |||
); | |||
})} | |||
</ul> | |||
<div className="billing-downgrade-feedback-form-actions"> | |||
<SubmitButton className="spacer-right" disabled={!this.state.feedback}> | |||
{translate('billing.send')} | |||
</SubmitButton> | |||
<a href="#" onClick={this.handleSkip}> | |||
{translate('billing.skip')} | |||
</a> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
</div> | |||
); | |||
} | |||
} |
@@ -1,103 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { giveDowngradeFeedback } from '../../../../api/billing'; | |||
import { mockLocation, mockRouter } from '../../../../helpers/testMocks'; | |||
import DowngradeFeedback, { LocationState } from '../DowngradeFeedback'; | |||
jest.mock('../../../../api/billing', () => ({ | |||
giveDowngradeFeedback: jest.fn() | |||
})); | |||
const mockRouterReplace = jest.fn(); | |||
const org: T.Organization = { | |||
key: 'myorg', | |||
name: 'My Org' | |||
}; | |||
const returnPath = '/path?with=query'; | |||
beforeEach(() => { | |||
(mockRouterReplace as jest.Mock).mockClear(); | |||
(giveDowngradeFeedback as jest.Mock).mockClear(); | |||
}); | |||
it('should render correctly', () => { | |||
const wrapper = getWrapper(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it('should enforce choosing a reason, and show an extra textarea if a reason was chosen', () => { | |||
const wrapper = getWrapper(); | |||
expect(wrapper.find('SubmitButton')).toMatchSnapshot(); | |||
wrapper.setState({ feedback: 'other' }); | |||
expect(wrapper.find('[name="reason_text_other"]').exists()).toBe(true); | |||
expect(wrapper.find('SubmitButton')).toMatchSnapshot(); | |||
}); | |||
it('should submit the data to the webservice', () => { | |||
const wrapper = getWrapper(); | |||
const feedback = 'other'; | |||
const additionalFeedback = 'Additional feedback'; | |||
wrapper.setState({ feedback, additionalFeedback }); | |||
wrapper | |||
.find('form') | |||
.at(0) | |||
.simulate('submit', { | |||
preventDefault: jest.fn() | |||
}); | |||
expect(giveDowngradeFeedback).toBeCalledWith({ | |||
organization: org.key, | |||
feedback, | |||
additionalFeedback | |||
}); | |||
expect(mockRouterReplace).toBeCalledWith({ | |||
pathname: returnPath | |||
}); | |||
}); | |||
function mockLocationState(overrides = {}): LocationState { | |||
return { | |||
confirmationMessage: 'Downgrade successful', | |||
returnTo: returnPath, | |||
organization: org, | |||
title: 'Title', | |||
...overrides | |||
}; | |||
} | |||
function getWrapper(props = {}, locationState = {}) { | |||
return shallow( | |||
<DowngradeFeedback | |||
location={mockLocation({ | |||
state: mockLocationState(locationState) | |||
})} | |||
params={{}} | |||
router={mockRouter({ | |||
replace: mockRouterReplace | |||
})} | |||
routes={[]} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -1,129 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should enforce choosing a reason, and show an extra textarea if a reason was chosen 1`] = ` | |||
<SubmitButton | |||
className="spacer-right" | |||
disabled={true} | |||
> | |||
billing.send | |||
</SubmitButton> | |||
`; | |||
exports[`should enforce choosing a reason, and show an extra textarea if a reason was chosen 2`] = ` | |||
<SubmitButton | |||
className="spacer-right" | |||
disabled={false} | |||
> | |||
billing.send | |||
</SubmitButton> | |||
`; | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="billing-downgrade-feedback" | |||
> | |||
<Alert | |||
variant="success" | |||
> | |||
Downgrade successful | |||
</Alert> | |||
<div | |||
className="boxed-group boxed-group-centered" | |||
> | |||
<div | |||
className="boxed-group-header" | |||
> | |||
<h2> | |||
Title | |||
</h2> | |||
<div> | |||
billing.downgrade.reason.explanation | |||
</div> | |||
</div> | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<form | |||
className="billing-downgrade-feedback-form" | |||
onSubmit={[Function]} | |||
> | |||
<ul | |||
className="boxed-group-list" | |||
> | |||
<li | |||
key="did_not_work" | |||
> | |||
<Radio | |||
checked={false} | |||
onCheck={[Function]} | |||
value="did_not_work" | |||
> | |||
billing.downgrade.reason.option.did_not_work.label | |||
</Radio> | |||
</li> | |||
<li | |||
key="did_not_match_expectations" | |||
> | |||
<Radio | |||
checked={false} | |||
onCheck={[Function]} | |||
value="did_not_match_expectations" | |||
> | |||
billing.downgrade.reason.option.did_not_match_expectations.label | |||
</Radio> | |||
</li> | |||
<li | |||
key="company_policy" | |||
> | |||
<Radio | |||
checked={false} | |||
onCheck={[Function]} | |||
value="company_policy" | |||
> | |||
billing.downgrade.reason.option.company_policy.label | |||
</Radio> | |||
</li> | |||
<li | |||
key="just_testing" | |||
> | |||
<Radio | |||
checked={false} | |||
onCheck={[Function]} | |||
value="just_testing" | |||
> | |||
billing.downgrade.reason.option.just_testing.label | |||
</Radio> | |||
</li> | |||
<li | |||
key="other" | |||
> | |||
<Radio | |||
checked={false} | |||
onCheck={[Function]} | |||
value="other" | |||
> | |||
billing.downgrade.reason.option.other.label | |||
</Radio> | |||
</li> | |||
</ul> | |||
<div | |||
className="billing-downgrade-feedback-form-actions" | |||
> | |||
<SubmitButton | |||
className="spacer-right" | |||
disabled={true} | |||
> | |||
billing.send | |||
</SubmitButton> | |||
<a | |||
href="#" | |||
onClick={[Function]} | |||
> | |||
billing.skip | |||
</a> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
</div> | |||
`; |
@@ -778,13 +778,15 @@ export class App extends React.PureComponent<Props, State> { | |||
handlePopupToggle = (issue: string, popupName: string, open?: boolean) => { | |||
this.setState((state: State) => { | |||
const samePopup = | |||
state.openPopup && state.openPopup.name === popupName && state.openPopup.issue === issue; | |||
const { openPopup } = state; | |||
const samePopup = openPopup && openPopup.name === popupName && openPopup.issue === issue; | |||
if (open !== false && !samePopup) { | |||
return { openPopup: { issue, name: popupName } }; | |||
return { ...state, openPopup: { issue, name: popupName } }; | |||
} else if (open !== true && samePopup) { | |||
return { openPopup: undefined }; | |||
return { ...state, openPopup: undefined }; | |||
} | |||
return state; | |||
}); | |||
}; |
@@ -31,11 +31,7 @@ const setting: T.Setting = { | |||
name: 'Foo setting', | |||
description: 'When Foo then Bar', | |||
type: 'INTEGER', | |||
category: 'general', | |||
subCategory: 'SubFoo', | |||
defaultValue: '42', | |||
options: [], | |||
fields: [] | |||
options: [] | |||
} | |||
}; | |||
@@ -42,14 +42,10 @@ exports[`should render correctly 1`] = ` | |||
setting={ | |||
Object { | |||
"definition": Object { | |||
"category": "general", | |||
"defaultValue": "42", | |||
"description": "When Foo then Bar", | |||
"fields": Array [], | |||
"key": "foo", | |||
"name": "Foo setting", | |||
"options": Array [], | |||
"subCategory": "SubFoo", | |||
"type": "INTEGER", | |||
}, | |||
"inherited": true, | |||
@@ -70,14 +66,10 @@ exports[`should render correctly 1`] = ` | |||
setting={ | |||
Object { | |||
"definition": Object { | |||
"category": "general", | |||
"defaultValue": "42", | |||
"description": "When Foo then Bar", | |||
"fields": Array [], | |||
"key": "foo", | |||
"name": "Foo setting", | |||
"options": Array [], | |||
"subCategory": "SubFoo", | |||
"type": "INTEGER", | |||
}, | |||
"inherited": true, |
@@ -59,7 +59,7 @@ it('should render MultiValueInput', () => { | |||
it('should render PropertySetInput', () => { | |||
const setting: T.Setting = { | |||
...settingValue, | |||
definition: { ...settingDefinition, type: 'PROPERTY_SET', fields: [] } | |||
definition: { ...settingDefinition, type: 'PROPERTY_SET' } | |||
}; | |||
const onChange = jest.fn(); |
@@ -24,7 +24,7 @@ interface SourceViewerContextShape { | |||
file: T.SourceViewerFile; | |||
} | |||
export const SourceViewerContext = React.createContext({ | |||
branchLike: {}, | |||
file: {} | |||
}) as React.Context<SourceViewerContextShape>; | |||
export const SourceViewerContext = React.createContext<SourceViewerContextShape>({ | |||
branchLike: {} as T.BranchLike, | |||
file: {} as T.SourceViewerFile | |||
}); |
@@ -803,6 +803,7 @@ declare namespace T { | |||
export interface SettingDefinition { | |||
description?: string; | |||
key: string; | |||
multiValues?: boolean; | |||
name?: string; | |||
options: string[]; | |||
type?: SettingType; |
@@ -1127,6 +1127,11 @@ | |||
"@types/cheerio" "*" | |||
"@types/react" "*" | |||
"@types/eslint-visitor-keys@^1.0.0": | |||
version "1.0.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" | |||
integrity sha1-HuMNeVRMqE1o1LPNsK9PIFZj3S0= | |||
"@types/events@*": | |||
version "3.0.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" | |||
@@ -1187,6 +1192,11 @@ | |||
dependencies: | |||
"@types/jest-diff" "*" | |||
"@types/json-schema@^7.0.3": | |||
version "7.0.3" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" | |||
integrity sha1-vf1p1h5GTcyBslFZwnDXWnPBpjY= | |||
"@types/keymaster@1.6.28": | |||
version "1.6.28" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/keymaster/-/keymaster-1.6.28.tgz#093fc6fe49deff4ee17d36935a49230edb1c935f" | |||
@@ -1302,22 +1312,35 @@ | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" | |||
integrity sha1-Rd0dBjjoyPFT6H0paQdlkpaHORY= | |||
"@typescript-eslint/parser@1.5.0": | |||
version "1.5.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/parser/-/parser-1.5.0.tgz#a96114d195dff2a49534e4c4850fb676f905a072" | |||
integrity sha1-qWEU0ZXf8qSVNOTEhQ+2dvkFoHI= | |||
"@typescript-eslint/experimental-utils@2.6.0": | |||
version "2.6.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/experimental-utils/-/experimental-utils-2.6.0.tgz#ed70bef72822bff54031ff0615fc888b9e2b6e8a" | |||
integrity sha1-7XC+9ygiv/VAMf8GFfyIi54rboo= | |||
dependencies: | |||
"@typescript-eslint/typescript-estree" "1.5.0" | |||
eslint-scope "^4.0.0" | |||
eslint-visitor-keys "^1.0.0" | |||
"@types/json-schema" "^7.0.3" | |||
"@typescript-eslint/typescript-estree" "2.6.0" | |||
eslint-scope "^5.0.0" | |||
"@typescript-eslint/typescript-estree@1.5.0": | |||
version "1.5.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/typescript-estree/-/typescript-estree-1.5.0.tgz#986b356ecdf5a0c3bc9889d221802149cf5dbd4e" | |||
integrity sha1-mGs1bs31oMO8mInSIYAhSc9dvU4= | |||
"@typescript-eslint/parser@2.6.0": | |||
version "2.6.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/parser/-/parser-2.6.0.tgz#5106295c6a7056287b4719e24aae8d6293d5af49" | |||
integrity sha1-UQYpXGpwVih7RxniSq6NYpPVr0k= | |||
dependencies: | |||
"@types/eslint-visitor-keys" "^1.0.0" | |||
"@typescript-eslint/experimental-utils" "2.6.0" | |||
"@typescript-eslint/typescript-estree" "2.6.0" | |||
eslint-visitor-keys "^1.1.0" | |||
"@typescript-eslint/typescript-estree@2.6.0": | |||
version "2.6.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/@typescript-eslint/typescript-estree/-/typescript-estree-2.6.0.tgz#d3e9d8e001492e2b9124c4d4bd4e7f03c0fd7254" | |||
integrity sha1-0+nY4AFJLiuRJMTUvU5/A8D9clQ= | |||
dependencies: | |||
debug "^4.1.1" | |||
glob "^7.1.4" | |||
is-glob "^4.0.1" | |||
lodash.unescape "4.0.1" | |||
semver "5.5.0" | |||
semver "^6.3.0" | |||
"@webassemblyjs/ast@1.8.5": | |||
version "1.8.5" | |||
@@ -3954,6 +3977,14 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: | |||
esrecurse "^4.1.0" | |||
estraverse "^4.1.1" | |||
eslint-scope@^5.0.0: | |||
version "5.0.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" | |||
integrity sha1-6HyIh8c+jR7ITxylkWRcNYv8j7k= | |||
dependencies: | |||
esrecurse "^4.1.0" | |||
estraverse "^4.1.1" | |||
eslint-utils@^1.3.1: | |||
version "1.3.1" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" | |||
@@ -3964,6 +3995,11 @@ eslint-visitor-keys@^1.0.0: | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" | |||
integrity sha1-PzGA+y4pEBdxastMnW1bXDSmqB0= | |||
eslint-visitor-keys@^1.1.0: | |||
version "1.1.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" | |||
integrity sha1-4qgs6oT/JGrW+1f5veW0ZiFFnsI= | |||
eslint@5.16.0: | |||
version "5.16.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" | |||
@@ -5498,7 +5534,7 @@ is-glob@^3.1.0: | |||
dependencies: | |||
is-extglob "^2.1.0" | |||
is-glob@^4.0.0: | |||
is-glob@^4.0.0, is-glob@^4.0.1: | |||
version "4.0.1" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" | |||
integrity sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw= | |||
@@ -9186,16 +9222,16 @@ semver-compare@^1.0.0: | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" | |||
integrity sha1-eQp89v6lRZuslhELKbYEEtyP+Ws= | |||
semver@5.5.0: | |||
version "5.5.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" | |||
integrity sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs= | |||
semver@^6.0.0, semver@^6.1.1: | |||
version "6.2.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" | |||
integrity sha1-TYE9lZCq+KkZJpPWyFuTRN5ZAds= | |||
semver@^6.3.0: | |||
version "6.3.0" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" | |||
integrity sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0= | |||
send@0.17.1: | |||
version "0.17.1" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" | |||
@@ -10129,10 +10165,10 @@ typedarray@^0.0.6: | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" | |||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= | |||
typescript@3.3.3333: | |||
version "3.3.3333" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/typescript/-/typescript-3.3.3333.tgz#171b2c5af66c59e9431199117a3bcadc66fdcfd6" | |||
integrity sha1-FxssWvZsWelDEZkRejvK3Gb9z9Y= | |||
typescript@3.6.4: | |||
version "3.6.4" | |||
resolved "https://repox.jfrog.io/repox/api/npm/npm/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d" | |||
integrity sha1-sYdSuzeSvBoCgTNff26/G7/FuR0= | |||
ua-parser-js@^0.7.18: | |||
version "0.7.20" |