fix(client): add validation to profile image URL (#41927)

* fix: fix broken image url after validation

* feat: add tests for a broken image url submission

* fix: reduce event related calls

* Update cypress/integration/settings/image-picture-check.js

Co-authored-by: Sem Bauke <46919888+Sembauke@users.noreply.github.com>

* Update cypress/integration/settings/image-picture-check.js

Co-authored-by: Ahmad Abdolsaheb <ahmad.abdolsaheb@gmail.com>
Co-authored-by: Sem Bauke <46919888+Sembauke@users.noreply.github.com>
This commit is contained in:
Ismail Tlemcani
2021-05-23 15:08:12 +01:00
committed by GitHub
parent 3b2be48dea
commit 914ff44f74
2 changed files with 86 additions and 9 deletions

View File

@@ -3,7 +3,9 @@ import PropTypes from 'prop-types';
import {
FormGroup,
ControlLabel,
FormControl
FormControl,
HelpBlock,
Alert
} from '@freecodecamp/react-bootstrap';
import { FullWidthRow, Spacer } from '../helpers';
@@ -28,7 +30,7 @@ const propTypes = {
class AboutSettings extends Component {
constructor(props) {
super(props);
this.validationImage = new Image();
const { name = '', location = '', picture = '', about = '' } = props;
const values = {
name,
@@ -39,7 +41,8 @@ class AboutSettings extends Component {
this.state = {
formValues: { ...values },
originalValues: { ...values },
formClicked: false
formClicked: false,
isPictureUrlValid: true
};
}
@@ -69,18 +72,25 @@ class AboutSettings extends Component {
isFormPristine = () => {
const { formValues, originalValues } = this.state;
return Object.keys(originalValues)
.map(key => originalValues[key] === formValues[key])
.every(bool => bool);
return (
this.state.isPictureUrlValid === false ||
Object.keys(originalValues)
.map(key => originalValues[key] === formValues[key])
.every(bool => bool)
);
};
handleSubmit = e => {
e.preventDefault();
const { formValues } = this.state;
const { submitNewAbout } = this.props;
return this.setState({ formClicked: true }, () =>
submitNewAbout(formValues)
);
if (this.state.isPictureUrlValid === true) {
return this.setState({ formClicked: true }, () =>
submitNewAbout(formValues)
);
} else {
return false;
}
};
handleNameChange = e => {
@@ -103,8 +113,22 @@ class AboutSettings extends Component {
}));
};
componentDidMount() {
this.validationImage.addEventListener('error', this.errorEvent);
this.validationImage.addEventListener('load', this.loadEvent);
}
componentWillUnmount() {
this.validationImage.removeEventListener('load', this.loadEvent);
this.validationImage.removeEventListener('error', this.errorEvent);
}
loadEvent = () => this.setState({ isPictureUrlValid: true });
errorEvent = () => this.setState({ isPictureUrlValid: false });
handlePictureChange = e => {
const value = e.target.value.slice(0);
this.validationImage.src = value;
return this.setState(state => ({
formValues: {
...state.formValues,
@@ -113,6 +137,19 @@ class AboutSettings extends Component {
}));
};
showImageValidationWarning = () => {
const { t } = this.props;
if (this.state.isPictureUrlValid === false) {
return (
<HelpBlock>
<Alert bsStyle='info'>{t('validation.url-not-image')}</Alert>
</HelpBlock>
);
} else {
return true;
}
};
handleAboutChange = e => {
const value = e.target.value.slice(0);
return this.setState(state => ({
@@ -164,6 +201,7 @@ class AboutSettings extends Component {
type='url'
value={picture}
/>
{this.showImageValidationWarning()}
</FormGroup>
<FormGroup controlId='about-about'>
<ControlLabel>