Ivan - Add validations for frontend signup, fix styling regarding margin, add public reCaptcha key for development, update unit testing with performValidation
This commit is contained in:
parent
4943a5eb94
commit
78e2146357
|
@ -4,10 +4,6 @@
|
|||
height: 361px;
|
||||
}
|
||||
|
||||
&__input {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
&__inputs {
|
||||
display: inline-block;
|
||||
margin: 0 auto 20px;
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
.recover-password {
|
||||
&__inputs {
|
||||
display: inline-block;
|
||||
margin: 0 auto 20px;
|
||||
margin: 0 auto 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&__input {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
&__submit-button {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
|
|
@ -24,17 +24,17 @@ let MainSignUpPageWidget = React.createClass({
|
|||
render() {
|
||||
return (
|
||||
<div className="main-signup-page">
|
||||
<WidgetTransition sideToShow="front" className="main-signup-page--widget-container">
|
||||
<WidgetTransition sideToShow="front" className="main-signup-page__widget-container col-md-4 col-md-offset-4">
|
||||
<Widget className="signup-widget" title="Register">
|
||||
<Form className="signup-widget--form" onSubmit={this.handleLoginFormSubmit}>
|
||||
<div className="signup-widget--inputs">
|
||||
<Input {...this.getInputProps()} label="Full Name" name="name"/>
|
||||
<Input {...this.getInputProps()} label="Email Address" name="email"/>
|
||||
<Input {...this.getInputProps()} label="Password" name="password" password/>
|
||||
<Input {...this.getInputProps()} label="Repeat Password" name="repeated-password" password/>
|
||||
<Form className="signup-widget__form" onSubmit={this.handleLoginFormSubmit}>
|
||||
<div className="signup-widget__inputs">
|
||||
<Input {...this.getInputProps()} label="Full Name" name="name" validation="NAME" required/>
|
||||
<Input {...this.getInputProps()} label="Email Address" name="email" validation="EMAIL" required/>
|
||||
<Input {...this.getInputProps()} label="Password" name="password" password validation="PASSWORD" required/>
|
||||
<Input {...this.getInputProps()} label="Repeat Password" name="repeated-password" password validation="REPEAT_PASSWORD" required/>
|
||||
</div>
|
||||
<div className="signup-widget--captcha">
|
||||
<ReCAPTCHA sitekey="custom-site-key" onChange={function () {}}/>
|
||||
<div className="signup-widget__captcha">
|
||||
<ReCAPTCHA sitekey="6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS" onChange={function () {}}/>
|
||||
</div>
|
||||
<Button type="primary">SIGN UP</Button>
|
||||
</Form>
|
||||
|
@ -47,7 +47,7 @@ let MainSignUpPageWidget = React.createClass({
|
|||
getInputProps() {
|
||||
return {
|
||||
inputType: 'secondary',
|
||||
className: 'signup-widget-input'
|
||||
className: 'signup-widget__input'
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,26 +1,17 @@
|
|||
.main-signup-page {
|
||||
|
||||
&--widget-container {
|
||||
height: 525px;
|
||||
width: 364px;
|
||||
}
|
||||
height: 629px;
|
||||
|
||||
.signup-widget {
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
|
||||
&--inputs {
|
||||
&__inputs {
|
||||
display: inline-block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
&--input {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&--captcha {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 20px;
|
||||
&__captcha {
|
||||
margin: 20px 0;
|
||||
height: 78px;
|
||||
width: 304px;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ describe('Form component', function () {
|
|||
}
|
||||
|
||||
function resetStubs() {
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.validate = stub();
|
||||
ValidationFactoryMock.validators.customValidatorMock.validate = stub();
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.performValidation = stub();
|
||||
ValidationFactoryMock.validators.customValidatorMock.performValidation = stub();
|
||||
ValidationFactoryMock.getValidator.reset();
|
||||
onSubmit.reset();
|
||||
}
|
||||
|
@ -84,8 +84,8 @@ describe('Form component', function () {
|
|||
});
|
||||
|
||||
it('should validate required fields when blurring', function () {
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.validate = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.validate = stub().returns('MOCK_ERROR_2');
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.performValidation = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.performValidation = stub().returns('MOCK_ERROR_2');
|
||||
expect(fields[0].props.error).to.equal(undefined);
|
||||
expect(fields[0].props.error).to.equal(undefined);
|
||||
expect(fields[0].props.error).to.equal(undefined);
|
||||
|
@ -107,8 +107,8 @@ describe('Form component', function () {
|
|||
beforeEach(function () {
|
||||
onValidateErrors = stub();
|
||||
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.validate = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.validate = stub().returns('MOCK_ERROR_2');
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.performValidation = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.performValidation = stub().returns('MOCK_ERROR_2');
|
||||
|
||||
renderForm({
|
||||
errors: {first: 'MOCK_ERROR_CONTROLLED'},
|
||||
|
@ -172,8 +172,8 @@ describe('Form component', function () {
|
|||
});
|
||||
|
||||
it('should validate all fields and not call onSubmit if there are errors', function () {
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.validate = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.validate = stub().returns('MOCK_ERROR_2');
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.performValidation = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.performValidation = stub().returns('MOCK_ERROR_2');
|
||||
fields[0].focus = spy(fields[0].focus);
|
||||
fields[1].focus = spy(fields[1].focus);
|
||||
|
||||
|
@ -186,15 +186,15 @@ describe('Form component', function () {
|
|||
});
|
||||
|
||||
it('should focus the first field with error', function () {
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.validate = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.validate = stub().returns('MOCK_ERROR_2');
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.performValidation = stub().returns('MOCK_ERROR');
|
||||
ValidationFactoryMock.validators.customValidatorMock.performValidation = stub().returns('MOCK_ERROR_2');
|
||||
fields[0].focus = spy(fields[0].focus);
|
||||
fields[1].focus = spy(fields[1].focus);
|
||||
|
||||
TestUtils.Simulate.submit(ReactDOM.findDOMNode(form));
|
||||
expect(fields[0].focus).to.have.been.called;
|
||||
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.validate = stub();
|
||||
ValidationFactoryMock.validators.defaultValidatorMock.performValidation = stub();
|
||||
fields[0].focus.reset();
|
||||
fields[1].focus.reset();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const React = require('react');
|
||||
const _ = require('lodash');
|
||||
const classNames = require('classnames');
|
||||
|
||||
const {reactDFS, renderChildrenWithProps} = require('lib-core/react-dfs');
|
||||
const ValidationFactory = require('lib-app/validations/validations-factory');
|
||||
|
@ -49,8 +50,9 @@ const Form = React.createClass({
|
|||
getProps() {
|
||||
let props = _.clone(this.props);
|
||||
|
||||
props.className = this.getClass();
|
||||
props.onSubmit = this.handleSubmit;
|
||||
|
||||
|
||||
delete props.errors;
|
||||
delete props.loading;
|
||||
delete props.onValidateErrors;
|
||||
|
@ -58,6 +60,16 @@ const Form = React.createClass({
|
|||
return props;
|
||||
},
|
||||
|
||||
getClass() {
|
||||
let classes = {
|
||||
'form': true
|
||||
};
|
||||
|
||||
classes[this.props.className] = (this.props.className);
|
||||
|
||||
return classNames(classes);
|
||||
},
|
||||
|
||||
getFieldProps({props, type}) {
|
||||
let additionalProps = {};
|
||||
|
||||
|
@ -112,7 +124,7 @@ const Form = React.createClass({
|
|||
let newErrors = _.clone(errors);
|
||||
|
||||
if (this.state.validations[fieldName]) {
|
||||
newErrors[fieldName] = this.state.validations[fieldName].validate(form[fieldName], form);
|
||||
newErrors[fieldName] = this.state.validations[fieldName].performValidation(form[fieldName], form);
|
||||
}
|
||||
|
||||
return newErrors;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.form {
|
||||
.input {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ export default {
|
|||
//ERRORS
|
||||
'ERROR_EMPTY': 'Invalid value',
|
||||
'ERROR_PASSWORD': 'Invalid password',
|
||||
'ERROR_NAME': 'Invalid name',
|
||||
'ERROR_EMAIL': 'Invalid email',
|
||||
'PASSWORD_NOT_MATCH': 'Password does not match'
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
let customValidatorMock = {validate: stub()};
|
||||
let defaultValidatorMock = {validate: stub()};
|
||||
let customValidatorMock = {performValidation: stub(), validate: stub()};
|
||||
let defaultValidatorMock = {performValidation: stub(), validate: stub()};
|
||||
|
||||
export default {
|
||||
getValidator: spy(function (validation) {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import Validator from 'lib-app/validations/validator';
|
||||
|
||||
class AlphaNumericValidator extends Validator {
|
||||
constructor(errorKey = 'INVALID_VALUE', validator = null) {
|
||||
super(validator);
|
||||
|
||||
this.errorKey = errorKey;
|
||||
}
|
||||
|
||||
validate(value, form) {
|
||||
let alphaMatch = /^[-\sa-zA-Z.]+$/;
|
||||
|
||||
if (!alphaMatch.test(value)) return this.getError(this.errorKey);
|
||||
}
|
||||
}
|
||||
|
||||
export default AlphaNumericValidator;
|
|
@ -3,8 +3,9 @@ import Validator from 'lib-app/validations/validator';
|
|||
class EmailValidator extends Validator {
|
||||
|
||||
validate(value, form) {
|
||||
if (value.length < 6) return this.getError('ERROR_EMAIL');
|
||||
if (value.indexOf('@') === -1) return this.getError('ERROR_EMAIL');
|
||||
let emailMatch = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
|
||||
if (!emailMatch.test(value)) return this.getError('ERROR_EMAIL');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Validator from 'lib-app/validations/validator';
|
||||
|
||||
class LengthValidator extends Validator {
|
||||
constructor(length, errorKey = 'INVALID_VALUE') {
|
||||
super();
|
||||
constructor(length, errorKey = 'INVALID_VALUE', validator = null) {
|
||||
super(validator);
|
||||
|
||||
this.minlength = length;
|
||||
this.errorKey = errorKey;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import Validator from 'lib-app/validations/validator';
|
||||
import AlphaNumericValidator from 'lib-app/validations/alphanumeric-validator';
|
||||
import EmailValidator from 'lib-app/validations/email-validator';
|
||||
import RepeatPasswordValidator from 'lib-app/validations/repeat-password-validator';
|
||||
import LengthValidator from 'lib-app/validations/length-validator';
|
||||
|
||||
let validators = {
|
||||
'DEFAULT': new Validator(),
|
||||
'NAME': new AlphaNumericValidator('ERROR_NAME', new LengthValidator(2, 'ERROR_NAME')),
|
||||
'EMAIL': new EmailValidator(),
|
||||
'PASSWORD': new LengthValidator(6, 'ERROR_PASSWORD'),
|
||||
'REPEAT_PASSWORD': new RepeatPasswordValidator()
|
||||
|
|
|
@ -1,6 +1,22 @@
|
|||
const i18n = require('lib-app/i18n');
|
||||
|
||||
class Validator {
|
||||
constructor(validator = null) {
|
||||
this.previousValidator = validator;
|
||||
}
|
||||
|
||||
performValidation(value, form) {
|
||||
let error;
|
||||
|
||||
error = this.validate(value, form);
|
||||
|
||||
if (this.previousValidator && !error) {
|
||||
error = this.previousValidator.validate(value, form);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
validate(value, form) {
|
||||
if (!value.length) return this.getError('ERROR_EMPTY');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue