diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2019-08-20 11:29:23 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-09-23 20:21:06 +0200 |
commit | 42339a34c4beefc564d6ae7d3e36040624027cef (patch) | |
tree | fdf01314ae986d27379a5cbc6c7377c0b9dfb8a2 /server | |
parent | f831f6244ff31d74d8c8454ad144848780643d71 (diff) | |
download | sonarqube-42339a34c4beefc564d6ae7d3e36040624027cef.tar.gz sonarqube-42339a34c4beefc564d6ae7d3e36040624027cef.zip |
SONAR-12371 Fix password inputs in settings
Diffstat (limited to 'server')
2 files changed, 48 insertions, 13 deletions
diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.tsx index 0d93cc5e80b..9a3952faf04 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.tsx @@ -26,7 +26,6 @@ import { DefaultSpecializedInputProps } from '../../utils'; interface State { changing: boolean; - value: string; } export default class InputForPassword extends React.PureComponent< @@ -34,19 +33,26 @@ export default class InputForPassword extends React.PureComponent< State > { state: State = { - value: '', - changing: false + changing: !this.props.value }; - componentDidUpdate(prevProps: DefaultSpecializedInputProps) { - if (!prevProps.hasValueChanged && this.props.hasValueChanged) { - this.setState({ changing: false, value: '' }); + componentWillReceiveProps(nextProps: DefaultSpecializedInputProps) { + /* + * Reset `changing` if: + * - the value is reset (valueChanged -> !valueChanged) + * or + * - the value changes from outside the input (i.e. store update/reset/cancel) + */ + if ( + (this.props.hasValueChanged || this.props.value !== nextProps.value) && + !nextProps.hasValueChanged + ) { + this.setState({ changing: !nextProps.value }); } } handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => { this.props.onChange(event.target.value); - this.setState({ changing: true, value: event.target.value }); }; handleChangeClick = () => { @@ -59,21 +65,19 @@ export default class InputForPassword extends React.PureComponent< <input className="hidden" type="password" /> <input autoComplete="off" - autoFocus={this.state.changing} + autoFocus={this.state.changing && this.props.value} className="js-password-input settings-large-input text-top" name={this.props.name} onChange={this.handleInputChange} type="password" - value={this.state.value} + value={this.props.value} /> </form> ); } render() { - const hasValue = !!this.props.value; - - if (this.state.changing || !hasValue) { + if (this.state.changing) { return this.renderInput(); } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.tsx index 2ac8b3d7191..4fb9e65e4f5 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.tsx @@ -51,8 +51,39 @@ it('should set value', () => { expect(onChange).toBeCalledWith('secret'); }); +it('should show form when empty, and enable handle typing', () => { + const input = shallowRender({ value: '' }); + const onChange = (value: string) => input.setProps({ hasValueChanged: true, value }); + input.setProps({ onChange }); + + expect(input.find('form').length).toBe(1); + change(input.find('input.js-password-input'), 'hello'); + expect(input.find('form').length).toBe(1); + expect(input.find('input.js-password-input').prop('value')).toBe('hello'); +}); + +it('should handle value reset', () => { + const input = shallowRender({ hasValueChanged: true, value: 'whatever' }); + input.setState({ changing: true }); + + // reset + input.setProps({ hasValueChanged: false, value: 'original' }); + + expect(input.state('changing')).toBe(false); +}); + +it('should handle value reset to empty', () => { + const input = shallowRender({ hasValueChanged: true, value: 'whatever' }); + input.setState({ changing: true }); + + // outside change + input.setProps({ hasValueChanged: false, value: '' }); + + expect(input.state('changing')).toBe(true); +}); + function shallowRender(props: Partial<DefaultSpecializedInputProps> = {}) { - return shallow( + return shallow<InputForPassword>( <InputForPassword hasValueChanged={false} isDefault={false} |