-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mgr/dashboard: Add custom validators.
Signed-off-by: Volker Theile <vtheile@suse.com>
- Loading branch information
Showing
2 changed files
with
109 additions
and
0 deletions.
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
src/pybind/mgr/dashboard/frontend/src/app/shared/validators/cd-validators.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
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}); | ||
}); | ||
}); | ||
}); |
44 changes: 44 additions & 0 deletions
44
src/pybind/mgr/dashboard/frontend/src/app/shared/validators/cd-validators.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { | ||
AbstractControl, | ||
ValidationErrors, | ||
ValidatorFn, | ||
Validators | ||
} from '@angular/forms'; | ||
|
||
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 have a non-empty value if the | ||
* specified prerequisite matches. | ||
*/ | ||
static requiredIf(prerequisites: Prerequisites): 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; | ||
} | ||
return isEmptyInputValue(control.value) ? {'required': true} : null; | ||
}; | ||
} | ||
} |