mirror of
https://github.com/ceph/ceph
synced 2024-12-27 14:03:25 +00:00
mgr/dashboard: Add custom validators.
Signed-off-by: Volker Theile <vtheile@suse.com>
This commit is contained in:
parent
aaac83abb5
commit
20a2ec5e94
@ -0,0 +1,89 @@
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
|
||||
import { CdValidators } from './cd-validators';
|
||||
|
||||
describe('CdValidators', () => {
|
||||
describe('email', () => {
|
||||
it('should not error on an empty email address', () => {
|
||||
const control = new FormControl('');
|
||||
expect(CdValidators.email(control)).toBeNull();
|
||||
});
|
||||
|
||||
it('should not error on valid email address', () => {
|
||||
const control = new FormControl('dashboard@ceph.com');
|
||||
expect(CdValidators.email(control)).toBeNull();
|
||||
});
|
||||
|
||||
it('should error on invalid email address', () => {
|
||||
const control = new FormControl('xyz');
|
||||
expect(CdValidators.email(control)).toEqual({'email': true});
|
||||
});
|
||||
});
|
||||
|
||||
describe('requiredIf', () => {
|
||||
let form: FormGroup;
|
||||
|
||||
beforeEach(() => {
|
||||
form = new FormGroup({
|
||||
x: new FormControl(true),
|
||||
y: new FormControl('abc'),
|
||||
z: new FormControl('')
|
||||
});
|
||||
});
|
||||
|
||||
it('should not error because all conditions are fulfilled', () => {
|
||||
form.get('z').setValue('zyx');
|
||||
const validatorFn = CdValidators.requiredIf({
|
||||
'x': true,
|
||||
'y': 'abc'
|
||||
});
|
||||
expect(validatorFn(form.controls['z'])).toBeNull();
|
||||
});
|
||||
|
||||
it('should not error because of unmet prerequisites', () => {
|
||||
// Define prereqs that do not match the current values of the form fields.
|
||||
const validatorFn = CdValidators.requiredIf({
|
||||
'x': false,
|
||||
'y': 'xyz'
|
||||
});
|
||||
// The validator must succeed because the prereqs do not match, so the
|
||||
// validation of the 'z' control will be skipped.
|
||||
expect(validatorFn(form.controls['z'])).toBeNull();
|
||||
});
|
||||
|
||||
it('should error because of an empty value', () => {
|
||||
// Define prereqs that force the validator to validate the value of
|
||||
// the 'z' control.
|
||||
const validatorFn = CdValidators.requiredIf({
|
||||
'x': true,
|
||||
'y': 'abc'
|
||||
});
|
||||
// The validator must fail because the value of control 'z' is empty.
|
||||
expect(validatorFn(form.controls['z'])).toEqual({'required': true});
|
||||
});
|
||||
|
||||
it('should not error because of unsuccessful condition', () => {
|
||||
form.get('z').setValue('zyx');
|
||||
// Define prereqs that force the validator to validate the value of
|
||||
// the 'z' control.
|
||||
const validatorFn = CdValidators.requiredIf({
|
||||
'x': true,
|
||||
'z': 'zyx'
|
||||
}, () => false);
|
||||
expect(validatorFn(form.controls['z'])).toBeNull();
|
||||
});
|
||||
|
||||
it('should error because of successful condition', () => {
|
||||
const conditionFn = (value) => {
|
||||
return value === 'abc';
|
||||
};
|
||||
// Define prereqs that force the validator to validate the value of
|
||||
// the 'y' control.
|
||||
const validatorFn = CdValidators.requiredIf({
|
||||
'x': true,
|
||||
'z': ''
|
||||
}, conditionFn);
|
||||
expect(validatorFn(form.controls['y'])).toEqual({'required': true});
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,65 @@
|
||||
import {
|
||||
AbstractControl,
|
||||
ValidationErrors,
|
||||
ValidatorFn,
|
||||
Validators
|
||||
} from '@angular/forms';
|
||||
|
||||
import * as _ from 'lodash';
|
||||
|
||||
type Prerequisites = { // tslint:disable-line
|
||||
[key: string]: any
|
||||
};
|
||||
|
||||
export function isEmptyInputValue(value: any): boolean {
|
||||
return value == null || value.length === 0;
|
||||
}
|
||||
|
||||
export class CdValidators {
|
||||
/**
|
||||
* Validator that performs email validation. In contrast to the Angular
|
||||
* email validator an empty email will not be handled as invalid.
|
||||
*/
|
||||
static email(control: AbstractControl): ValidationErrors | null {
|
||||
// Exit immediately if value is empty.
|
||||
if (isEmptyInputValue(control.value)) {
|
||||
return null;
|
||||
}
|
||||
return Validators.email(control);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validator that requires controls to fulfill the specified condition if
|
||||
* the specified prerequisites matches. If the prerequisites are fulfilled,
|
||||
* then the given function is executed and if it succeeds, the 'required'
|
||||
* validation error will be returned, otherwise null.
|
||||
* @param {Prerequisites} prerequisites An object containing the prerequisites.
|
||||
* ### Example
|
||||
* ```typescript
|
||||
* {
|
||||
* 'generate_key': true,
|
||||
* 'username': 'Max Mustermann'
|
||||
* }
|
||||
* ```
|
||||
* Only if all prerequisites are fulfilled, then the validation of the
|
||||
* control will be triggered.
|
||||
* @param {Function | undefined} condition The function to be executed when all
|
||||
* prerequisites are fulfilled. If not set, then the {@link isEmptyInputValue}
|
||||
* function will be used by default. The control's value is used as function
|
||||
* argument. The function must return true to set the validation error.
|
||||
* @return {ValidatorFn} Returns the validator function.
|
||||
*/
|
||||
static requiredIf(prerequisites: Prerequisites, condition?: Function | undefined): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
// Check if all prerequisites matches.
|
||||
if (!Object.keys(prerequisites).every((key) => {
|
||||
return (control.parent && control.parent.get(key).value === prerequisites[key]);
|
||||
})) {
|
||||
return null;
|
||||
}
|
||||
const success = _.isFunction(condition) ? condition.call(condition, control.value) :
|
||||
isEmptyInputValue(control.value);
|
||||
return success ? {'required': true} : null;
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user