forked from eatvio/eatvio_app
feat(consultant_refistration): added explicit validation for scoring data
This commit is contained in:
@@ -158,6 +158,10 @@ void main() {
|
||||
expect(valid.hasValidPassportData, isTrue);
|
||||
expect(valid.copyWith(inn: '123').hasValidPassportData, isFalse);
|
||||
expect(valid.copyWith(lastName: '').hasValidPassportData, isFalse);
|
||||
expect(
|
||||
valid.copyWith(birthDate: '2020-02-31').hasValidPassportData,
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -463,7 +463,30 @@ void main() {
|
||||
expect(cubit.state.isScoringPolling, isFalse);
|
||||
});
|
||||
|
||||
test('registerConsultant blocks submit without passport data', () async {
|
||||
test(
|
||||
'retryScoring writes fieldErrors when passport data is invalid',
|
||||
() async {
|
||||
cubit.emit(
|
||||
cubit.state.copyWith(
|
||||
alfaScoringStatus: AlfaScoringStatus.scoringFailed,
|
||||
loading: false,
|
||||
),
|
||||
);
|
||||
|
||||
await cubit.retryScoring();
|
||||
|
||||
expect(cubit.state.fieldErrors['inn'], 'Укажите ИНН');
|
||||
expect(cubit.state.alfaScoringStatus, AlfaScoringStatus.scoringFailed);
|
||||
verifyNever(
|
||||
() => repository.registerConsultant(
|
||||
consultant: any<ConsultantProfileModel>(named: 'consultant'),
|
||||
update: any<bool>(named: 'update'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test('registerConsultant writes fieldErrors without calling API', () async {
|
||||
when(
|
||||
() => repository.registerConsultant(
|
||||
consultant: any<ConsultantProfileModel>(named: 'consultant'),
|
||||
@@ -473,7 +496,10 @@ void main() {
|
||||
|
||||
await cubit.registerConsultant();
|
||||
|
||||
expect(cubit.state.error, 'Заполните паспортные данные');
|
||||
expect(cubit.state.fieldErrors['last_name'], 'Укажите фамилию');
|
||||
expect(cubit.state.fieldErrors['inn'], 'Укажите ИНН');
|
||||
expect(cubit.state.fieldErrors['birth_date'], 'Укажите дату рождения');
|
||||
expect(cubit.state.error, isNull);
|
||||
verifyNever(
|
||||
() => repository.registerConsultant(
|
||||
consultant: any<ConsultantProfileModel>(named: 'consultant'),
|
||||
@@ -482,6 +508,19 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('editing a field clears only that field error', () async {
|
||||
await cubit.registerConsultant();
|
||||
expect(cubit.state.fieldErrors.containsKey('last_name'), isTrue);
|
||||
expect(cubit.state.fieldErrors.containsKey('inn'), isTrue);
|
||||
|
||||
cubit.updateConsultantProfileModel(
|
||||
cubit.state.consultant.copyWith(lastName: 'Иванов'),
|
||||
);
|
||||
|
||||
expect(cubit.state.fieldErrors.containsKey('last_name'), isFalse);
|
||||
expect(cubit.state.fieldErrors['inn'], 'Укажите ИНН');
|
||||
});
|
||||
|
||||
test('registerConsultant maps Laravel 422 into fieldErrors', () async {
|
||||
when(
|
||||
() => repository.registerConsultant(
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/features/consultant/become_consultant/presentation/bl
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/passport_data_screen.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@@ -60,5 +61,19 @@ void main() {
|
||||
expect(find.text('Банк получатель (поиск)'), findsOneWidget);
|
||||
expect(find.text('Я являюсь налоговым резидентом США'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('shows ValidationErrorWidget for invalid field', (
|
||||
tester,
|
||||
) async {
|
||||
cubit.emit(
|
||||
cubit.state.copyWith(fieldErrors: const {'inn': 'Некорректный ИНН'}),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(wrap(const PassportDataScreen()));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(ValidationErrorWidget), findsOneWidget);
|
||||
expect(find.text('Некорректный ИНН'), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_profile_model.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/utils/passport_data_validator.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
const valid = ConsultantProfileModel(
|
||||
lastName: 'Иванов',
|
||||
firstName: 'Иван',
|
||||
inn: '123456789012',
|
||||
snils: '123-456-789 00',
|
||||
passportSeries: '1234',
|
||||
passportNumber: '567890',
|
||||
passportIssueDate: '2020-01-15',
|
||||
passportIssuer: 'ОВД',
|
||||
passportIssuerCode: '772-053',
|
||||
birthDate: '1990-05-20',
|
||||
birthPlace: 'Москва',
|
||||
registrationAddress: 'Адрес 1',
|
||||
residenceAddress: 'Адрес 2',
|
||||
citizenship: 'RU',
|
||||
);
|
||||
|
||||
group('PassportDataValidator', () {
|
||||
test('returns empty map for a valid individual person profile', () {
|
||||
expect(PassportDataValidator.validate(valid), isEmpty);
|
||||
});
|
||||
|
||||
test('requires empty text fields', () {
|
||||
final errors = PassportDataValidator.validate(
|
||||
valid.copyWith(lastName: '', firstName: null),
|
||||
);
|
||||
|
||||
expect(errors['last_name'], 'Укажите фамилию');
|
||||
expect(errors['first_name'], 'Укажите имя');
|
||||
});
|
||||
|
||||
test('rejects short INN and malformed SNILS', () {
|
||||
final errors = PassportDataValidator.validate(
|
||||
valid.copyWith(inn: '123', snils: '12345678900'),
|
||||
);
|
||||
|
||||
expect(errors['inn'], 'Некорректный ИНН');
|
||||
expect(errors['snils'], 'Некорректный СНИЛС');
|
||||
});
|
||||
|
||||
test('rejects empty INN and SNILS', () {
|
||||
final errors = PassportDataValidator.validate(
|
||||
valid.copyWith(inn: '', snils: ''),
|
||||
);
|
||||
|
||||
expect(errors['inn'], 'Укажите ИНН');
|
||||
expect(errors['snils'], 'Укажите СНИЛС');
|
||||
});
|
||||
|
||||
test('rejects non-calendar dates', () {
|
||||
final errors = PassportDataValidator.validate(
|
||||
valid.copyWith(
|
||||
birthDate: '2020-02-31',
|
||||
passportIssueDate: '1999-13-32',
|
||||
),
|
||||
);
|
||||
|
||||
expect(errors['birth_date'], 'Некорректная дата рождения');
|
||||
expect(errors['passport_issue_date'], 'Некорректная дата выдачи');
|
||||
});
|
||||
|
||||
test('rejects dates in the future', () {
|
||||
final errors = PassportDataValidator.validate(
|
||||
valid.copyWith(
|
||||
birthDate: '2030-01-01',
|
||||
passportIssueDate: '2030-01-01',
|
||||
),
|
||||
now: DateTime(2026, 8, 13),
|
||||
);
|
||||
|
||||
expect(errors['birth_date'], PassportDataValidator.futureDateMessage);
|
||||
expect(
|
||||
errors['passport_issue_date'],
|
||||
PassportDataValidator.futureDateMessage,
|
||||
);
|
||||
});
|
||||
|
||||
test('accepts today as a valid date', () {
|
||||
final errors = PassportDataValidator.validate(
|
||||
valid.copyWith(passportIssueDate: '2026-08-13'),
|
||||
now: DateTime(2026, 8, 13, 18),
|
||||
);
|
||||
|
||||
expect(errors.containsKey('passport_issue_date'), isFalse);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user