diff --git a/packages/wyatt_form_bloc/lib/src/data/form_validators/only_required_input_validator.dart b/packages/wyatt_form_bloc/lib/src/data/form_validators/only_required_input_validator.dart index bd83d295..95414a62 100644 --- a/packages/wyatt_form_bloc/lib/src/data/form_validators/only_required_input_validator.dart +++ b/packages/wyatt_form_bloc/lib/src/data/form_validators/only_required_input_validator.dart @@ -23,7 +23,21 @@ class OnlyRequiredInputValidator extends FormValidator { @override FormStatus validate(WyattForm form) { - // TODO(hpcl): use metadata to check if input is required or not. + if (isPure(form)) { + return FormStatus.pure; + } + + final inputsToTest = + form.inputs.where((input) => input.metadata.isRequired); + + if (inputsToTest.every((input) => input.validator.pure)) { + return FormStatus.pure; + } + + if (inputsToTest.any((input) => input.validator.valid == false)) { + return FormStatus.invalid; + } + return FormStatus.valid; } } diff --git a/packages/wyatt_form_bloc/lib/src/domain/entities/form_input_metadata.dart b/packages/wyatt_form_bloc/lib/src/domain/entities/form_input_metadata.dart index df21c950..5c50ec2d 100644 --- a/packages/wyatt_form_bloc/lib/src/domain/entities/form_input_metadata.dart +++ b/packages/wyatt_form_bloc/lib/src/domain/entities/form_input_metadata.dart @@ -18,38 +18,44 @@ import 'package:equatable/equatable.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart'; -class FormInputMetadata extends Equatable - implements Entity { +class FormInputMetadata extends Equatable implements Entity { final bool export; + final bool isRequired; final String? name; final Extra? extra; const FormInputMetadata({ this.export = true, + this.isRequired = true, this.name, this.extra, }); FormInputMetadata copyWith({ bool? export, + bool? isRequired, String? name, Extra? extra, }) => FormInputMetadata( export: export ?? this.export, + isRequired: isRequired ?? this.isRequired, name: name ?? this.name, extra: extra ?? this.extra, ); FormInputMetadata clone() => copyWith( export: export, + isRequired: isRequired, name: name, extra: extra, ); @override - bool? get stringify => true; + List get props => [export, isRequired, name, extra]; @override - List get props => [export, name, extra]; + String toString() => + 'FormInputMetada(name: $name, export: $export, isRequired: $isRequired, ' + '${(extra != null) ? "extra(${extra.runtimeType}): $extra" : ""})'; } diff --git a/packages/wyatt_form_bloc/test/form_validator_test.dart b/packages/wyatt_form_bloc/test/form_validator_test.dart new file mode 100644 index 00000000..7ea33f70 --- /dev/null +++ b/packages/wyatt_form_bloc/test/form_validator_test.dart @@ -0,0 +1,136 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +import 'package:flutter_test/flutter_test.dart'; +import 'package:wyatt_form_bloc/wyatt_form_bloc.dart'; + +void main() { + group('FormValidator', () { + WyattForm form = WyattFormImpl( + const [], + name: 'signInForm', + ); + group('EveryInputValidator', () { + setUp(() { + // Reset form + form = WyattFormImpl( + [ + FormInput( + 'email', + const Email.pure(), + ), + FormInput( + 'password', + const Password.pure(), + ), + FormInput( + 'phone', + const Phone.pure(), + metadata: const FormInputMetadata(isRequired: false), + ), + ], + name: 'signInForm', + ); + }); + test('returns `pure` on untouched form', () { + expect(form.validate(), FormStatus.pure); + }); + + test('returns `invalid` when 1 input is invalid', () { + form.updateValidator('email', const Email.dirty('incorrect')); + expect(form.validate(), FormStatus.invalid); + }); + + test('returns `invalid` when 1 no required input is invalid ', () { + form.updateValidator('phone', const Phone.dirty('incorrect')); + expect(form.validate(), FormStatus.invalid); + }); + + test('returns `valid` when all inputs are valid', () { + form + ..updateValidator('email', const Email.dirty('test@test.fr')) + ..updateValidator('password', const Password.dirty('password1234')) + ..updateValidator('phone', const Phone.dirty('0000000000')); + expect(form.validate(), FormStatus.valid); + }); + }); + + group('OnlyRequiredInputValidator', () { + setUp(() { + // Reset form + form = WyattFormImpl( + [ + FormInput( + 'email', + const Email.pure(), + ), + FormInput( + 'password', + const Password.pure(), + ), + FormInput( + 'phone', + const Phone.pure(), + metadata: const FormInputMetadata(isRequired: false), + ), + ], + name: 'signInForm', + validationStrategy: const OnlyRequiredInputValidator(), + ); + }); + test('returns `pure` on untouched form', () { + expect(form.validate(), FormStatus.pure); + }); + + test('returns `invalid` when 1 input is invalid', () { + form.updateValidator('email', const Email.dirty('incorrect')); + expect(form.validate(), FormStatus.invalid); + }); + + test( + 'returns `pure` when no required input ' + 'are invalid but other untouched', () { + form.updateValidator('phone', const Phone.dirty('incorrect')); + expect(form.validate(), FormStatus.pure); + }); + + test( + 'returns `valid` when required inputs ' + 'are valid but not the not required', () { + form + ..updateValidator('email', const Email.dirty('test@test.fr')) + ..updateValidator('password', const Password.dirty('password1234')) + ..updateValidator('phone', const Phone.dirty('incorrect')); + expect(form.validate(), FormStatus.valid); + }); + + test('returns `valid` when all required inputs are valid', () { + form + ..updateValidator('email', const Email.dirty('test@test.fr')) + ..updateValidator('password', const Password.dirty('password1234')); + expect(form.validate(), FormStatus.valid); + }); + + test('returns `valid` when all inputs are valid', () { + form + ..updateValidator('email', const Email.dirty('test@test.fr')) + ..updateValidator('password', const Password.dirty('password1234')) + ..updateValidator('phone', const Phone.dirty('0000000000')); + expect(form.validate(), FormStatus.valid); + }); + }); + }); +}