fix(auth): update form plugin and fix auth

This commit is contained in:
Hugo Pointcheval 2022-07-10 22:11:16 +02:00
parent 01df7a0dff
commit b21aa04557
Signed by: hugo
GPG Key ID: A9E8E9615379254F
7 changed files with 98 additions and 85 deletions

View File

@ -31,23 +31,29 @@ class App extends StatelessWidget {
static FormData getNormalFormData() { static FormData getNormalFormData() {
return const FormData([ return const FormData([
FormEntry(formFieldName, Name.pure()), FormInput(formFieldName, Name.pure()),
FormEntry(formFieldPhone, Phone.pure()), FormInput(formFieldPhone, Phone.pure()),
FormEntry(formFieldPro, Boolean.pure()), FormInput(formFieldPro, Boolean.pure()),
FormEntry(formFieldConfirmedPassword, ConfirmedPassword.pure(), FormInput(
export: false), formFieldConfirmedPassword,
ConfirmedPassword.pure(),
metadata: FormInputMetadata(export: false),
),
]); ]);
} }
static FormData getProFormData() { static FormData getProFormData() {
return const FormData([ return const FormData([
FormEntry(formFieldName, Name.pure()), FormInput(formFieldName, Name.pure()),
FormEntry(formFieldPhone, Phone.pure()), FormInput(formFieldPhone, Phone.pure()),
FormEntry(formFieldPro, Boolean.pure()), FormInput(formFieldPro, Boolean.pure()),
FormEntry(formFieldSiren, Siren.pure()), FormInput(formFieldSiren, Siren.pure()),
FormEntry(formFieldIban, Iban.pure()), FormInput(formFieldIban, Iban.pure()),
FormEntry(formFieldConfirmedPassword, ConfirmedPassword.pure(), FormInput(
export: false), formFieldConfirmedPassword,
ConfirmedPassword.pure(),
metadata: FormInputMetadata(export: false),
),
]); ]);
} }
@ -103,42 +109,42 @@ class App extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AuthenticationRepositoryInterface _authenticationRepository = AuthenticationRepositoryInterface authenticationRepository =
AuthenticationRepositoryFirebase(); AuthenticationRepositoryFirebase();
AuthenticationCubit _authenticationCubit = AuthenticationCubit( AuthenticationCubit authenticationCubit = AuthenticationCubit(
authenticationRepository: _authenticationRepository, authenticationRepository: authenticationRepository,
onAuthSuccess: onAuthSuccess, onAuthSuccess: onAuthSuccess,
); );
SignUpCubit _signUpCubit = SignUpCubit( SignUpCubit signUpCubit = SignUpCubit(
authenticationRepository: _authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: _authenticationCubit, authenticationCubit: authenticationCubit,
entries: getNormalFormData(), entries: getNormalFormData(),
onSignUpSuccess: onSignUpSuccess, onSignUpSuccess: onSignUpSuccess,
); );
SignInCubit _signInCubit = SignInCubit( SignInCubit signInCubit = SignInCubit(
authenticationRepository: _authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: _authenticationCubit, authenticationCubit: authenticationCubit,
); );
return MultiRepositoryProvider( return MultiRepositoryProvider(
providers: [ providers: [
RepositoryProvider<AuthenticationRepositoryInterface>( RepositoryProvider<AuthenticationRepositoryInterface>(
create: (context) => _authenticationRepository, create: (context) => authenticationRepository,
), ),
], ],
child: MultiBlocProvider( child: MultiBlocProvider(
providers: [ providers: [
BlocProvider<AuthenticationCubit>( BlocProvider<AuthenticationCubit>(
create: (context) => _authenticationCubit..init(), create: (context) => authenticationCubit..init(),
), ),
BlocProvider<SignUpCubit>( BlocProvider<SignUpCubit>(
create: (context) => _signUpCubit, create: (context) => signUpCubit,
), ),
BlocProvider<SignInCubit>( BlocProvider<SignInCubit>(
create: (context) => _signInCubit, create: (context) => signInCubit,
), ),
], ],
child: const AppView(), child: const AppView(),

View File

@ -37,7 +37,7 @@ class _NameInput extends StatelessWidget {
labelText: 'name', labelText: 'name',
helperText: '', helperText: '',
errorText: errorText:
state.data.input(formFieldName).invalid ? 'invalid name' : null, state.data.isNotValid(formFieldName) ? 'invalid name' : null,
), ),
); );
}, },
@ -58,7 +58,7 @@ class _PhoneInput extends StatelessWidget {
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'phone', labelText: 'phone',
helperText: '', helperText: '',
errorText: state.data.input(formFieldPhone).invalid errorText: state.data.isNotValid(formFieldPhone)
? 'invalid phone' ? 'invalid phone'
: null, : null,
), ),
@ -81,7 +81,7 @@ class _SirenInput extends StatelessWidget {
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'siren', labelText: 'siren',
helperText: '', helperText: '',
errorText: state.data.input(formFieldSiren).invalid errorText: state.data.isNotValid(formFieldSiren)
? 'invalid SIREN' ? 'invalid SIREN'
: null, : null,
), ),
@ -105,7 +105,7 @@ class _IbanInput extends StatelessWidget {
labelText: 'iban', labelText: 'iban',
helperText: '', helperText: '',
errorText: errorText:
state.data.input(formFieldIban).invalid ? 'invalid IBAN' : null, state.data.isNotValid(formFieldIban) ? 'invalid IBAN' : null,
), ),
); );
}, },
@ -149,8 +149,7 @@ class _PasswordInput extends StatelessWidget {
.read<SignUpCubit>() .read<SignUpCubit>()
.state .state
.data .data
.input(formFieldConfirmedPassword) .valueOf<String, ValidationError>(formFieldConfirmedPassword),
.value,
), ),
); );
}, },
@ -185,7 +184,7 @@ class _ConfirmPasswordInput extends StatelessWidget {
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'confirm password', labelText: 'confirm password',
helperText: '', helperText: '',
errorText: state.data.input(formFieldConfirmedPassword).invalid errorText: state.data.isNotValid(formFieldConfirmedPassword)
? 'passwords do not match' ? 'passwords do not match'
: null, : null,
), ),
@ -203,7 +202,7 @@ class _CheckIsProInput extends StatelessWidget {
trailing: BlocBuilder<SignUpCubit, SignUpState>( trailing: BlocBuilder<SignUpCubit, SignUpState>(
builder: (context, state) { builder: (context, state) {
return Checkbox( return Checkbox(
value: state.data.input<bool>(formFieldPro).value, value: state.data.valueOf<bool, ValidationError>(formFieldPro),
onChanged: (isPro) { onChanged: (isPro) {
final value = final value =
isPro!; // tristate is false, so value can't be null isPro!; // tristate is false, so value can't be null
@ -297,7 +296,7 @@ class SignUpForm extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
BlocBuilder<SignUpCubit, SignUpState>( BlocBuilder<SignUpCubit, SignUpState>(
builder: (context, state) { builder: (context, state) {
if (state.data.input<bool>(formFieldPro).value) { if (state.data.valueOf<bool, ValidationError>(formFieldPro)) {
return Column(children: [ return Column(children: [
_SirenInput(), _SirenInput(),
const SizedBox(height: 8), const SizedBox(height: 8),

View File

@ -33,7 +33,7 @@ class PasswordResetCubit extends Cubit<PasswordResetState> {
emit( emit(
state.copyWith( state.copyWith(
email: email, email: email,
status: FormData.validate([email]), status: FormStatus.validate([email]),
), ),
); );
} }

View File

@ -39,7 +39,7 @@ class SignInCubit extends Cubit<SignInState> {
emit( emit(
state.copyWith( state.copyWith(
email: email, email: email,
status: FormData.validate([email, state.password]), status: FormStatus.validate([email, state.password]),
), ),
); );
} }
@ -49,7 +49,7 @@ class SignInCubit extends Cubit<SignInState> {
emit( emit(
state.copyWith( state.copyWith(
password: password, password: password,
status: FormData.validate([state.email, password]), status: FormStatus.validate([state.email, password]),
), ),
); );
} }

View File

@ -44,16 +44,16 @@ class SignUpCubit extends Cubit<SignUpState> {
void emailChanged(String value) { void emailChanged(String value) {
final Email email = Email.dirty(value); final Email email = Email.dirty(value);
final List<FormInput<dynamic, ValidationError>> inputsToValidate = [ final List<FormInputValidator<dynamic, ValidationError>> toValidate = [
email, email,
state.password, state.password,
...state.data.inputs<dynamic>(), ...state.data.validators<dynamic, ValidationError>(),
]; ];
emit( emit(
state.copyWith( state.copyWith(
email: email, email: email,
status: FormData.validate(inputsToValidate), status: FormStatus.validate(toValidate),
), ),
); );
} }
@ -61,26 +61,26 @@ class SignUpCubit extends Cubit<SignUpState> {
void passwordChanged(String value) { void passwordChanged(String value) {
final Password password = Password.dirty(value); final Password password = Password.dirty(value);
final List<FormInput<dynamic, ValidationError>> inputsToValidate = [ final List<FormInputValidator<dynamic, ValidationError>> toValidate = [
state.email, state.email,
password, password,
...state.data.inputs<dynamic>(), ...state.data.validators<dynamic, ValidationError>(),
]; ];
emit( emit(
state.copyWith( state.copyWith(
password: password, password: password,
status: FormData.validate(inputsToValidate), status: FormStatus.validate(toValidate),
), ),
); );
} }
// Take from wyatt_form_bloc/wyatt_form_bloc.dart // Take from wyatt_form_bloc/wyatt_form_bloc.dart
void dataChanged<T>(String field, FormInput dirtyValue) { void dataChanged<T>(String field, FormInputValidator dirtyValue) {
final _form = state.data.clone(); final _form = state.data.clone();
if (_form.contains(field)) { if (_form.contains(field)) {
_form.update(field, dirtyValue); _form.updateValidator(field, dirtyValue);
} else { } else {
throw Exception('Form field $field not found'); throw Exception('Form field $field not found');
} }
@ -88,8 +88,12 @@ class SignUpCubit extends Cubit<SignUpState> {
emit( emit(
state.copyWith( state.copyWith(
data: _form, data: _form,
status: FormData.validate( status: FormStatus.validate(
[state.email, state.password, ..._form.inputs<dynamic>()], [
state.email,
state.password,
...state.data.validators<dynamic, ValidationError>(),
],
), ),
), ),
); );
@ -120,8 +124,12 @@ class SignUpCubit extends Cubit<SignUpState> {
emit( emit(
state.copyWith( state.copyWith(
data: _form, data: _form,
status: FormData.validate( status: FormStatus.validate(
[state.email, state.password, ..._form.inputs<dynamic>()], [
state.email,
state.password,
...state.data.validators<dynamic, ValidationError>(),
],
), ),
), ),
); );

View File

@ -68,9 +68,9 @@ void main() {
SignUpCubit( SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
).state, ).state,
SignUpState(data: FormData.empty()), const SignUpState(data: FormData.empty()),
); );
}); });
@ -80,11 +80,11 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
act: (SignUpCubit cubit) => cubit.emailChanged(invalidEmailString), act: (SignUpCubit cubit) => cubit.emailChanged(invalidEmailString),
expect: () => <SignUpState>[ expect: () => <SignUpState>[
SignUpState( const SignUpState(
email: invalidEmail, email: invalidEmail,
status: FormStatus.invalid, status: FormStatus.invalid,
data: FormData.empty(), data: FormData.empty(),
@ -97,15 +97,15 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
seed: () => SignUpState( seed: () => const SignUpState(
password: validPassword, password: validPassword,
data: FormData.empty(), data: FormData.empty(),
), ),
act: (SignUpCubit cubit) => cubit.emailChanged(validEmailString), act: (SignUpCubit cubit) => cubit.emailChanged(validEmailString),
expect: () => <SignUpState>[ expect: () => <SignUpState>[
SignUpState( const SignUpState(
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
status: FormStatus.valid, status: FormStatus.valid,
@ -121,12 +121,12 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
act: (SignUpCubit cubit) => act: (SignUpCubit cubit) =>
cubit.passwordChanged(invalidPasswordString), cubit.passwordChanged(invalidPasswordString),
expect: () => <SignUpState>[ expect: () => <SignUpState>[
SignUpState( const SignUpState(
password: invalidPassword, password: invalidPassword,
status: FormStatus.invalid, status: FormStatus.invalid,
data: FormData.empty(), data: FormData.empty(),
@ -139,15 +139,15 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
seed: () => SignUpState( seed: () => const SignUpState(
email: validEmail, email: validEmail,
data: FormData.empty(), data: FormData.empty(),
), ),
act: (SignUpCubit cubit) => cubit.passwordChanged(validPasswordString), act: (SignUpCubit cubit) => cubit.passwordChanged(validPasswordString),
expect: () => <SignUpState>[ expect: () => <SignUpState>[
SignUpState( const SignUpState(
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
status: FormStatus.valid, status: FormStatus.valid,
@ -163,7 +163,7 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(), act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(),
expect: () => const <SignUpState>[], expect: () => const <SignUpState>[],
@ -174,9 +174,9 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
seed: () => SignUpState( seed: () => const SignUpState(
status: FormStatus.valid, status: FormStatus.valid,
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
@ -199,9 +199,9 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
seed: () => SignUpState( seed: () => const SignUpState(
status: FormStatus.valid, status: FormStatus.valid,
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
@ -209,13 +209,13 @@ void main() {
), ),
act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(), act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(),
expect: () => <SignUpState>[ expect: () => <SignUpState>[
SignUpState( const SignUpState(
status: FormStatus.submissionInProgress, status: FormStatus.submissionInProgress,
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
data: FormData.empty(), data: FormData.empty(),
), ),
SignUpState( const SignUpState(
status: FormStatus.submissionSuccess, status: FormStatus.submissionSuccess,
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
@ -238,9 +238,9 @@ void main() {
build: () => SignUpCubit( build: () => SignUpCubit(
authenticationRepository: authenticationRepository, authenticationRepository: authenticationRepository,
authenticationCubit: authenticationCubit, authenticationCubit: authenticationCubit,
entries: FormData.empty(), entries: const FormData.empty(),
), ),
seed: () => SignUpState( seed: () => const SignUpState(
status: FormStatus.valid, status: FormStatus.valid,
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
@ -248,13 +248,13 @@ void main() {
), ),
act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(), act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(),
expect: () => <SignUpState>[ expect: () => <SignUpState>[
SignUpState( const SignUpState(
status: FormStatus.submissionInProgress, status: FormStatus.submissionInProgress,
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,
data: FormData.empty(), data: FormData.empty(),
), ),
SignUpState( const SignUpState(
status: FormStatus.submissionFailure, status: FormStatus.submissionFailure,
email: validEmail, email: validEmail,
password: validPassword, password: validPassword,

View File

@ -26,10 +26,10 @@ void main() {
group('SignUpState', () { group('SignUpState', () {
test('supports value comparisons', () { test('supports value comparisons', () {
expect( expect(
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
), ),
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
), ),
); );
@ -37,10 +37,10 @@ void main() {
test('returns same object when no properties are passed', () { test('returns same object when no properties are passed', () {
expect( expect(
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
).copyWith(), ).copyWith(),
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
), ),
); );
@ -48,10 +48,10 @@ void main() {
test('returns object with updated status when status is passed', () { test('returns object with updated status when status is passed', () {
expect( expect(
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
).copyWith(status: FormStatus.pure), ).copyWith(status: FormStatus.pure),
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
), ),
); );
@ -59,10 +59,10 @@ void main() {
test('returns object with updated email when email is passed', () { test('returns object with updated email when email is passed', () {
expect( expect(
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
).copyWith(email: email), ).copyWith(email: email),
SignUpState( const SignUpState(
email: email, email: email,
data: FormData.empty(), data: FormData.empty(),
), ),
@ -71,10 +71,10 @@ void main() {
test('returns object with updated password when password is passed', () { test('returns object with updated password when password is passed', () {
expect( expect(
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
).copyWith(password: password), ).copyWith(password: password),
SignUpState( const SignUpState(
password: password, password: password,
data: FormData.empty(), data: FormData.empty(),
), ),
@ -85,12 +85,12 @@ void main() {
'returns object with updated data' 'returns object with updated data'
' when data is passed', () { ' when data is passed', () {
expect( expect(
SignUpState( const SignUpState(
data: FormData.empty(), data: FormData.empty(),
).copyWith( ).copyWith(
data: const FormData( data: const FormData(
[ [
FormEntry( FormInput(
'field', 'field',
Name.pure(), Name.pure(),
), ),
@ -100,7 +100,7 @@ void main() {
const SignUpState( const SignUpState(
data: FormData( data: FormData(
[ [
FormEntry( FormInput(
'field', 'field',
Name.pure(), Name.pure(),
), ),