diff --git a/lib/core/routing/main_navigation_routes.dart b/lib/core/routing/main_navigation_routes.dart index d6dd7420..d0746c88 100644 --- a/lib/core/routing/main_navigation_routes.dart +++ b/lib/core/routing/main_navigation_routes.dart @@ -89,16 +89,7 @@ class MainNavigationRoutes { GoRoute( path: RouteConstants.menuScreen, name: 'menuScreen', - pageBuilder: (context, state) => NoTransitionPage( - child: BlocBuilder( - builder: (BuildContext context, ProfileAvatarState state) { - if (state is ProfileAvatarStateLoaded) { - return MenuScreen(profileModel: state.profile); - } - return const SizedBox.shrink(); - }, - ), - ), + pageBuilder: (context, state) => const NoTransitionPage(child: MenuScreen()), ), ], ), diff --git a/lib/features/menu/presentation/bloc/menu_cubit/menu_cubit.dart b/lib/features/menu/presentation/bloc/menu_cubit/menu_cubit.dart index b4ab6b41..3d5b94ed 100644 --- a/lib/features/menu/presentation/bloc/menu_cubit/menu_cubit.dart +++ b/lib/features/menu/presentation/bloc/menu_cubit/menu_cubit.dart @@ -7,7 +7,19 @@ import 'package:eatvio_app/core/error_reporting/report_from.dart'; class MenuCubit extends Cubit { final ProfileRepository profileRepository; - MenuCubit(this.profileRepository) : super(MenuState()); + MenuCubit(this.profileRepository) : super(const MenuState.initial()); + + Future getMyProfile() async { + emit(const MenuState.loading()); + try { + final profile = await profileRepository.getMyProfile(); + emit(MenuState.loaded(profileModel: profile)); + } catch (e, st) { + await reportFrom(e, st, this); + log(e.toString()); + emit(const MenuState.error()); + } + } Future makePassKey() async { try { diff --git a/lib/features/menu/presentation/bloc/menu_cubit/menu_state.dart b/lib/features/menu/presentation/bloc/menu_cubit/menu_state.dart index 70f37bb8..51dfcc1d 100644 --- a/lib/features/menu/presentation/bloc/menu_cubit/menu_state.dart +++ b/lib/features/menu/presentation/bloc/menu_cubit/menu_state.dart @@ -1 +1,17 @@ -class MenuState {} \ No newline at end of file +import 'package:eatvio_app/features/profile/models/profile_model.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'menu_state.freezed.dart'; + +@freezed +abstract class MenuState with _$MenuState { + const factory MenuState.initial() = MenuStateInitial; + + const factory MenuState.loading() = MenuStateLoading; + + const factory MenuState.loaded({ + required ProfileModel profileModel, + }) = MenuStateLoaded; + + const factory MenuState.error() = MenuStateError; +} \ No newline at end of file diff --git a/lib/features/menu/presentation/pages/menu_screen.dart b/lib/features/menu/presentation/pages/menu_screen.dart index 859b1b6f..05cabce2 100644 --- a/lib/features/menu/presentation/pages/menu_screen.dart +++ b/lib/features/menu/presentation/pages/menu_screen.dart @@ -6,6 +6,8 @@ import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/token_storage.dart'; import 'package:eatvio_app/core/utils/image_constant.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; +import 'package:eatvio_app/core/widgets/data_error_widget.dart'; +import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/websockets/ws_manager.dart'; @@ -13,9 +15,9 @@ import 'package:eatvio_app/features/consultant_rating/presentation/consultant_ra import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/consultant_finances_screen.dart'; import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart'; import 'package:eatvio_app/features/menu/presentation/bloc/menu_cubit/menu_cubit.dart'; +import 'package:eatvio_app/features/menu/presentation/bloc/menu_cubit/menu_state.dart'; import 'package:eatvio_app/features/my_diets/presentation/my_diets_screen.dart'; import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart'; -import 'package:eatvio_app/features/profile/models/profile_model.dart'; import 'package:eatvio_app/features/recipe/presentation/pages/my_recipes_screen.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -25,90 +27,107 @@ import 'package:go_router/go_router.dart'; import 'package:package_info_plus/package_info_plus.dart'; class MenuScreen extends StatelessWidget { - final ProfileModel profileModel; - - const MenuScreen({super.key, required this.profileModel}); + const MenuScreen({super.key}); @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => sl(), + create: (context) => sl()..getMyProfile(), child: Builder( builder: (context) { - return Scaffold( - appBar: AppBar(centerTitle: false, title: const Text('Меню')), - body: SingleChildScrollView( - child: Column( - children: [ - _tile(title: 'Настройки профиля', leading: ImageConstant.icnProfileSettings, onTap: () => GoRouter.of(context).push('/settings-screen')), - if (profileModel.roles.contains('consultant')) _divider(context), - if (profileModel.roles.contains('consultant')) - _tile(leading: ImageConstant.icnRecipes, title: 'Мои рецепты', onTap: () => GoRouter.of(context).push(MyRecipesScreen.path)), - if (profileModel.roles.contains('consultant')) _divider(context), - if (profileModel.roles.contains('consultant')) - _tile(leading: 'assets/icons/diets.svg', title: 'Мои диеты', onTap: () => GoRouter.of(context).push(MyDietsScreen.path)), - if (profileModel.roles.contains('consultant')) _divider(context), - if (profileModel.roles.contains('consultant')) - _tile(leading: ImageConstant.icnPlans, title: 'Мои планы', onTap: () => GoRouter.of(context).push(MyPlansScreen.path)), - if (!hidePlans) ...[ - _divider(context), - _tile( - leading: 'assets/icons/finance.svg', - title: 'Мои финансы', - onTap: () { - if (profileModel.roles.contains('consultant')) { - GoRouter.of(context).push(ConsultantFinancesScreen.path); - return; - } - GoRouter.of(context).push(UserPurchasesScreen.path); - }, + return BlocBuilder( + builder: (BuildContext context, MenuState state) { + if (state is MenuStateLoaded) { + final profileModel = state.profileModel; + return Scaffold( + appBar: AppBar(centerTitle: false, title: const Text('Меню')), + body: SingleChildScrollView( + child: Column( + children: [ + _tile(title: 'Настройки профиля', leading: ImageConstant.icnProfileSettings, onTap: () => GoRouter.of(context).push('/settings-screen')), + if (profileModel.roles.contains('consultant')) _divider(context), + if (profileModel.roles.contains('consultant')) + _tile(leading: ImageConstant.icnRecipes, title: 'Мои рецепты', onTap: () => GoRouter.of(context).push(MyRecipesScreen.path)), + if (profileModel.roles.contains('consultant')) _divider(context), + if (profileModel.roles.contains('consultant')) + _tile(leading: 'assets/icons/diets.svg', title: 'Мои диеты', onTap: () => GoRouter.of(context).push(MyDietsScreen.path)), + if (profileModel.roles.contains('consultant')) _divider(context), + if (profileModel.roles.contains('consultant')) + _tile(leading: ImageConstant.icnPlans, title: 'Мои планы', onTap: () => GoRouter.of(context).push(MyPlansScreen.path)), + if (!hidePlans) ...[ + _divider(context), + _tile( + leading: 'assets/icons/finance.svg', + title: 'Мои финансы', + onTap: () { + if (profileModel.roles.contains('consultant')) { + GoRouter.of(context).push(ConsultantFinancesScreen.path); + return; + } + GoRouter.of(context).push(UserPurchasesScreen.path); + }, + ), + ], + if (profileModel.roles.contains('consultant')) _divider(context), + if (profileModel.roles.contains('consultant')) + _tile( + leading: 'assets/icons/consultant_rating_icon.svg', + title: 'Мой рейтинг', + onTap: () { + GoRouter.of(context).push(ConsultantRatingScreen.path); + }, + ), + _divider(context), + _tile( + leading: ImageConstant.icnGlossary, + title: 'Глоссарий', + onTap: () async { + final passKey = await context.read().makePassKey(); + if (passKey != null && context.mounted) { + GoRouter.of(context).push('/glossary-screen', extra: passKey); + } + }, + ), + _divider(context), + _tile( + leading: 'assets/icons/notifications.svg', + title: 'Уведомления', + onTap: () => GoRouter.of(context).pushNamed('notificationsSettingsScreen'), + ), + _divider(context), + _tile(leading: ImageConstant.icnSupport, title: 'Поддержка', onTap: () => GoRouter.of(context).push('/support-screen')), + _divider(context), + _tile(leading: 'assets/icons/blocked_users.svg', title: 'Чёрный список', onTap: () => GoRouter.of(context).pushNamed('blockedUsersScreen')), + // _divider(context), + // _tile( + // leading: ImageConstant.icnDevTools, + // title: 'Для разработчиков', + // onTap: () { + // GoRouter.of(context).pushNamed(DevToolsScreen.name); + // }, + // ), + _divider(context), + _tile(leading: ImageConstant.icnExit, title: 'Выход', onTap: _onTapLogout(context)), + const SizedBox(height: 10), + const AppInfo(), + ], ), - ], - if (profileModel.roles.contains('consultant')) _divider(context), - if (profileModel.roles.contains('consultant')) - _tile( - leading: 'assets/icons/consultant_rating_icon.svg', - title: 'Мой рейтинг', - onTap: () { - GoRouter.of(context).push(ConsultantRatingScreen.path); - }, - ), - _divider(context), - _tile( - leading: ImageConstant.icnGlossary, - title: 'Глоссарий', - onTap: () async { - final passKey = await context.read().makePassKey(); - if (passKey != null && context.mounted) { - GoRouter.of(context).push('/glossary-screen', extra: passKey); - } - }, ), - _divider(context), - _tile( - leading: 'assets/icons/notifications.svg', - title: 'Уведомления', - onTap: () => GoRouter.of(context).pushNamed('notificationsSettingsScreen'), - ), - _divider(context), - _tile(leading: ImageConstant.icnSupport, title: 'Поддержка', onTap: () => GoRouter.of(context).push('/support-screen')), - _divider(context), - _tile(leading: 'assets/icons/blocked_users.svg', title: 'Чёрный список', onTap: () => GoRouter.of(context).pushNamed('blockedUsersScreen')), - // _divider(context), - // _tile( - // leading: ImageConstant.icnDevTools, - // title: 'Для разработчиков', - // onTap: () { - // GoRouter.of(context).pushNamed(DevToolsScreen.name); - // }, - // ), - _divider(context), - _tile(leading: ImageConstant.icnExit, title: 'Выход', onTap: _onTapLogout(context)), - const SizedBox(height: 10), - const AppInfo(), - ], - ), - ), + ); + } + + if (state is MenuStateError) { + return Scaffold( + appBar: AppBar(centerTitle: false, title: const Text('Меню')), + body: DataErrorWidget(onReload: () async => context.read().getMyProfile()), + ); + } + + return Scaffold( + appBar: AppBar(centerTitle: false, title: const Text('Меню')), + body: const Loader(), + ); + }, ); }, ), diff --git a/lib/features/settings/presentation/pages/general_info_screen.dart b/lib/features/settings/presentation/pages/general_info_screen.dart index 7ea472ab..2f799bf7 100644 --- a/lib/features/settings/presentation/pages/general_info_screen.dart +++ b/lib/features/settings/presentation/pages/general_info_screen.dart @@ -1,6 +1,8 @@ import 'package:eatvio_app/core/data/selectionPopupModel/selection_popup_model.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; import 'package:eatvio_app/core/widgets/custom_drop_down.dart'; +import 'package:eatvio_app/core/widgets/loader.dart'; +import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widget.dart'; import 'package:eatvio_app/features/settings/entities/settings_entity.dart'; import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_state.dart'; import 'package:eatvio_app/generated/l10n.dart'; @@ -8,15 +10,11 @@ import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/widgets/custom_text_form_field.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; class GeneralInfoScreen extends StatefulWidget { final SettingsEntity settingsEntity; - const GeneralInfoScreen({ - super.key, - required this.settingsEntity, - }); + const GeneralInfoScreen({super.key, required this.settingsEntity}); @override State createState() => _GeneralInfoScreenState(); @@ -31,6 +29,10 @@ class _GeneralInfoScreenState extends State { final cityController = TextEditingController(); final languageController = TextEditingController(); late SelectionPopupModel isPublicProfile; + bool isLoading = false; + bool isNameMissing = false; + bool isLastNameMissing = false; + bool isLanguageMissing = false; final List genderSelectionPopupList = [ const SelectionPopupModel(id: 0, title: 'Женский', value: 'female'), @@ -53,8 +55,9 @@ class _GeneralInfoScreenState extends State { countryController.text = widget.settingsEntity.profileDetailsModel.country; cityController.text = widget.settingsEntity.profileDetailsModel.city; languageController.text = widget.settingsEntity.profileDetailsModel.lang; - isPublicProfile = - widget.settingsEntity.profileSettingsModel.isPublicProfile == true ? isPublicProfileSelectionPopupList[1] : isPublicProfileSelectionPopupList[0]; + isPublicProfile = widget.settingsEntity.profileSettingsModel.isPublicProfile == true + ? isPublicProfileSelectionPopupList[1] + : isPublicProfileSelectionPopupList[0]; } @override @@ -62,9 +65,7 @@ class _GeneralInfoScreenState extends State { final s = S.of(context); return Scaffold( - appBar: AppBar( - title: const Text('Общая информация'), - ), + appBar: AppBar(title: const Text('Общая информация')), bottomSheet: SafeArea( top: false, child: Padding( @@ -80,34 +81,31 @@ class _GeneralInfoScreenState extends State { children: [ Text(s.first_name), const SizedBox(height: 4), - CustomTextFormField( - controller: firstNameController, - hintText: 'Введите имя', - onChanged: (newValue) {}, + Column( + children: [ + CustomTextFormField(hasError: isNameMissing, controller: firstNameController, hintText: 'Введите имя', onChanged: (newValue) {}), + if (isNameMissing) ...[const SizedBox(height: 4), const ValidationErrorWidget(error: 'Имя не может быть пустым')], + ], ), const SizedBox(height: 16), Text(s.last_name), const SizedBox(height: 4), - CustomTextFormField( - controller: lastNameController, - hintText: 'Введите фамилию', - onChanged: (newValue) {}, + Column( + children: [ + CustomTextFormField(hasError: isLastNameMissing, controller: lastNameController, hintText: 'Введите фамилию', onChanged: (newValue) {}), + if (isLastNameMissing) ...[const SizedBox(height: 4), const ValidationErrorWidget(error: 'Фамилия не может быть пустой')], + ], ), const SizedBox(height: 16), Text(s.date_of_birth), const SizedBox(height: 4), ListTile( onTap: onTapCalendar(context), - trailing: Icon( - Icons.keyboard_arrow_down_rounded, - color: Colors.grey.shade700, - ), + trailing: Icon(Icons.keyboard_arrow_down_rounded, color: Colors.grey.shade700), contentPadding: const EdgeInsets.symmetric(horizontal: 12), title: Text(selectedDate.format('dd MMMM yyyy', 'ru')), tileColor: const Color(0xFFF6F6F6), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), const SizedBox(height: 16), const Text('Пол'), @@ -124,20 +122,19 @@ class _GeneralInfoScreenState extends State { const SizedBox(height: 16), const Text('Страна'), const SizedBox(height: 4), - CustomTextFormField( - controller: countryController, - ), + CustomTextFormField(controller: countryController), const SizedBox(height: 16), const Text('Город'), const SizedBox(height: 4), - CustomTextFormField( - controller: cityController, - ), + CustomTextFormField(controller: cityController), const SizedBox(height: 16), const Text('Предпочтительный язык общения'), const SizedBox(height: 4), - CustomTextFormField( - controller: languageController, + Column( + children: [ + CustomTextFormField(hasError: isLanguageMissing, controller: languageController), + if (isLanguageMissing) ...[const SizedBox(height: 4), const ValidationErrorWidget(error: 'Язык не может быть пустым')], + ], ), const SizedBox(height: 16), const Text('Показывать анкету'), @@ -181,59 +178,92 @@ class _GeneralInfoScreenState extends State { builder: (BuildContext context) => Container( height: 216, padding: const EdgeInsets.only(top: 6), - margin: EdgeInsets.only( - bottom: MediaQuery.of(context).viewInsets.bottom, - ), + margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), color: CupertinoColors.systemBackground.resolveFrom(context), - child: SafeArea( - top: false, - child: child, - ), + child: SafeArea(top: false, child: child), ), ); } - InkWell _saveButton() { - return InkWell( - onTap: () { - widget.settingsEntity.settingsCubit.updateProfileDetails( - profileDetailsModel: (widget.settingsEntity.settingsCubit.state as SettingsStateLoaded).profileDetails.copyWith( - firstName: firstNameController.text, - lastName: lastNameController.text, - birthdate: selectedDate.toString(), - gender: gender.value, - country: countryController.text, - city: cityController.text, - lang: languageController.text, - ), - ); - widget.settingsEntity.settingsCubit.updateProfileSettings( - profileSettingsModel: (widget.settingsEntity.settingsCubit.state as SettingsStateLoaded).profileSettings.copyWith( - isPublicProfile: isPublicProfile.value, + bool _checkFields() { + bool hasError = false; + if (firstNameController.text.isEmpty) { + setState(() { + isNameMissing = true; + }); + hasError = true; + } else { + setState(() { + isNameMissing = false; + }); + } + if (lastNameController.text.isEmpty) { + setState(() { + isLastNameMissing = true; + }); + hasError = true; + } else { + setState(() { + isLastNameMissing = false; + }); + } + if (languageController.text.isEmpty) { + setState(() { + isLanguageMissing = true; + }); + hasError = true; + } else { + setState(() { + isLanguageMissing = false; + }); + } + return hasError; + } + + Widget _saveButton() { + return isLoading + ? const Center(child: Loader()) + : InkWell( + onTap: () async { + final hasError = _checkFields(); + if (hasError) { + return; + } + setState(() { + isLoading = true; + }); + await widget.settingsEntity.settingsCubit.updateProfileDetails( + profileDetailsModel: (widget.settingsEntity.settingsCubit.state as SettingsStateLoaded).profileDetails.copyWith( + firstName: firstNameController.text, + lastName: lastNameController.text, + birthdate: selectedDate.toString(), + gender: gender.value, + country: countryController.text, + city: cityController.text, + lang: languageController.text, + ), + ); + await widget.settingsEntity.settingsCubit.updateProfileSettings( + profileSettingsModel: (widget.settingsEntity.settingsCubit.state as SettingsStateLoaded).profileSettings.copyWith( + isPublicProfile: isPublicProfile.value, + ), + ); + setState(() { + isLoading = false; + }); + }, + borderRadius: BorderRadius.circular(20), + child: Ink( + height: 52, + width: MediaQuery.of(context).size.width - 32, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: appTheme.blueA400), + child: const Center( + child: Text( + 'Сохранить', + style: TextStyle(color: Colors.white, height: 1, fontWeight: FontWeight.w600, fontSize: 18), + ), ), - ); - GoRouter.of(context).pop(); - }, - borderRadius: BorderRadius.circular(20), - child: Ink( - height: 52, - width: MediaQuery.of(context).size.width - 32, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: appTheme.blueA400, - ), - child: const Center( - child: Text( - 'Сохранить', - style: TextStyle( - color: Colors.white, - height: 1, - fontWeight: FontWeight.w600, - fontSize: 18, ), - ), - ), - ), - ); + ); } } diff --git a/test/features/menu/presentation/bloc/menu_cubit/menu_state_test.dart b/test/features/menu/presentation/bloc/menu_cubit/menu_state_test.dart index 98a09db5..eae4f6ca 100644 --- a/test/features/menu/presentation/bloc/menu_cubit/menu_state_test.dart +++ b/test/features/menu/presentation/bloc/menu_cubit/menu_state_test.dart @@ -1,32 +1,64 @@ import 'package:eatvio_app/features/menu/presentation/bloc/menu_cubit/menu_state.dart'; +import 'package:eatvio_app/features/profile/models/profile_model.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { group('MenuState', () { - test('creates MenuState instance', () { - final state = MenuState(); + test('creates MenuState initial state', () { + const state = MenuState.initial(); expect(state, isNotNull); - expect(state, isA()); + expect(state, isA()); }); - test('creates multiple MenuState instances', () { - final state1 = MenuState(); - final state2 = MenuState(); - - expect(state1, isNotNull); - expect(state2, isNotNull); - expect(state1, isA()); - expect(state2, isA()); + test('creates MenuState loading state', () { + const state = MenuState.loading(); + expect(state, isNotNull); + expect(state, isA()); }); - test('MenuState instances are not equal by default', () { - final state1 = MenuState(); - final state2 = MenuState(); + test('creates MenuState error state', () { + const state = MenuState.error(); + expect(state, isNotNull); + expect(state, isA()); + }); - // MenuState is a regular class without overridden == operator, - // so instances are compared by reference - expect(state1 == state2, isFalse); - expect(state1, isNot(same(state2))); + test('creates MenuState loaded state', () { + const profile = ProfileModel( + id: 1, + name: 'Test', + email: 'test@example.com', + phoneConfirmationState: 'confirmed', + isPublicProfile: true, + isBlockedByMe: false, + isBlockedByAuthor: false, + isBlockedByUser: false, + isEntitySubscribedByMe: false, + profilePhotoUrl: 'https://example.com/icon.jpg', + roles: [], + badges: [], + subscriptions: [], + subscribers: [], + slug: 'test-user', + ); + const state = MenuState.loaded(profileModel: profile); + expect(state, isNotNull); + expect(state, isA()); + expect((state as MenuStateLoaded).profileModel, isNotNull); + expect((state).profileModel.id, 1); + expect((state).profileModel.name, 'Test'); + expect((state).profileModel.email, 'test@example.com'); + expect((state).profileModel.phoneConfirmationState, 'confirmed'); + expect((state).profileModel.isPublicProfile, true); + expect((state).profileModel.isBlockedByMe, false); + expect((state).profileModel.isBlockedByAuthor, false); + expect((state).profileModel.isBlockedByUser, false); + expect((state).profileModel.isEntitySubscribedByMe, false); + expect((state).profileModel.profilePhotoUrl, 'https://example.com/icon.jpg'); + expect((state).profileModel.roles, []); + expect((state).profileModel.badges, []); + expect((state).profileModel.subscriptions, []); + expect((state).profileModel.subscribers, []); + expect((state).profileModel.slug, 'test-user'); }); }); } diff --git a/test/features/menu/presentation/pages/menu_screen_smoke_test.dart b/test/features/menu/presentation/pages/menu_screen_smoke_test.dart index cc1cc135..1facf0bb 100644 --- a/test/features/menu/presentation/pages/menu_screen_smoke_test.dart +++ b/test/features/menu/presentation/pages/menu_screen_smoke_test.dart @@ -141,11 +141,12 @@ void main() { final cubit = MenuCubit(repository); when(repository.getPassKey(routeName: anyNamed('routeName'), routeParams: anyNamed('routeParams'))).thenAnswer((_) async => 'test-passkey'); + when(repository.getMyProfile()).thenAnswer((_) async => mockUserProfile); sl.registerLazySingleton(() => repository); sl.registerLazySingleton(() => cubit); - await tester.pumpWidget(wrap(const MenuScreen(profileModel: mockUserProfile))); + await tester.pumpWidget(wrap(const MenuScreen())); await tester.pumpAndSettle(); expect(find.text('Меню'), findsOneWidget); @@ -157,11 +158,12 @@ void main() { final cubit = MenuCubit(repository); when(repository.getPassKey(routeName: anyNamed('routeName'), routeParams: anyNamed('routeParams'))).thenAnswer((_) async => 'test-passkey'); + when(repository.getMyProfile()).thenAnswer((_) async => mockConsultantProfile); sl.registerLazySingleton(() => repository); sl.registerLazySingleton(() => cubit); - await tester.pumpWidget(wrap(const MenuScreen(profileModel: mockConsultantProfile))); + await tester.pumpWidget(wrap(const MenuScreen())); await tester.pumpAndSettle(); expect(find.text('Меню'), findsOneWidget);