From 40b35df998ac0f7ccff9b66a0382aea9a19437c2 Mon Sep 17 00:00:00 2001 From: Shaik Azad <120930148+Azad99-9@users.noreply.github.com> Date: Mon, 18 Dec 2023 01:00:21 +0530 Subject: [PATCH] Refactor Talawa URL to Hamburger menu. (#2227) * fetchmore bug fix in organizationlist widget * fetchmore result typecast * Refactor talawa conneciton url to hamburger menu * minor changes * minor fixes * minor fixes * minor fixes * added comments to the files mentioned in the failing test case. * added comments * minor fixes * ran build runner * fixed fail test * Bug fix: Edited tag does not get updated immediately (#2224) * Fixing bug to join or switch to any joined org (#2216) * Fixing bug to join or switch to any joined org * fixing linting errors * fixing * fixing coverage * fixing overflow error * fixing overflow error * Fixes Snackbar clipping by adding an auto scroll and duration based on length of message (#2231) * fix: Snackbar clipping by adding an auto scroll based on length of message * changes to tests and added documentation * minor changes to documentation * Navigation Services Test Written (#2230) * Navigation Services Test Written * Null Check Error Fixed * Update pull_request_template.md * Revert "Navigation Services Test Written (#2230)" (#2234) This reverts commit 23c2a74759112fb5fc130998837ad138de530367. * Refactor talawa conneciton url to hamburger menu * Bug fix: Edited tag does not get updated immediately (#2224) * Refactor talawa conneciton url to hamburger menu * Bug fix: Edited tag does not get updated immediately (#2224) * add some tests * added some tests * added tests to userConfig Service * fixed failing tests * fixed failing tests * added tests for explore_events_demo page * added comments for event_card widget * made add_post_page 100% code covered. * Refactor talawa conneciton url to hamburger menu * Navigation Services Test Written (#2230) * Navigation Services Test Written * Null Check Error Fixed * add tests to mainscreenviewModel * resolve conflicts * fixed failing test * added tests to apptour file --------- Co-authored-by: Bhav Khurana <96694482+bhav-khurana@users.noreply.github.com> Co-authored-by: Parag Gupta <103507835+Dante291@users.noreply.github.com> Co-authored-by: Hemanth Krishnakumar <72601105+Wreck-X@users.noreply.github.com> Co-authored-by: Manik Mehta Co-authored-by: Peter Harrison <16875803+palisadoes@users.noreply.github.com> --- lang/de.json | 4 +- lang/en.json | 4 +- lang/es.json | 4 +- lang/fr.json | 4 +- lang/hi.json | 4 +- lang/ja.json | 4 +- lang/pt.json | 8 +- lang/zh.json | 4 +- lib/constants/routing_constants.dart | 9 + lib/models/app_tour.dart | 187 +++++ lib/models/mainscreen_navigation_args.dart | 41 +- lib/router.dart | 28 +- lib/services/navigation_service.dart | 1 + lib/services/user_config.dart | 144 +++- lib/splash_screen.dart | 2 +- .../add_post_view_model.dart | 15 +- .../explore_events_view_model.dart | 225 +++--- .../organization_feed_view_model.dart | 1 - .../profile_page_view_model.dart | 81 +- lib/view_model/lang_view_model.dart | 78 +- lib/view_model/main_screen_view_model.dart | 603 ++++++++------- .../select_organization_view_model.dart | 9 +- .../custom_drawer_view_model.dart | 56 +- .../after_auth_screens/add_post_page.dart | 276 +++---- .../app_settings/app_settings_page.dart | 8 +- .../events/create_event_page.dart | 13 +- .../events/event_calendar.dart | 1 + .../feed/organization_feed.dart | 6 +- .../profile/profile_page.dart | 16 +- .../demo_screens/explore_events_demo.dart | 266 +++++++ .../demo_screens/organization_feed_demo.dart | 136 ++++ lib/views/demo_screens/profile_page_demo.dart | 237 ++++++ lib/views/main_screen.dart | 65 +- .../pre_auth_screens/select_language.dart | 6 +- lib/views/pre_auth_screens/set_url.dart | 3 +- lib/widgets/custom_alert_dialog.dart | 36 +- lib/widgets/custom_drawer.dart | 37 +- lib/widgets/event_card.dart | 25 +- lib/widgets/pinned_post.dart | 7 +- lib/widgets/talawa_error_dialog.dart | 9 +- pubspec.lock | 2 +- test/helpers/test_helpers.dart | 44 +- test/helpers/test_helpers.mocks.dart | 727 +++++++++++++----- test/model_tests/app_tour_test.dart | 170 ++++ .../mainscreen_navigation_args_test.dart | 33 + test/router_test.dart | 51 ++ .../navigation_service_test.dart | 36 +- test/service_tests/user_config_test.dart | 174 +++++ test/utils/app_localization_test.dart | 2 +- .../profile_page_view_model_test.dart | 120 ++- .../lang_view_model_test.dart | 38 +- .../main_screen_view_model_test.dart | 627 ++++++++++++--- .../select_organization_view_model_test.dart | 16 +- .../events/create_event_page_test.dart | 19 + .../profile/profile_page_test.dart | 82 ++ .../explore_events_demo_test.dart | 226 ++++++ .../organization_feed_demo_test.dart | 64 ++ .../demo_screens/profile_page_demo_test.dart | 77 ++ test/views/main_screen_test.dart | 49 +- .../add_post_page_test.dart | 54 +- .../app_settings/app_setting_page_test.dart | 12 + .../feed/organization_feed_test.dart | 139 ++-- .../select_language_page_test.dart | 8 +- .../widgets/custom_drawer_test.dart | 191 ++++- .../widgets/pinned_post_test.dart | 48 +- 65 files changed, 4532 insertions(+), 1140 deletions(-) create mode 100644 lib/models/app_tour.dart create mode 100644 lib/views/demo_screens/explore_events_demo.dart create mode 100644 lib/views/demo_screens/organization_feed_demo.dart create mode 100644 lib/views/demo_screens/profile_page_demo.dart create mode 100644 test/model_tests/app_tour_test.dart create mode 100644 test/model_tests/mainscreen_navigation_args_test.dart create mode 100644 test/service_tests/user_config_test.dart create mode 100644 test/views/after_auth_screens/profile/profile_page_test.dart create mode 100644 test/views/demo_screens/explore_events_demo_test.dart create mode 100644 test/views/demo_screens/organization_feed_demo_test.dart create mode 100644 test/views/demo_screens/profile_page_demo_test.dart diff --git a/lang/de.json b/lang/de.json index c2b431df4..7ff5a6eea 100644 --- a/lang/de.json +++ b/lang/de.json @@ -21,7 +21,7 @@ "Select": "Auswählen", "Selected Organization": "Ausgewählte Organisation", "Continue": "Weitermachen", - "Enter Organization URL": "Organisations-URL eingeben", + "Enter Community URL": "Geben Sie die Community-URL ein", "Verify": "Verifizieren", "Sign Up": "Anmeldung", "Change language": "Sprache ändern", @@ -160,5 +160,7 @@ "Dismiss": "afwijzen", "No organizations found Please contact your admin": "Geen organisaties gevonden! Neem contact op met uw beheerder", "Notification Feature is not installed": "Meddelelsesfunktionen er ikke installeret", + "For complete access, please": "Für vollständigen Zugriff bitte", + " join an organization.": " einer Organisation beitreten.", "JOIN":"BEITRETEN" } diff --git a/lang/en.json b/lang/en.json index 8b5eb16ec..bed1b4a65 100644 --- a/lang/en.json +++ b/lang/en.json @@ -23,7 +23,7 @@ "Select": "Select", "Selected Organization": "Selected Organization", "Continue": "Continue", - "Enter Organization URL": "Enter Organization URL", + "Enter Community URL": "Enter Community URL", "Verify": "Verify", "Sign Up": "Sign Up", "Change language": "Change language", @@ -166,5 +166,7 @@ "Settings": "Settings", "Dark Theme": "Dark Theme", "No organizations found Please contact your admin": "No organizations found ! Please contact your admin", + "For complete access, please": "For complete access, please", + " join an organization.": " join an organization.", "JOIN":"JOIN" } diff --git a/lang/es.json b/lang/es.json index 986d7062f..5a8ffb18a 100644 --- a/lang/es.json +++ b/lang/es.json @@ -24,7 +24,7 @@ "Select": "Seleccione", "Selected Organization": "Organización seleccionada", "Continue": "Continuar", - "Enter Organization URL": "Ingrese la URL de la organización", + "Enter Community URL": "Ingrese la URL de la comunidad", "Verify": "Verificarlo", "Sign Up": "Inscribirse", "Change language": "Cambiar idioma", @@ -161,5 +161,7 @@ "No account registered with this email": "El servidor no se está ejecutando/url", "Dismiss": "despedir", "No organizations found Please contact your admin": "Neniuj organizoj trovitaj! Bonvolu kontakti vian administranton", + "For complete access, please": "Para acceso completo, por favor", + " join an organization.": " unirse a una organización.", "JOIN":"UNIRSE" } diff --git a/lang/fr.json b/lang/fr.json index 393532fe4..5070b7deb 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -24,7 +24,7 @@ "Select": "Sélectionner", "Selected Organization": "Organisation sélectionnée", "Continue": "Continuer", - "Enter Organization URL": "Saisissez l'URL de l'organisation", + "Enter Community URL": "Entrez l'URL de la communauté", "Verify": "Vérifier", "Sign Up": "S'inscrire", "Change language": "Changer de langue", @@ -163,5 +163,7 @@ "Settings": "Paramètres", "Dark Theme": "Thème sombre", "No organizations found Please contact your admin": "Aucune organisation trouvée ! Veuillez contacter votre administrateur", + "For complete access, please": "Pour un accès complet, veuillez", + " join an organization.": " rejoindre une organisation.", "JOIN":"REJOINDRE" } diff --git a/lang/hi.json b/lang/hi.json index 737a2b63f..db3328742 100644 --- a/lang/hi.json +++ b/lang/hi.json @@ -22,7 +22,7 @@ "Notification Feature is not installed": "अधिसूचना सुविधा स्थापित नहीं है", "Selected Organization": "चयनित संगठन", "Continue": "जारी रखें", - "Enter Organization URL": "संगठन URL दर्ज करें", + "Enter Community URL": "समुदाय URL दर्ज करें", "Verify": "सत्यापित करें", "Sign Up": "साइन अप करें", "Change language": "भाषा बदलें", @@ -159,5 +159,7 @@ "No account registered with this email": "सर्वर नहीं चल रहा/गलत url", "Dismiss": "नकार", "No organizations found Please contact your admin": "कोई संगठन नहीं मिला! कृपया अपने व्यवस्थापक से संपर्क करें", + "For complete access, please": "पूर्ण पहुंच के लिए, कृपया", + " join an organization.": " किसी संगठन से जुड़ें.", "JOIN":"जोड़ना" } diff --git a/lang/ja.json b/lang/ja.json index 3e21432b1..cf17112a0 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -23,7 +23,7 @@ "Select": "選択する", "Selected Organization": "選択した組織", "Continue": "継続する", - "Enter Organization URL": "組織のURLを入力してください", + "Enter Community URL": "コミュニティの URL を入力してください", "Verify": "確認", "Sign Up": "サインアップ", "Change language": "言語を変更", @@ -162,5 +162,7 @@ "No account registered with this email": "サーバーが実行されていない/間違った URL", "Dismiss": "解散", "No organizations found Please contact your admin": "組織が見つかりません!管理者に連絡してください", + "For complete access, please": "完全にアクセスするには、", + " join an organization.": " 組織に参加します。", "JOIN": "参加する" } diff --git a/lang/pt.json b/lang/pt.json index 34fa2e2b0..6948f0e91 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -24,7 +24,7 @@ "Select": "Selecione", "Selected Organization": "Organização Selecionada", "Continue": "Prosseguir", - "Enter Organization URL": "Insira o URL da organização", + "Enter Community URL": "Insira o URL da sua comunidade", "Verify": "Verificar", "Sign Up": "Inscrever-se", "Change language": "Mudar idioma", @@ -160,6 +160,8 @@ "Information": "Informação", "No account registered with this email": "Servidor não está em execução/url errado", "Dismiss": "liberar", - "JOIN":"ENTRAR", - "No organizations found Please contact your admin": "Neniuj organizoj trovitaj! Bonvolu kontakti vian administranton" + "No organizations found Please contact your admin": "Neniuj organizoj trovitaj! Bonvolu kontakti vian administranton", + "For complete access, please": "Para acesso completo, por favor", + " join an organization.": " ingressar em uma organização.", + "JOIN":"ENTRAR" } diff --git a/lang/zh.json b/lang/zh.json index 46d1769ea..8d96d4789 100644 --- a/lang/zh.json +++ b/lang/zh.json @@ -23,7 +23,7 @@ "Select": "选择", "Selected Organization": "选定组织", "Continue": "继续", - "Enter Organization URL": "输入组织 URL", + "Enter Community URL": "输入您的社区网址", "Verify": "验证一下", "Sign Up": "报名", "Change language": "改变语言", @@ -160,5 +160,7 @@ "No account registered with this email": "服务器未运行/网址错误", "Dismiss": "解雇", "No organizations found Please contact your admin": "Neniuj organizoj trovitaj! Bonvolu kontakti vian administranton", + "For complete access, please": "如需完整访问,请", + " join an organization.": " 加入一个组织。", "JOIN":"加入" } diff --git a/lib/constants/routing_constants.dart b/lib/constants/routing_constants.dart index 26e2c28b5..a462a6d37 100644 --- a/lib/constants/routing_constants.dart +++ b/lib/constants/routing_constants.dart @@ -34,6 +34,9 @@ class Routes { /// static variables. static const String homeScreen = "/homeScreen"; + /// static variables. + static const String demoHomeScreen = "/demoHomeScreen"; + /// static variables. static const String mainScreen = "/mainScreen"; @@ -49,6 +52,9 @@ class Routes { /// static variables. static const String exploreEventsScreen = "/exploreEvents"; + /// static variables. + static const String demoExploreEventsScreen = "/demoExploreEvents"; + /// static variables. static const String eventInfoPage = "/eventInfo"; @@ -58,6 +64,9 @@ class Routes { /// static variables. static const String profilePage = "/profilePage"; + /// static variables. + static const String demoProfilePage = "/demoProfilePage"; + /// static variables. static const String editProfilePage = "/editProfilePage"; diff --git a/lib/models/app_tour.dart b/lib/models/app_tour.dart new file mode 100644 index 000000000..a956c805d --- /dev/null +++ b/lib/models/app_tour.dart @@ -0,0 +1,187 @@ +import 'package:flutter/material.dart'; +import 'package:talawa/locator.dart'; +import 'package:talawa/services/size_config.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; + +/// Class that handles all the apptour routines. +class AppTour { + AppTour({ + required this.model, + }); + + ///instance of mainscreenviewmodel. + MainScreenViewModel model; + + ///instance of tutorialCoachMark. + late TutorialCoachMark tutorialCoachMark; + + /// This function show tutorial to user. + /// + /// **params**: + /// * `onClickTarget`: Its a function which is required to run desired tasks on click. + /// * `onFinish`: Its a function which is required to run desired tasks on finish + /// + /// + /// **returns**: + /// None + + void showTutorial({ + required Function(TargetFocus) onClickTarget, + required dynamic Function() onFinish, + required List targets, + }) { + tutorialCoachMark = TutorialCoachMark( + targets: targets.map((target) => target.focusWidget).toList(), + colorShadow: Theme.of(model.context).colorScheme.secondaryContainer, + textSkip: "SKIP", + textStyleSkip: TextStyle( + color: Theme.of(model.context).colorScheme.background, + fontSize: 20, + ), + paddingFocus: 10, + opacityShadow: 1.0, + onFinish: onFinish, + onClickTarget: onClickTarget, + onSkip: () { + if (MainScreenViewModel.scaffoldKey.currentState!.isDrawerOpen) { + navigationService.pop(); + } + model.tourSkipped = true; + model.onTabTapped(0); + return true; + }, + onClickOverlay: (target) { + onClickTarget(target); + }, + ); + if (!model.testMode) tutorialCoachMark.show(context: model.context); + } +} + +/// Class that represents FocusTarget. +class FocusTarget { + /// This returns a widget for a step in a tutorial. + /// + /// **params**: + /// * `key`: key of type GlobalKey. + /// * `keyName`: key where the widget shows. + /// * `description`: description of the step. + /// * `isCircle`: bool to specify if circle + /// * `align`: align of type ContentAlign to align button. + /// * `crossAlign`: Cross align axes + /// * `skipAlignment`: to give alignment of skip option + /// * `next`: Function` type, this show the next step or `key` to show the tour of. + /// * `nextCrossAlign`: nextCrossAlign to give alignment of next option + /// * `isEnd`: true if last step of the tour. + /// * `tutorialCoachMark`: instance of tutorialCoachMark to which this focusTarget is linked. + FocusTarget({ + required this.key, + required this.keyName, + required this.description, + required this.appTour, + this.isCircle = false, + this.align = ContentAlign.bottom, + this.crossAlign = CrossAxisAlignment.start, + this.skipAlignment = Alignment.topRight, + this.next, + this.nextCrossAlign = CrossAxisAlignment.end, + this.isEnd = false, + }) { + this.focusWidget = TargetFocus( + enableOverlayTab: true, + color: Colors.transparent, + identify: keyName, + keyTarget: key, + alignSkip: skipAlignment, + shape: isCircle ? ShapeLightFocus.Circle : ShapeLightFocus.RRect, + contents: [ + TargetContent( + align: align, + builder: (context, controller) { + return Container( + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: crossAlign, + children: [ + Text( + description, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontSize: 20, + ), + ), + ], + ), + ); + }, + ), + TargetContent( + align: ContentAlign.custom, + customPosition: CustomTargetContentPosition( + bottom: SizeConfig.screenHeight! * 0.025, + ), + builder: (context, controller) { + return GestureDetector( + onTap: () { + // ignore: avoid_dynamic_calls + next?.call(); + + appTour.tutorialCoachMark.next(); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: nextCrossAlign, + children: [ + Text( + isEnd ? 'COMPLETE' : 'NEXT', + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontSize: 20, + ), + ), + ], + ), + ); + }, + ), + ], + ); + } + + /// represents the key of the target that is intended to be focused. + GlobalKey key; + + /// keyName of the target in mainScreenViewModel. + String keyName; + + /// description of the target. + String description; + + /// true if focusing shape is circle. + bool isCircle; + + /// alignment of description text. + ContentAlign align; + + /// crossAxisAlignment. + CrossAxisAlignment crossAlign; + + /// skip alignment configuration. + Alignment skipAlignment; + + /// instance of AppTour. + AppTour appTour; + + /// next callback that is executed on pressing this target. + Function? next; + + /// next target's crossAxisAlignment. + CrossAxisAlignment nextCrossAlign; + + /// true current target ends ths appTour. + bool isEnd; + + /// Target focus widget with all above properties. + late TargetFocus focusWidget; +} diff --git a/lib/models/mainscreen_navigation_args.dart b/lib/models/mainscreen_navigation_args.dart index 436ae3054..a23caaff2 100644 --- a/lib/models/mainscreen_navigation_args.dart +++ b/lib/models/mainscreen_navigation_args.dart @@ -1,9 +1,42 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - +/// This class creates a MainScreenArgs model. class MainScreenArgs { - MainScreenArgs({this.fromSignUp = false, required this.mainScreenIndex}); + MainScreenArgs({ + this.fromSignUp = false, + required this.mainScreenIndex, + this.toggleDemoMode = false, + }); + /// Indicates whether the user navigated to the main screen from the signup page. final bool fromSignUp; + + /// Represents the index of the current page. final int mainScreenIndex; + + /// Determines if the application is in demo mode. + final bool toggleDemoMode; + + /// Overrides the equality operator to compare instances of the MainScreenArgs class. + /// + /// Checks whether the [other] object is of the same type and compares its properties: + /// If all properties match, returns `true`; otherwise, returns `false`. + /// + /// **params**: + /// * `other`: The object to compare against this MainScreenArgs instance. + /// + /// **returns**: + /// * `bool`: Returns `true` if the properties of both instances match; otherwise, `false`. + @override + bool operator ==(Object other) => + identical(this, other) || + other is MainScreenArgs && + other.fromSignUp == fromSignUp && + other.mainScreenIndex == mainScreenIndex && + other.toggleDemoMode == toggleDemoMode; + + /// Overrides the hashCode getter to generate a hash code based on the properties of the MainScreenArgs instance. + /// + /// Returns an integer value representing the combined hash codes. + @override + int get hashCode => + fromSignUp.hashCode ^ mainScreenIndex.hashCode ^ toggleDemoMode.hashCode; } diff --git a/lib/router.dart b/lib/router.dart index 4b348a890..86fd7f8a1 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -32,6 +32,9 @@ import 'package:talawa/views/after_auth_screens/tasks/edit_task_page.dart'; import 'package:talawa/views/after_auth_screens/tasks/event_tasks_page.dart'; import 'package:talawa/views/after_auth_screens/tasks/user_tasks_page.dart'; import 'package:talawa/views/after_auth_screens/venue/map_screen.dart'; +import 'package:talawa/views/demo_screens/explore_events_demo.dart'; +import 'package:talawa/views/demo_screens/organization_feed_demo.dart'; +import 'package:talawa/views/demo_screens/profile_page_demo.dart'; import 'package:talawa/views/main_screen.dart'; import 'package:talawa/views/pre_auth_screens/change_password.dart'; import 'package:talawa/views/pre_auth_screens/login.dart'; @@ -134,6 +137,13 @@ Route generateRoute(RouteSettings settings) { builder: (context) => const OrganizationFeed(key: Key('HomeScreen')), ); + // Returns the DemoOrganizationFeed Widget + case Routes.demoHomeScreen: + return MaterialPageRoute( + builder: (context) => + const DemoOrganizationFeed(key: Key('DemoHomeScreen')), + ); + // Returns the MainScreen Widget case Routes.mainScreen: final MainScreenArgs mainScreenArgs = @@ -169,6 +179,13 @@ Route generateRoute(RouteSettings settings) { builder: (context) => const ExploreEvents(key: Key('ExploreEvents')), ); + // Returns the DemoExploreEvents Widget + case Routes.demoExploreEventsScreen: + return MaterialPageRoute( + builder: (context) => + const DemoExploreEvents(key: Key('DemoExploreEvents')), + ); + // Returns the EventInfoPage Widget case Routes.eventInfoPage: final Map args = @@ -192,6 +209,12 @@ Route generateRoute(RouteSettings settings) { builder: (context) => const ProfilePage(key: Key('Profile')), ); + // Return the DemoProfilePage Widget + case Routes.demoProfilePage: + return MaterialPageRoute( + builder: (context) => const DemoProfilePage(key: Key('DemoProfile')), + ); + // Returns the EditProfilePage Widget case Routes.editProfilePage: return MaterialPageRoute( @@ -307,13 +330,14 @@ Route generateRoute(RouteSettings settings) { return MaterialPageRoute( builder: (context) => const SelectContact(key: Key('selectContact')), ); + case Routes.addPostScreen: return MaterialPageRoute( builder: (context) => const AddPost( - key: Key('addPostScreen'), + key: Key('AddPostPage'), ), ); - // Returns the DemoPageView Widget by default + default: return MaterialPageRoute( builder: (context) => const DemoPageView( diff --git a/lib/services/navigation_service.dart b/lib/services/navigation_service.dart index 750f42359..ae9260dba 100644 --- a/lib/services/navigation_service.dart +++ b/lib/services/navigation_service.dart @@ -94,6 +94,7 @@ class NavigationService { /// **returns**: /// None void pushDialog(Widget dialog) { + print('came'); showDialog( context: navigatorKey.currentContext!, barrierColor: Colors.transparent, diff --git a/lib/services/user_config.dart b/lib/services/user_config.dart index e352c5af5..73fcfa739 100644 --- a/lib/services/user_config.dart +++ b/lib/services/user_config.dart @@ -1,5 +1,4 @@ // ignore_for_file: talawa_api_doc, avoid_dynamic_calls -// ignore_for_file: talawa_good_doc_comments import 'dart:async'; @@ -10,6 +9,7 @@ import 'package:talawa/enums/enums.dart'; import 'package:talawa/locator.dart'; import 'package:talawa/models/organization/org_info.dart'; import 'package:talawa/models/user/user_info.dart'; +import 'package:talawa/widgets/custom_progress_dialog.dart'; /// UserConfig class provides different services in the context of the User. /// @@ -29,24 +29,52 @@ class UserConfig { final StreamController _currentOrgInfoController = StreamController.broadcast(); + /// Getter method to retrieve the stream of current organization information. Stream get currentOrgInfoStream => _currentOrgInfoStream; + + /// Getter method to retrieve the stream controller for current organization information. StreamController get currentOrgInfoController => _currentOrgInfoController; + /// Getter method to retrieve the current organization information. OrgInfo get currentOrg => _currentOrg!; + + /// Getter method to retrieve the name of the current organization. String get currentOrgName => _currentOrg!.name!; + + /// Getter method to check if a user is logged in. + bool get loggedIn => _currentUser?.id != 'null'; + + /// Setter method to update the current organization information. set currentOrg(OrgInfo org) => _currentOrg = org; + + /// Getter method to retrieve the current user. User get currentUser => _currentUser!; + + /// Setter method to update the current user. set currentUser(User user) { _currentUser = user; } + /// initialise. + /// + /// **params**: + /// None + /// + /// **returns**: + /// None void initialiseStream() { _currentOrgInfoStream = _currentOrgInfoController.stream.asBroadcastStream(); } /// This function is used to log in the user. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: returns future of bool type. Future userLoggedIn() async { initialiseStream(); final boxUser = Hive.box('currentUser'); @@ -92,48 +120,107 @@ class UserConfig { return true; } + /// This function logs out the current user. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: returns future of bool type. + Future userLogOut() async { + try { + final result = await databaseFunctions.gqlAuthMutation(queries.logout()) + as QueryResult?; + if (result != null && result.data!['logout'] == true) { + navigationService.pop(); + navigationService.pushDialog( + const CustomProgressDialog( + key: Key('LogoutProgress'), + ), + ); + // throw StateError('error'); + + final user = Hive.box('currentUser'); + final url = Hive.box('url'); + // final androidFirebaseOptionsBox = Hive.box('androidFirebaseOptions'); + // final iosFirebaseOptionsBox = Hive.box('iosFirebaseOptions'); + final organisation = Hive.box('currentOrg'); + await user.clear(); + await url.clear(); + // androidFirebaseOptionsBox.clear(); + // iosFirebaseOptionsBox.clear(); + // try { + // Firebase.app() + // .delete(); // Deleting app will stop all Firebase plugins + // } catch (e) { + // debugPrint("ERROR: Unable to delete firebase app $e"); + // } + await organisation.clear(); + _currentUser = User(id: 'null', authToken: 'null'); + } + } catch (e) { + return false; + } + return true; + } + /// This function is used to update the user joined organization. /// - /// params: - /// * [orgDetails] : details of the organization that user joined. - Future updateUserJoinedOrg(List orgDetails) async { + /// **params**: + /// * `orgDetails`: details of the organization that user joined. + /// + /// **returns**: + /// * `Future`: returns future of void type. + Future updateUserJoinedOrg(List orgDetails) async { _currentUser!.updateJoinedOrg(orgDetails); saveUserInHive(); } /// This function is used to update the user created organization. /// - /// params: - /// * [orgDetails] : details of the organization that user created. - Future updateUserCreatedOrg(List orgDetails) async { + /// **params**: + /// * `orgDetails`: details of the organization that user joined. + /// + /// **returns**: + /// * `Future`: returns future of void type. + Future updateUserCreatedOrg(List orgDetails) async { _currentUser!.updateCreatedOrg(orgDetails); saveUserInHive(); } /// This function is used to update the user request to join the organization. /// - /// params: - /// * [orgDetails] : details of the organization that user requested to join. - Future updateUserMemberRequestOrg(List orgDetails) async { + /// **params**: + /// * `orgDetails`: details of the organization that user joined. + /// + /// **returns**: + /// * `Future`: returns future of void type. + Future updateUserMemberRequestOrg(List orgDetails) async { _currentUser!.updateMemberRequestOrg(orgDetails); saveUserInHive(); } /// This function is used to update the organization admin. /// - /// params: - /// * [orgDetails] : details of the organization. - Future updateUserAdminOrg(List orgDetails) async { + /// **params**: + /// * `orgDetails`: details of the organization that user joined. + /// + /// **returns**: + /// * `Future`: returns future of void type. + Future updateUserAdminOrg(List orgDetails) async { _currentUser!.updateAdminFor(orgDetails); saveUserInHive(); } /// This function is used to updated the access token of the user. /// - /// params: - /// * [accessToken] - /// * [refreshToken] - Future updateAccessToken({ + /// **params**: + /// * `accessToken`: current user's accesstoken. + /// * `refreshToken`: current user's refreshtoken. + /// + /// **returns**: + /// * `Future`: returns future of void type. + Future updateAccessToken({ required String accessToken, required String refreshToken, }) async { @@ -144,8 +231,11 @@ class UserConfig { /// This function is used to update the user details. /// - /// params: - /// * [updatedUserDetails] : `User` type variable containing all the details of an user need to be updated. + /// **params**: + /// * `updatedUserDetails`: `User` type variable containing all the details of an user need to be updated. + /// + /// **returns**: + /// * `Future`: returns future of bool type. Future updateUser(User updatedUserDetails) async { try { _currentUser = updatedUserDetails; @@ -159,7 +249,13 @@ class UserConfig { } } - // save user in hive. + /// save user in hive. + /// + /// **params**: + /// None + /// + /// **returns**: + /// None void saveUserInHive() { final box = Hive.box('currentUser'); if (box.get('user') == null) { @@ -169,7 +265,13 @@ class UserConfig { } } - // save current organization details in hive. + /// save current organization details in hive. + /// + /// **params**: + /// * `saveOrgAsCurrent`: instance of OrgInfo + /// + /// **returns**: + /// None void saveCurrentOrgInHive(OrgInfo saveOrgAsCurrent) { _currentOrg = saveOrgAsCurrent; _currentOrgInfoController.add(_currentOrg!); diff --git a/lib/splash_screen.dart b/lib/splash_screen.dart index 88d82dae1..6bb6a5eb0 100644 --- a/lib/splash_screen.dart +++ b/lib/splash_screen.dart @@ -58,7 +58,7 @@ class _SplashScreenState extends State { }, ); try { - // Retrieving the initial URI from getIntitialUri function. + // Retrieving the initial URI from getInitialUri function. final uri = await getInitialUri(); if (!mounted) return; setState(() => _initialUri = uri); diff --git a/lib/view_model/after_auth_view_models/add_post_view_models/add_post_view_model.dart b/lib/view_model/after_auth_view_models/add_post_view_models/add_post_view_model.dart index 39bae9755..0bcc7ea1a 100644 --- a/lib/view_model/after_auth_view_models/add_post_view_models/add_post_view_model.dart +++ b/lib/view_model/after_auth_view_models/add_post_view_models/add_post_view_model.dart @@ -6,7 +6,6 @@ import 'package:flutter/material.dart'; import 'package:talawa/enums/enums.dart'; import 'package:talawa/locator.dart'; import 'package:talawa/models/organization/org_info.dart'; -import 'package:talawa/models/user/user_info.dart'; import 'package:talawa/services/database_mutation_functions.dart'; import 'package:talawa/services/navigation_service.dart'; import 'package:talawa/services/third_party_service/multi_media_pick_service.dart'; @@ -18,6 +17,8 @@ import 'package:talawa/view_model/base_view_model.dart'; /// /// to interact with the model to add a new post in the organization. class AddPostViewModel extends BaseModel { + AddPostViewModel({this.demoMode = false}); + //Services late MultiMediaPickerService _multiMediaPickerService; late NavigationService _navigationService; @@ -25,11 +26,11 @@ class AddPostViewModel extends BaseModel { // ignore: unused_field late File? _imageFile; late String? _imageInBase64; - late User _currentUser; late OrgInfo _selectedOrg; final TextEditingController _controller = TextEditingController(); final TextEditingController _textHashTagController = TextEditingController(); final TextEditingController _titleController = TextEditingController(); + late bool demoMode; /// The image file that is to be uploaded. /// @@ -74,7 +75,8 @@ class AddPostViewModel extends BaseModel { /// None /// returns: /// * `String`: The username of the currentUser - String get userName => _currentUser.firstName! + _currentUser.lastName!; + String get userName => + userConfig.currentUser.firstName! + userConfig.currentUser.lastName!; /// The organisation name. /// @@ -117,12 +119,13 @@ class AddPostViewModel extends BaseModel { /// **returns**: /// None void initialise() { - _currentUser = locator().currentUser; _navigationService = locator(); - _selectedOrg = locator().currentOrg; _imageFile = null; _multiMediaPickerService = locator(); - _dbFunctions = locator(); + if (!demoMode) { + _dbFunctions = locator(); + _selectedOrg = locator().currentOrg; + } } /// to convert the image in base64. diff --git a/lib/view_model/after_auth_view_models/event_view_models/explore_events_view_model.dart b/lib/view_model/after_auth_view_models/event_view_models/explore_events_view_model.dart index 3d4f1213f..4777b0d8d 100644 --- a/lib/view_model/after_auth_view_models/event_view_models/explore_events_view_model.dart +++ b/lib/view_model/after_auth_view_models/event_view_models/explore_events_view_model.dart @@ -1,6 +1,3 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - import 'dart:async'; import 'package:intl/intl.dart'; @@ -20,6 +17,11 @@ import 'package:talawa/widgets/custom_alert_dialog.dart'; /// * `deleteEvent` : to delete the event. /// * `choseValueFromDropdown` : to return the relevant message in the dropdown after any action. class ExploreEventsViewModel extends BaseModel { + ExploreEventsViewModel({this.demoMode = false}); + + /// flag to check if the app is in demo mode. + bool demoMode; + final _eventService = locator(); late StreamSubscription _eventStreamSubscription; @@ -29,14 +31,28 @@ class ExploreEventsViewModel extends BaseModel { final Set _uniqueEventIds = {}; late StreamSubscription _currentOrganizationStreamSubscription; late final List _bufferEvents; + + /// Getter method to retrieve the list of events. List get events => _events; + + /// Getter method to retrieve the EventService instance. EventService get eventService => _eventService; + + /// Getter method to retrieve the empty list message. String get emptyListMessage => _emptyListMessage; + /// Getter method to retrieve the chosen value. String get chosenValue => _chosenValue; /// This function is used to fetch new events in the organization. + /// /// The function uses `getEvents` method from `EventService`. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: return future void. Future fetchNewEvents() async { setState(ViewState.busy); notifyListeners(); @@ -45,7 +61,14 @@ class ExploreEventsViewModel extends BaseModel { } /// This function is used to refresh the events in the organization. + /// /// The function uses `getEvents` method from `EventService`. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: return future void. Future refreshEvents() async { setState(ViewState.busy); _events.clear(); @@ -54,24 +77,36 @@ class ExploreEventsViewModel extends BaseModel { setState(ViewState.idle); } - // initialiser + /// initialiser. + /// + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: return future void. Future initialise() async { setState(ViewState.busy); - _currentOrganizationStreamSubscription = userConfig.currentOrgInfoStream - .listen((updatedOrganization) => refreshEvents()); - await _eventService.getEvents(); + if (!demoMode) { + _currentOrganizationStreamSubscription = userConfig.currentOrgInfoStream + .listen((updatedOrganization) => refreshEvents()); + await _eventService.getEvents(); - _eventStreamSubscription = _eventService.eventStream.listen( - (newEvent) => checkIfExistsAndAddNewEvent(newEvent), - ); - _bufferEvents = _events; + _eventStreamSubscription = _eventService.eventStream.listen( + (newEvent) => checkIfExistsAndAddNewEvent(newEvent), + ); + _bufferEvents = _events; + } setState(ViewState.idle); } /// This function add a new event if the event not exist. /// - /// params: - /// * [newEvent] : `Event` type variable containing data to create a new event. + /// **params**: + /// * `newEvent`: `Event` type variable containing data to create a new event. + /// + /// **returns**: + /// * `Future`: return future void. Future checkIfExistsAndAddNewEvent(Event newEvent) async { // checking if the `newEvent.id` is unique and not exist already. if ((!_uniqueEventIds.contains(newEvent.id)) && @@ -83,6 +118,12 @@ class ExploreEventsViewModel extends BaseModel { } /// The helper function that used to parse the date and time. + /// + /// **params**: + /// * `newEvent`: `Event` type variable containing data to create a new event. + /// + /// **returns**: + /// None void _parseEventDateTime(Event newEvent) { // Maybe needed for the tests. Can be further discussed. if (newEvent.startDate == null || @@ -113,8 +154,11 @@ class ExploreEventsViewModel extends BaseModel { /// This function deletes the event. /// - /// params: - /// * [eventId] : id of the event that need to be delete. + /// **params**: + /// * `eventId`: id of the event that need to be delete. + /// + /// **returns**: + /// * `Future`: return future void. Future deleteEvent({required String eventId}) async { // push the custom alert dialog to ask for confirmation. navigationService.pushDialog( @@ -142,85 +186,90 @@ class ExploreEventsViewModel extends BaseModel { ); } - /// This function takes the choosen value from dropdown and - /// return the filter events, if empty list then return relevant message. + /// This function takes the choosen value from dropdown and return the filter events, if empty list then return relevant message. + /// + /// **params**: + /// * `value`: choosen value from dropdown. /// - /// params: - /// * [value] : choosen value from dropdown. + /// + /// **returns**: + /// * `Future`: return future void. Future choseValueFromDropdown(String value) async { _chosenValue = value; notifyListeners(); setState(ViewState.busy); - switch (_chosenValue) { - // if `_chosenValue` is "All events". - case 'All Events': - { - // all events - _events = _bufferEvents; - // if list is empty - _emptyListMessage = "Looks like there aren't any events."; - } - break; - // if `_chosenValue` is "created event". - case 'Created Events': - { - // loop through the `_events` list and check - // for the creator id matched the current user id. - _events = List.from( - _bufferEvents.where( - (element) => element.creator!.id == userConfig.currentUser.id, - ), - ); - // if list is empty - _emptyListMessage = "You have not created any event."; - } - break; - // if `_chosenValue` is "Registered Events". - case 'Registered Events': - { - // loop through the `_events` list and filter elements - // if `element.isRegistered` is true and user is not the creator. - _events = List.from( - _bufferEvents.where( - (element) => - element.isRegistered == true && - element.creator!.id != userConfig.currentUser.id, - ), - ); - // if list is empty - _emptyListMessage = "No registered events are present"; - } - break; - // if `_chosenValue` is "Registered Events". - case 'Public Events': - { - // loop through the `_events` list and filter elements - // with the `isPublic` as true. - _events = _bufferEvents - .where((element) => element.isPublic == true) - .toList(); - - // if list is empty - _emptyListMessage = "There aren't any public events."; - } - break; - case 'Private Events': - { - // loop through the `_events` list and filter elements - // with the `isPublic` as false. - _events = _bufferEvents - .where((element) => element.isPublic == false) - .toList(); - // if list is empty - _emptyListMessage = "There aren't any private events."; - } - break; - - default: - { - _events = _bufferEvents; - } + if (!demoMode) { + switch (_chosenValue) { + // if `_chosenValue` is "All events". + case 'All Events': + { + // all events + _events = _bufferEvents; + // if list is empty + _emptyListMessage = "Looks like there aren't any events."; + } + break; + // if `_chosenValue` is "created event". + case 'Created Events': + { + // loop through the `_events` list and check + // for the creator id matched the current user id. + _events = List.from( + _bufferEvents.where( + (element) => element.creator!.id == userConfig.currentUser.id, + ), + ); + // if list is empty + _emptyListMessage = "You have not created any event."; + } + break; + // if `_chosenValue` is "Registered Events". + case 'Registered Events': + { + // loop through the `_events` list and filter elements + // if `element.isRegistered` is true and user is not the creator. + _events = List.from( + _bufferEvents.where( + (element) => + element.isRegistered == true && + element.creator!.id != userConfig.currentUser.id, + ), + ); + // if list is empty + _emptyListMessage = "No registered events are present"; + } + break; + // if `_chosenValue` is "Registered Events". + case 'Public Events': + { + // loop through the `_events` list and filter elements + // with the `isPublic` as true. + _events = _bufferEvents + .where((element) => element.isPublic == true) + .toList(); + + // if list is empty + _emptyListMessage = "There aren't any public events."; + } + break; + case 'Private Events': + { + // loop through the `_events` list and filter elements + // with the `isPublic` as false. + _events = _bufferEvents + .where((element) => element.isPublic == false) + .toList(); + // if list is empty + _emptyListMessage = "There aren't any private events."; + } + break; + + default: + { + _events = _bufferEvents; + } + } } await Future.delayed(const Duration(milliseconds: 500)); setState(ViewState.idle); diff --git a/lib/view_model/after_auth_view_models/feed_view_models/organization_feed_view_model.dart b/lib/view_model/after_auth_view_models/feed_view_models/organization_feed_view_model.dart index 85155af8b..8949d5776 100644 --- a/lib/view_model/after_auth_view_models/feed_view_models/organization_feed_view_model.dart +++ b/lib/view_model/after_auth_view_models/feed_view_models/organization_feed_view_model.dart @@ -115,7 +115,6 @@ class OrganizationFeedViewModel extends BaseModel { bool isTest = false, }) { // For caching/initializing the current organization after the stream subscription has canceled and the stream is updated - _currentOrgName = _userConfig.currentOrg.name!; // ------ // Attaching the stream subscription to rebuild the widgets automatically diff --git a/lib/view_model/after_auth_view_models/profile_view_models/profile_page_view_model.dart b/lib/view_model/after_auth_view_models/profile_view_models/profile_page_view_model.dart index 0a1e8435f..d17dadb47 100644 --- a/lib/view_model/after_auth_view_models/profile_view_models/profile_page_view_model.dart +++ b/lib/view_model/after_auth_view_models/profile_view_models/profile_page_view_model.dart @@ -1,7 +1,5 @@ import 'package:currency_picker/currency_picker.dart'; -import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; -import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:hive/hive.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:talawa/constants/constants.dart'; @@ -18,7 +16,7 @@ import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/view_model/base_view_model.dart'; import 'package:talawa/view_model/lang_view_model.dart'; import 'package:talawa/widgets/custom_alert_dialog.dart'; -import 'package:talawa/widgets/custom_progress_dialog.dart'; +import 'package:talawa/widgets/talawa_error_dialog.dart'; /// ProfilePageViewModel class helps to interact with model to serve data and react to user's input in Profile Page view. /// @@ -89,55 +87,7 @@ class ProfilePageViewModel extends BaseModel { /// * `Future`: Resolves when user logout Future logout(BuildContext context) async { // push custom alert dialog with the confirmation message. - navigationService.pushDialog( - CustomAlertDialog( - key: const Key('customalertdialog'), - reverse: true, - dialogSubTitle: 'Are you sure you want to logout?', - successText: 'Logout', - success: () async { - try { - final result = await databaseFunctions - .gqlAuthMutation(queries.logout()) as QueryResult?; - if (result != null && result.data!['logout'] == true) { - navigationService.pop(); - navigationService.pushDialog( - const CustomProgressDialog( - key: Key('LogoutProgress'), - ), - ); - Future.delayed(const Duration(seconds: 1)).then((value) { - user = Hive.box('currentUser'); - url = Hive.box('url'); - final androidFirebaseOptionsBox = - Hive.box('androidFirebaseOptions'); - final iosFirebaseOptionsBox = Hive.box('iosFirebaseOptions'); - organisation = Hive.box('currentOrg'); - user.clear(); - url.clear(); - androidFirebaseOptionsBox.clear(); - iosFirebaseOptionsBox.clear(); - try { - Firebase.app() - .delete(); // Deleting app will stop all Firebase plugins - } catch (e) { - debugPrint("ERROR: Unable to delete firebase app $e"); - } - organisation.clear(); - navigationService.pop(); - navigationService.removeAllAndPush( - '/selectLang', - '/', - arguments: '0', - ); - }); - } - } catch (e) { - print(e); - } - }, - ), - ); + navigationService.pushDialog(logoutDialog()); } /// This method changes the currency of the user for donation purpose. @@ -235,6 +185,33 @@ class ProfilePageViewModel extends BaseModel { ); } + Widget logoutDialog() { + return CustomAlertDialog( + reverse: true, + dialogSubTitle: 'Are you sure you want to logout?', + successText: 'Logout', + success: () async { + await userConfig.userLogOut(); + navigationService.pop(); + if (userConfig.loggedIn) { + navigationService.pushDialog( + const TalawaErrorDialog( + 'Unable to logout, please try again.', + key: Key('TalawaError'), + messageType: MessageType.error, + ), + ); + } else { + navigationService.removeAllAndPush( + '/selectLang', + '/', + arguments: '0', + ); + } + }, + ); + } + /// This widget returns the button for social media sharing option. /// /// **params**: diff --git a/lib/view_model/lang_view_model.dart b/lib/view_model/lang_view_model.dart index 7ad6220e0..229e7993f 100644 --- a/lib/view_model/lang_view_model.dart +++ b/lib/view_model/lang_view_model.dart @@ -1,14 +1,14 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:talawa/constants/routing_constants.dart'; import 'package:talawa/locator.dart'; +import 'package:talawa/models/mainscreen_navigation_args.dart'; import 'package:talawa/services/database_mutation_functions.dart'; import 'package:talawa/services/navigation_service.dart'; import 'package:talawa/view_model/base_view_model.dart'; /// AppLanguage view model class interact with modal in the context of the App Language. +/// /// The class provides methods that set's the language, change the language in the modal. /// /// Methods include: @@ -21,20 +21,39 @@ import 'package:talawa/view_model/base_view_model.dart'; class AppLanguage extends BaseModel { AppLanguage({this.isTest = false}); + /// Represents a boolean value indicating whether the current environment is a test environment. final bool isTest; + + /// A service that provides navigation-related functionalities. final navigationService = locator(); + + /// Functions related to database mutations. final databaseFunctions = locator(); late Locale _appLocale; + + /// getter for appLocal. Locale get appLocal => _appLocale; - // initialiser + /// initialiser. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: returns a future of void type. Future initialize() async { _appLocale = const Locale('en'); await fetchLocale(); } /// This function fetch the language of the user's app. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: returns a future of void type. Future fetchLocale() async { final prefs = await SharedPreferences.getInstance(); final String langCode = prefs.getString('language_code') ?? 'en'; @@ -45,8 +64,11 @@ class AppLanguage extends BaseModel { /// This function change the app default language. /// - /// params: - /// * [type] : `Locale` type, the language need to be updated with. + /// **params**: + /// * `type`: `Locale` type, the language need to be updated with. + /// + /// **returns**: + /// * `Future`: returns a future of void type. Future changeLanguage(Locale type) async { // if the app language is of same [type]. if (_appLocale == type) { @@ -104,19 +126,36 @@ class AppLanguage extends BaseModel { notifyListeners(); } - /// This function navigate user to `/appSettingsPage` route if the user is authenticated - /// else navigate to `/setUrl` route. + /// This function navigate user to `/appSettingsPage` route if the user is authenticated else navigate to `demoMode - /MainScreenPage` route. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: returns a future of void type. Future selectLanguagePress() async { - final bool userLoggedIn = await userConfig.userLoggedIn(); - if (userLoggedIn) { + if (userConfig.loggedIn) { dbLanguageUpdate(); navigationService.popAndPushScreen('/appSettingsPage', arguments: ''); } else { - navigationService.pushScreen('/setUrl', arguments: ''); + navigationService.pushScreen( + Routes.mainScreen, + arguments: MainScreenArgs( + mainScreenIndex: 0, + fromSignUp: false, + toggleDemoMode: true, + ), + ); } } /// This function updates the Database Language by running the graphQL `mutations`. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: returns a future of void type. Future dbLanguageUpdate() async { try { await databaseFunctions @@ -127,8 +166,13 @@ class AppLanguage extends BaseModel { } } - /// This function perform graphQL query to check the app language. - /// The function uses `gqlAuthQuery` method provided by Database Functions Services. + /// This function perform graphQL query to check the app language.The function uses `gqlAuthQuery` method provided by Database Functions Services. + /// + /// **params**: + /// None + /// + /// **returns**: + /// * `Future`: returns a future of void type. Future appLanguageQuery() async { try { await databaseFunctions.gqlAuthQuery(queries.userLanguage()); @@ -138,10 +182,14 @@ class AppLanguage extends BaseModel { } /// This function perform graphQL query to check the user's language in the database. + /// /// The function uses `gqlAuthQuery` method provided by Database Functions Services. /// - /// params: - /// * [userId] : user for which language need to be fetch. + /// **params**: + /// * `userId`: user for which language need to be fetch. + /// + /// **returns**: + /// * `Future`: returns a future of void type. Future userLanguageQuery(String userId) async { try { await databaseFunctions.gqlAuthQuery(queries.newUserLanguage(userId)); diff --git a/lib/view_model/main_screen_view_model.dart b/lib/view_model/main_screen_view_model.dart index adeab4eb5..9766c29f5 100644 --- a/lib/view_model/main_screen_view_model.dart +++ b/lib/view_model/main_screen_view_model.dart @@ -3,14 +3,17 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:talawa/locator.dart'; +import 'package:talawa/models/app_tour.dart'; import 'package:talawa/plugins/fetch_plugin_list.dart'; -import 'package:talawa/services/size_config.dart'; import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/view_model/base_view_model.dart'; // import 'package:talawa/views/after_auth_screens/chat/chat_list_screen.dart'; import 'package:talawa/views/after_auth_screens/events/explore_events.dart'; import 'package:talawa/views/after_auth_screens/feed/organization_feed.dart'; import 'package:talawa/views/after_auth_screens/profile/profile_page.dart'; +import 'package:talawa/views/demo_screens/explore_events_demo.dart'; +import 'package:talawa/views/demo_screens/organization_feed_demo.dart'; +import 'package:talawa/views/demo_screens/profile_page_demo.dart'; import 'package:talawa/widgets/custom_alert_dialog.dart'; import 'package:talawa/widgets/theme_switch.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; @@ -35,6 +38,9 @@ class MainScreenViewModel extends BaseModel { /// static variables. final GlobalKey keyBNHome = GlobalKey(debugLabel: "HomeTab"); + /// static variables. + final GlobalKey keyBNDemoHome = GlobalKey(debugLabel: "DemoHomeTab"); + /// static variables. final GlobalKey keySHPinnedPost = GlobalKey(debugLabel: "HomeScreenPinnedPost"); @@ -67,6 +73,9 @@ class MainScreenViewModel extends BaseModel { /// static variables. final GlobalKey keyBNEvents = GlobalKey(debugLabel: "EventTab"); + /// static variables. + final GlobalKey keyBNDemoEvents = GlobalKey(debugLabel: "DemoEventTab"); + /// static variables. final GlobalKey keySECategoryMenu = GlobalKey(debugLabel: "EventScreenCategory"); @@ -84,12 +93,18 @@ class MainScreenViewModel extends BaseModel { /// static variables. final GlobalKey keyBNPost = GlobalKey(debugLabel: "PostTab"); + /// static variables. + final GlobalKey keyBNDemoPost = GlobalKey(debugLabel: "DemoPostTab"); + /// static variables. final GlobalKey keyBNChat = GlobalKey(debugLabel: "ChatTab"); /// static variables. final GlobalKey keyBNProfile = GlobalKey(debugLabel: "ProfileTab"); + /// static variables. + final GlobalKey keyBNDemoProfile = GlobalKey(debugLabel: "DemoProfileTab"); + /// static variables. final GlobalKey keySPEditProfile = GlobalKey(debugLabel: "ProfileScreenEdit"); @@ -127,10 +142,16 @@ class MainScreenViewModel extends BaseModel { late BuildContext context; /// tutorialCoachMark consist of coach used to give tutorial. - late TutorialCoachMark tutorialCoachMark; + late AppTour appTour = AppTour(model: this); /// array of target. - final List targets = []; + final List targets = []; + + /// flag to represent if app is in demoMode. + bool demoMode = false; + + /// flag to represent if app is in testMode. + bool testMode = false; /// Initalizing function. /// @@ -145,10 +166,17 @@ class MainScreenViewModel extends BaseModel { BuildContext ctx, { required bool fromSignUp, required int mainScreenIndex, + bool demoMode = false, + bool testMode = false, }) { + this.testMode = testMode; + this.demoMode = demoMode; currentPageIndex = mainScreenIndex; - showAppTour = fromSignUp; + showAppTour = fromSignUp || demoMode; + context = ctx; + print(ctx); + print(context); pluginPrototypeData = { "Donation": { "icon": Icons.attach_money_outlined, @@ -164,22 +192,7 @@ class MainScreenViewModel extends BaseModel { Future.delayed( const Duration(seconds: 1), () => navigationService.pushDialog( - CustomAlertDialog( - dialogTitle: 'App Tour', - dialogSubTitle: 'Start app tour to know talawa functioning', - successText: 'Start', - secondaryButtonText: 'Skip', - success: () { - context = ctx; - navigationService.pop(); - tourHomeTargets(); - }, - secondaryButtonTap: () { - tourComplete = false; - tourSkipped = true; - notifyListeners(); - }, - ), + appTourDialog(ctx), ), ); } @@ -250,58 +263,91 @@ class MainScreenViewModel extends BaseModel { ), ]; - pages = [ - OrganizationFeed( - key: const Key("HomeView"), - homeModel: this, - ), - ExploreEvents( - key: const Key('ExploreEvents'), - homeModel: this, - ), - ProfilePage( - key: keySPEditProfile, - homeModel: this, - ), - ]; - - pluginList = (Hive.box('pluginBox').get('plugins') ?? []) as List; - - pluginList.forEach((plugin) { - if (pluginPrototypeData.containsKey( - (plugin as Map)["pluginName"] as String, - ) && - plugin["pluginInstallStatus"] as bool) { - navBarItems.add( - BottomNavigationBarItem( - icon: Icon( - (pluginPrototypeData[plugin["pluginName"]] - as Map)["icon"] as IconData, - ), - label: AppLocalizations.of(context)!.strictTranslate( - plugin["pluginName"] as String, - ), - ), - ); - pages.add( - (pluginPrototypeData[plugin["pluginName"]] - as Map)["class"] as StatelessWidget, - ); - } - }); - - /// Causes the app check the plugins updates in every 300 sec - /// - /// updated and re-render the navbar - Timer.periodic(const Duration(seconds: 300), (timer) { - FetchPluginList(); - final newPluginList = + if (!demoMode) { + pages = [ + OrganizationFeed( + key: const Key("HomeView"), + homeModel: this, + ), + ExploreEvents( + key: const Key('ExploreEvents'), + homeModel: this, + ), + // AddPost( + // key: const Key('AddPost'), + // drawerKey: MainScreenViewModel.scaffoldKey, + // ), + // const ChatPage( + // key: Key('Chats'), + // ), + ProfilePage( + key: keySPEditProfile, + homeModel: this, + ), + ]; + pluginList = (Hive.box('pluginBox').get('plugins') ?? []) as List; - if (listEquals(pluginList, newPluginList)) { - notifyListeners(); - } - }); + print(pluginPrototypeData); + pluginList.forEach((plugin) { + if (pluginPrototypeData.containsKey( + (plugin as Map)["pluginName"] as String, + ) && + plugin["pluginInstallStatus"] as bool) { + navBarItems.add( + BottomNavigationBarItem( + icon: Icon( + (pluginPrototypeData[plugin["pluginName"]] + as Map)["icon"] as IconData, + ), + label: AppLocalizations.of(context)!.strictTranslate( + plugin["pluginName"] as String, + ), + ), + ); + pages.add( + (pluginPrototypeData[plugin["pluginName"]] + as Map)["class"] as StatelessWidget, + ); + } + }); + + /// Causes the app check the plugins updates in every 300 sec + /// + /// updated and re-render the navbar + Timer.periodic(Duration(seconds: (testMode ? 1 : 300)), (timer) { + FetchPluginList(); + final newPluginList = + (Hive.box('pluginBox').get('plugins') ?? []) as List; + + if (listEquals(pluginList, newPluginList)) { + // notifyListeners(); + } + if (testMode) timer.cancel(); + }); + } else { + pages = [ + DemoOrganizationFeed( + key: const Key("DemoHomeView"), + homeModel: this, + ), + DemoExploreEvents( + key: const Key('DemoExploreEvents'), + homeModel: this, + ), + // DemoAddPost( + // key: const Key('DemoAddPost'), + // drawerKey: MainScreenViewModel.scaffoldKey, + // ), + // const ChatPage( + // key: Key('Chats'), + // ), + DemoProfilePage( + key: const Key('DemoProfile'), + homeModel: this, + ), + ]; + } } /// var for current page in index. @@ -319,43 +365,28 @@ class MainScreenViewModel extends BaseModel { notifyListeners(); } - /// This function show tutorial to user. - /// - /// **params**: - /// * `onClickTarget`: Its a function which is required to run desired tasks on click. - /// * `onFinish`: Its a function which is required to run desired tasks on finish - /// - /// - /// **returns**: - /// None - void showTutorial({ - required dynamic Function(TargetFocus) onClickTarget, - required dynamic Function() onFinish, - }) { - tutorialCoachMark = TutorialCoachMark( - targets: targets, - colorShadow: Theme.of(context).colorScheme.secondaryContainer, - textSkip: "SKIP", - textStyleSkip: TextStyle( - color: Theme.of(context).colorScheme.background, - fontSize: 20, - ), - paddingFocus: 10, - opacityShadow: 1.0, - onFinish: onFinish, - onClickTarget: onClickTarget, - onSkip: () { - if (scaffoldKey.currentState!.isDrawerOpen) { - navigationService.pop(); + Widget appTourDialog(BuildContext ctx) { + return CustomAlertDialog( + dialogTitle: 'App Tour', + dialogSubTitle: 'Start app tour to know talawa functioning', + successText: 'Start', + secondaryButtonText: 'Skip', + success: () { + navigationService.pop(); + print(MainScreenViewModel.scaffoldKey.currentState?.isDrawerOpen); + if (MainScreenViewModel.scaffoldKey.currentState?.isDrawerOpen ?? + false) { + MainScreenViewModel.scaffoldKey.currentState?.closeDrawer(); } - tourSkipped = true; - onTabTapped(0); - return true; + tourHomeTargets(); }, - onClickOverlay: (target) { - onClickTarget(target); + secondaryButtonTap: () { + tourComplete = false; + tourSkipped = true; + navigationService.pop(); + notifyListeners(); }, - )..show(context: context); + ); } /// this functions starts the tour and info to be displayed is mentioned in this functions. @@ -368,78 +399,107 @@ class MainScreenViewModel extends BaseModel { void tourHomeTargets() { targets.clear(); targets.add( - focusTarget( - keySHOrgName, - 'keySHOrgName', - 'Current selected Organization Name', + FocusTarget( + key: keySHOrgName, + keyName: 'keySHOrgName', + description: 'Current selected Organization Name', + appTour: appTour, ), ); targets.add( - focusTarget( - keySHMenuIcon, - 'keySHMenuIcon', - 'Click this button to see options related to switching, joining and leaving organization(s)', + FocusTarget( + key: keySHMenuIcon, + keyName: 'keySHMenuIcon', + description: + 'Click this button to see options related to switching, joining and leaving organization(s)', isCircle: true, next: () => scaffoldKey.currentState!.openDrawer(), + appTour: appTour, ), ); + targets.add( - focusTarget( - keyDrawerCurOrg, - 'keyDrawerCurOrg', - "Current selected Organization's Name appears here", - ), - ); - targets.add( - focusTarget( - keyDrawerSwitchableOrg, - 'keyDrawerSwitchableOrg', - "All your joined organizations appear over here you can click on them to change the current organization", + FocusTarget( + key: keyDrawerCurOrg, + keyName: 'keyDrawerCurOrg', + description: "Current selected Organization's Name appears here", + appTour: appTour, ), ); + targets.add( - focusTarget( - keyDrawerJoinOrg, - 'keyDrawerJoinOrg', - "From this button you can join other listed organizations", - align: ContentAlign.top, + FocusTarget( + key: keyDrawerSwitchableOrg, + keyName: 'keyDrawerSwitchableOrg', + description: + "All your joined organizations appear over here you can click on them to change the current organization", + appTour: appTour, ), ); + targets.add( - focusTarget( - keyDrawerLeaveCurrentOrg, - 'keyDrawerLeaveCurrentOrg', - "To leave the current organization you can use this option", + FocusTarget( + key: keyDrawerJoinOrg, + keyName: 'keyDrawerJoinOrg', + description: "From this button you can join other listed organizations", + appTour: appTour, align: ContentAlign.top, - next: () => navigationService.pop(), + next: () { + if (!userConfig.loggedIn) { + navigationService.pop(); + } + }, ), ); + + if (userConfig.loggedIn) { + targets.add( + FocusTarget( + key: keyDrawerLeaveCurrentOrg, + keyName: 'keyDrawerLeaveCurrentOrg', + description: + "To leave the current organization you can use this option", + align: ContentAlign.top, + next: () => navigationService.pop(), + appTour: appTour, + ), + ); + } + targets.add( - focusTarget( - keyBNHome, - 'keyBNHome', - "This is the home tab here you can see the latest post from other members of the current organization", + FocusTarget( + key: keyBNHome, + keyName: 'keyBNHome', + description: + "This is the home tab here you can see the latest post from other members of the current organization", isCircle: true, align: ContentAlign.top, + appTour: appTour, ), ); + targets.add( - focusTarget( - keySHPinnedPost, - 'keySHPinnedPost', - "This section displays all the important post set by the organization admin(s)", + FocusTarget( + key: keySHPinnedPost, + keyName: 'keySHPinnedPost', + description: + "This section displays all the important post set by the organization admin(s)", align: ContentAlign.bottom, + appTour: appTour, ), ); + targets.add( - focusTarget( - keySHPost, - 'keySHPost', - "This is the post card you can like and comment on the post from the options available", + FocusTarget( + key: keySHPost, + keyName: 'keySHPost', + description: + "This is the post card you can like and comment on the post from the options available", align: ContentAlign.bottom, + appTour: appTour, ), ); - showTutorial( + appTour.showTutorial( onClickTarget: showHome, onFinish: () { onTabTapped(currentPageIndex + 1); @@ -447,6 +507,7 @@ class MainScreenViewModel extends BaseModel { tourEventTargets(); } }, + targets: targets, ); } @@ -477,51 +538,64 @@ class MainScreenViewModel extends BaseModel { void tourEventTargets() { targets.clear(); targets.add( - focusTarget( - keyBNEvents, - 'keyBNEvents', - 'This is the Events tab here you can see all event related information of the current selected organization', + FocusTarget( + key: keyBNEvents, + keyName: 'keyBNEvents', + description: + 'This is the Events tab here you can see all event related information of the current selected organization', isCircle: true, align: ContentAlign.top, + appTour: appTour, ), ); + targets.add( - focusTarget( - keySECategoryMenu, - 'keySECategoryMenu', - 'Filter Events based on categories', + FocusTarget( + key: keySECategoryMenu, + keyName: 'keySECategoryMenu', + description: 'Filter Events based on categories', + appTour: appTour, ), ); + targets.add( - focusTarget( - keySEDateFilter, - 'keySEDateFilter', - 'Filter Events between selected dates', + FocusTarget( + key: keySEDateFilter, + keyName: 'keySEDateFilter', + description: 'Filter Events between selected dates', + appTour: appTour, ), ); + targets.add( - focusTarget( - keySECard, - 'keySECard', - 'Description of event to see more details click on the card', + FocusTarget( + key: keySECard, + keyName: 'keySECard', + description: + 'Description of event to see more details click on the card', + appTour: appTour, ), ); + targets.add( - focusTarget( - keySEAdd, - 'keySEAdd', - 'You can create a new event from here', + FocusTarget( + key: keySEAdd, + keyName: 'keySEAdd', + description: 'You can create a new event from here', align: ContentAlign.top, + appTour: appTour, ), ); - showTutorial( + + appTour.showTutorial( onFinish: () { onTabTapped(currentPageIndex + 1); if (!tourComplete && !tourSkipped) { - tourAddPost(); + tourProfile(); } }, onClickTarget: (TargetFocus a) {}, + targets: targets, ); } @@ -535,22 +609,26 @@ class MainScreenViewModel extends BaseModel { void tourAddPost() { targets.clear(); targets.add( - focusTarget( - keyBNPost, - 'keyBNPost', - 'This is the Create post tab here you can add post to the current selected organization', + FocusTarget( + key: keyBNPost, + keyName: 'keyBNPost', + description: + 'This is the Create post tab here you can add post to the current selected organization', isCircle: true, align: ContentAlign.top, + appTour: appTour, ), ); - showTutorial( + appTour.showTutorial( onFinish: () { onTabTapped(currentPageIndex + 1); if (!tourComplete && !tourSkipped) { - tourChat(); + // tourChat(); + tourProfile(); } }, onClickTarget: (TargetFocus a) {}, + targets: targets, ); } @@ -564,15 +642,17 @@ class MainScreenViewModel extends BaseModel { void tourChat() { targets.clear(); targets.add( - focusTarget( - keyBNChat, - 'keyBNChat', - 'This is the Chat tab here you can see all your messages of the current selected organization', + FocusTarget( + key: keyBNChat, + keyName: 'keyBNChat', + description: + 'This is the Chat tab here you can see all your messages of the current selected organization', isCircle: true, align: ContentAlign.top, + appTour: appTour, ), ); - showTutorial( + appTour.showTutorial( onFinish: () { onTabTapped(currentPageIndex + 1); if (!tourComplete && !tourSkipped) { @@ -580,6 +660,7 @@ class MainScreenViewModel extends BaseModel { } }, onClickTarget: (TargetFocus a) {}, + targets: targets, ); } @@ -593,52 +674,68 @@ class MainScreenViewModel extends BaseModel { void tourProfile() { targets.clear(); targets.add( - focusTarget( - keyBNProfile, - 'keyBNProfile', - 'This is the Profile tab here you can see all options related to account, app setting, invitation, help etc', + FocusTarget( + key: keyBNProfile, + keyName: 'keyBNProfile', + description: + 'This is the Profile tab here you can see all options related to account, app setting, invitation, help etc', isCircle: true, align: ContentAlign.top, nextCrossAlign: CrossAxisAlignment.start, + appTour: appTour, ), ); + targets.add( - focusTarget( - keySPAppSetting, - 'keySPAppSetting', - 'You can edit application settings like language, theme etc from here', + FocusTarget( + key: keySPAppSetting, + keyName: 'keySPAppSetting', + description: + 'You can edit application settings like language, theme etc from here', + appTour: appTour, ), ); + targets.add( - focusTarget( - keySPHelp, - 'keySPHelp', - 'For any help we are always there. You can reach us from here', + FocusTarget( + key: keySPHelp, + keyName: 'keySPHelp', + description: + 'For any help we are always there. You can reach us from here', + appTour: appTour, ), ); + targets.add( - focusTarget( - keySPDonateUs, - 'keySPDonateUs', - 'To help your organization grow you can support them financially from here', + FocusTarget( + key: keySPDonateUs, + keyName: 'keySPDonateUs', + description: + 'To help your organization grow you can support them financially from here', + appTour: appTour, ), ); - // targets.add( - // focusTarget( - // keySPInvite, - // 'keySPInvite', - // 'Wanna invite colleague, invite them from here', - // ), - // ); + +// Uncomment the section below if you want to add the keySPInvite target +// targets.add( +// FocusTarget( +// key: keySPInvite, +// keyName: 'keySPInvite', +// description: 'Wanna invite colleague, invite them from here', +// ), +// ); + targets.add( - focusTarget( - keySPPalisadoes, - 'keySPPalisadoes', - 'You are all set to go lets get you in', + FocusTarget( + key: keySPPalisadoes, + keyName: 'keySPPalisadoes', + description: 'You are all set to go lets get you in', isEnd: true, + appTour: appTour, ), ); - showTutorial( + + appTour.showTutorial( onFinish: () { if (!tourComplete && !tourSkipped) { tourComplete = true; @@ -646,97 +743,7 @@ class MainScreenViewModel extends BaseModel { } }, onClickTarget: (TargetFocus a) {}, - ); - } - - /// This returns a widget for a step in a tutorial. - /// - /// **params**: - /// * `key`: key of type GlobalKey. - /// * `keyName`: key where the widget shows. - /// * `description`: description of the step. - /// * `isCircle`: bool to specify if circle - /// * `align`: align of type ContentAlign to align button. - /// * `crossAlign`: Cross align axes - /// * `skipAlignment`: to give alignment of skip option - /// * `next`: Function` type, this show the next step or `key` to show the tour of. - /// * `nextCrossAlign`: nextCrossAlign to give alignment of next option - /// * `isEnd`: true if last step of the tour. - /// - /// - /// **returns**: - /// * `TargetFocus`: This return widget foa a step in a tut - TargetFocus focusTarget( - GlobalKey key, - String keyName, - String description, { - bool isCircle = false, - ContentAlign align = ContentAlign.bottom, - CrossAxisAlignment crossAlign = CrossAxisAlignment.start, - Alignment skipAlignment = Alignment.topRight, - Function? next, - CrossAxisAlignment nextCrossAlign = CrossAxisAlignment.end, - bool isEnd = false, - }) { - return TargetFocus( - enableOverlayTab: true, - color: Colors.transparent, - identify: keyName, - keyTarget: key, - alignSkip: skipAlignment, - shape: isCircle ? ShapeLightFocus.Circle : ShapeLightFocus.RRect, - contents: [ - TargetContent( - align: align, - builder: (context, controller) { - return Container( - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: crossAlign, - children: [ - Text( - description, - style: TextStyle( - color: Theme.of(context).colorScheme.background, - fontSize: 20, - ), - ), - ], - ), - ); - }, - ), - TargetContent( - align: ContentAlign.custom, - customPosition: CustomTargetContentPosition( - bottom: SizeConfig.screenHeight! * 0.025, - ), - builder: (context, controller) { - return GestureDetector( - onTap: () { - if (next != null) { - // ignore: avoid_dynamic_calls - next(); - } - tutorialCoachMark.next(); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: nextCrossAlign, - children: [ - Text( - isEnd ? 'COMPLETE' : 'NEXT', - style: TextStyle( - color: Theme.of(context).colorScheme.background, - fontSize: 20, - ), - ), - ], - ), - ); - }, - ), - ], + targets: targets, ); } } diff --git a/lib/view_model/pre_auth_view_models/select_organization_view_model.dart b/lib/view_model/pre_auth_view_models/select_organization_view_model.dart index 5d33ae81d..170da8b86 100644 --- a/lib/view_model/pre_auth_view_models/select_organization_view_model.dart +++ b/lib/view_model/pre_auth_view_models/select_organization_view_model.dart @@ -257,10 +257,11 @@ class SelectOrganizationViewModel extends BaseModel { }, updateQuery: (existingOrganizations, newOrganizations) { return { - 'organizationsConnection': [ - existingOrganizations!["organizationsConnection"], - newOrganizations!['organizationsConnection'], - ], + 'organizationsConnection': + (existingOrganizations!["organizationsConnection"] + as List>) + + (newOrganizations!['organizationsConnection'] + as List>), }; }, ), diff --git a/lib/view_model/widgets_view_models/custom_drawer_view_model.dart b/lib/view_model/widgets_view_models/custom_drawer_view_model.dart index 2b27e958d..0abcb0742 100644 --- a/lib/view_model/widgets_view_models/custom_drawer_view_model.dart +++ b/lib/view_model/widgets_view_models/custom_drawer_view_model.dart @@ -1,6 +1,3 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - import 'dart:async'; import 'package:flutter/material.dart'; import 'package:talawa/enums/enums.dart'; @@ -11,8 +8,7 @@ import 'package:talawa/view_model/base_view_model.dart'; import 'package:talawa/view_model/main_screen_view_model.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; -/// CustomDrawerViewModel class helps to serve the data and -/// to react to user's input for Custom Dialog Widget. +/// CustomDrawerViewModel class helps to serve the data and to react to user's input for Custom Dialog Widget. /// /// Functions include: /// * `switchOrg` @@ -20,21 +16,40 @@ import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; /// * `setSelectedOrganizationName` class CustomDrawerViewModel extends BaseModel { // getters + + /// Scroll controller for managing scrolling behavior. final ScrollController controller = ScrollController(); + + /// List of TargetFocus objects used for tutorial coaching. final List targets = []; + + /// Instance of TutorialCoachMark responsible for providing tutorial guidance. late TutorialCoachMark tutorialCoachMark; late User _currentUser; late List _switchAbleOrg; bool _disposed = false; OrgInfo? _selectedOrg; StreamSubscription? _currentOrganizationStreamSubscription; + + //// Getter method to retrieve the selected organization. OrgInfo? get selectedOrg => _selectedOrg; + + /// Getter method to retrieve the switchAble organization. // ignore: unnecessary_getters_setters List get switchAbleOrg => _switchAbleOrg; + + /// Setter method for switchAble organization. set switchAbleOrg(List switchableOrg) => _switchAbleOrg = switchableOrg; - // initializer + /// initializer. + /// + /// **params**: + /// * `homeModel`: instance of MainScreenViewModel. + /// * `context`: instance of BuildContext. + /// + /// **returns**: + /// None void initialize(MainScreenViewModel homeModel, BuildContext context) { _currentOrganizationStreamSubscription = userConfig.currentOrgInfoStream.listen( @@ -44,11 +59,20 @@ class CustomDrawerViewModel extends BaseModel { ); _currentUser = userConfig.currentUser; _selectedOrg = userConfig.currentOrg; - _switchAbleOrg = _currentUser.joinedOrganizations!; + _switchAbleOrg = _currentUser.joinedOrganizations ?? []; } - /// This function switch the current organization to another organization, - /// if the organization(want switch to) is present. + /// This function switches the organization to the specified `switchToOrg`. + /// + /// If `selectedOrg` is equal to `switchToOrg` and `switchToOrg` is present, a warning message is displayed using a custom Snackbar. + /// Otherwise, it saves the `switchToOrg` as the current organization, updates the selected organization name, + /// and displays an informational message using a custom Snackbar. + /// + /// **params**: + /// * `switchToOrg`: The organization to switch to. + /// + /// **returns**: + /// None void switchOrg(OrgInfo switchToOrg) { // if `selectedOrg` is equal to `switchOrg` and `switchToOrg` present or not. if (selectedOrg == switchToOrg && isPresentinSwitchableOrg(switchToOrg)) { @@ -70,8 +94,11 @@ class CustomDrawerViewModel extends BaseModel { /// This function checks `switchOrg` is present in the `switchAbleOrg`. /// - /// params: - /// * [switchToOrg] : `OrgInfo` type of organization want to switch into. + /// **params**: + /// * `switchToOrg`: `OrgInfo` type of organization want to switch into. + /// + /// **returns**: + /// * `bool`: returns true if switchToOrg is in switchAbleOrg list. bool isPresentinSwitchableOrg(OrgInfo switchToOrg) { var isPresent = false; for (final OrgInfo orgs in switchAbleOrg) { @@ -91,8 +118,11 @@ class CustomDrawerViewModel extends BaseModel { /// This function switches the current organization to new organization. /// - /// params: - /// * [updatedOrganization] : `OrgInfo` type, new organization. + /// **params**: + /// * `updatedOrganization`: `OrgInfo` type, new organization. + /// + /// **returns**: + /// None void setSelectedOrganizationName(OrgInfo updatedOrganization) { // if current and updated organization are not same. if (_selectedOrg != updatedOrganization) { diff --git a/lib/views/after_auth_screens/add_post_page.dart b/lib/views/after_auth_screens/add_post_page.dart index f9fec26bd..7ed9fba9e 100644 --- a/lib/views/after_auth_screens/add_post_page.dart +++ b/lib/views/after_auth_screens/add_post_page.dart @@ -24,7 +24,6 @@ class _AddPostState extends State { Widget build(BuildContext context) { // final Uint8List imageBytes = base64Decode(sampleBase64Image); // final Uint8List bytes = BASE64.decode(_base64); - return Scaffold( resizeToAvoidBottomInset: false, // header for the widget @@ -77,155 +76,156 @@ class _AddPostState extends State { m.initialise(); model = m; }, - builder: (context, model, child) => SingleChildScrollView( - child: Column( - children: [ - ListTile( - leading: const CircleAvatar(radius: 25), - title: Text(model.userName), - subtitle: Text( - AppLocalizations.of(context)!.strictTranslate(model.orgName), - ), - ), - // renders icon button to upload post files. - Row( - children: [ - // button to select the photo from gallery. - IconButton( - key: const Key('add_post_icon_button2'), - onPressed: () => model.getImageFromGallery(), - icon: const Icon(Icons.photo), - ), - // button to capture the image. - IconButton( - key: const Key('add_post_icon_button3'), - onPressed: () => model.getImageFromGallery(camera: true), - icon: const Icon(Icons.camera_alt), + builder: (context, model, child) { + return SingleChildScrollView( + child: Column( + children: [ + ListTile( + leading: const CircleAvatar(radius: 25), + title: Text(model.userName), + subtitle: Text( + AppLocalizations.of(context)! + .strictTranslate(model.orgName), ), - // button to add hastags to the post. - TextButton( - key: const Key('add_post_text_btn2'), - onPressed: () async { - final TextEditingController hashController = - TextEditingController(); - hashController.text = model.textHashTagController.text; - await showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: const Text("Enter the Tag"), - content: TextField(controller: hashController), - actions: [ - TextButton( - key: const Key("add_hashtag_button"), - onPressed: () { - navigationService.showTalawaErrorSnackBar( - "The tag was added", - MessageType.info, - ); - Navigator.of(context).pop(); - }, - child: const Text("Add"), - ), - TextButton( - key: const Key("cancel_hashtag_button"), - onPressed: () { - Navigator.of(context).pop(); - }, - child: const Text("Cancel"), - ), - ], - ); - }, - ); - setState(() { - model.textHashTagController.text = hashController.text; - }); - }, - child: Text( - model.textHashTagController.text == "" - ? '# ${AppLocalizations.of(context)!.strictTranslate("Add tag")}' - : '# ${model.textHashTagController.text}', - style: Theme.of(context).textTheme.titleLarge, + ), + // renders icon button to upload post files. + Row( + children: [ + // button to select the photo from gallery. + IconButton( + key: const Key('add_post_icon_button2'), + onPressed: () => model.getImageFromGallery(), + icon: const Icon(Icons.photo), ), - ), - ], - ), - const Divider(), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: TextField( - controller: model.titleController, - // input field to write the description of the post. - decoration: InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - errorBorder: InputBorder.none, - disabledBorder: InputBorder.none, - hintText: AppLocalizations.of(context)!.strictTranslate( - "Enter the title of your post", + // button to capture the image. + IconButton( + key: const Key('add_post_icon_button3'), + onPressed: () => model.getImageFromGallery(camera: true), + icon: const Icon(Icons.camera_alt), + ), + // button to add hastags to the post. + TextButton( + key: const Key('add_post_text_btn2'), + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Enter the Tag"), + content: TextField( + controller: model.textHashTagController, + ), + actions: [ + TextButton( + key: const Key("add_hashtag_button"), + onPressed: () { + navigationService.showTalawaErrorSnackBar( + "The tag was added", + MessageType.info, + ); + Navigator.of(context).pop(); + }, + child: const Text("Add"), + ), + TextButton( + key: const Key("cancel_hashtag_button"), + onPressed: () { + Navigator.of(context).pop(); + }, + child: const Text("Cancel"), + ), + ], + ); + }, + ); + }, + child: Text( + model.textHashTagController.text == "" + ? '# ${AppLocalizations.of(context)!.strictTranslate("Add tag")}' + : model.textHashTagController.text, + style: Theme.of(context).textTheme.titleLarge, + ), ), - label: Text( - AppLocalizations.of(context)!.strictTranslate( - "Title", + ], + ), + const Divider(), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: TextField( + controller: model.titleController, + // input field to write the description of the post. + decoration: InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + disabledBorder: InputBorder.none, + hintText: AppLocalizations.of(context)!.strictTranslate( + "Enter the title of your post", + ), + label: Text( + AppLocalizations.of(context)!.strictTranslate( + "Title", + ), ), ), ), ), - ), - const Divider(), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: TextField( - controller: model.controller, - maxLines: null, - // input field to write the description of the post. - decoration: InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - errorBorder: InputBorder.none, - disabledBorder: InputBorder.none, - hintText: AppLocalizations.of(context)!.strictTranslate( - "Write here what do you want to share", + const Divider(), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: TextField( + controller: model.controller, + maxLines: null, + // input field to write the description of the post. + decoration: InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + disabledBorder: InputBorder.none, + hintText: AppLocalizations.of(context)!.strictTranslate( + "Write here what do you want to share", + ), ), ), ), - ), - // if the image for the post is added then render button to remove it. - model.imageFile != null - // ignore: sized_box_for_whitespace - ? Container( - height: 230, - padding: const EdgeInsets.all(8.0), - child: Stack( - children: [ - // Image.file( - // model.imageFile!, - // fit: BoxFit.cover, - // width: MediaQuery.of(context).size.width, - // ), - Image.file(model.imageFile!), - Positioned( - right: 5, - top: 5, - child: IconButton( - key: const Key("remove_icon"), - onPressed: () => model.removeImage(), - icon: const Icon( - Icons.cancel, - color: Colors.black, + // if the image for the post is added then render button to remove it. + model.imageFile != null + // ignore: sized_box_for_whitespace + ? Container( + height: 230, + padding: const EdgeInsets.all(8.0), + child: Stack( + children: [ + // Image.file( + // model.imageFile!, + // fit: BoxFit.cover, + // width: MediaQuery.of(context).size.width, + // ), + Image.file(model.imageFile!), + Positioned( + right: 5, + top: 5, + child: IconButton( + key: const Key("remove_icon"), + onPressed: () { + model.removeImage(); + }, + icon: const Icon( + Icons.cancel, + color: Colors.black, + ), ), ), - ), - ], - ), - ) - : Container(), - ], - ), - ), + ], + ), + ) + : Container(), + ], + ), + ); + }, ), ); } diff --git a/lib/views/after_auth_screens/app_settings/app_settings_page.dart b/lib/views/after_auth_screens/app_settings/app_settings_page.dart index 8e58e8e5a..88387999b 100644 --- a/lib/views/after_auth_screens/app_settings/app_settings_page.dart +++ b/lib/views/after_auth_screens/app_settings/app_settings_page.dart @@ -1,7 +1,5 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - import 'package:flutter/material.dart'; +import 'package:talawa/locator.dart'; import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/widgets/lang_switch.dart'; import 'package:talawa/widgets/theme_switch.dart'; @@ -38,6 +36,10 @@ class _AppSettingsPageState extends State { fontSize: 20, ), ), + leading: IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: () => navigationService.pop(), + ), ), // style of the AppBar. body: const Padding( diff --git a/lib/views/after_auth_screens/events/create_event_page.dart b/lib/views/after_auth_screens/events/create_event_page.dart index e31ec1b96..608f9975c 100644 --- a/lib/views/after_auth_screens/events/create_event_page.dart +++ b/lib/views/after_auth_screens/events/create_event_page.dart @@ -6,6 +6,7 @@ import 'package:talawa/services/size_config.dart'; import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/utils/validators.dart'; import 'package:talawa/view_model/after_auth_view_models/event_view_models/create_event_view_model.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; import 'package:talawa/views/after_auth_screens/events/create_event_form.dart'; import 'package:talawa/views/base_view.dart'; import 'package:talawa/widgets/add_members_bottom_sheet.dart'; @@ -54,8 +55,14 @@ class _CreateEventPageState extends State { ), actions: [ TextButton( + key: const Key('addButton'), onPressed: () { - model.createEvent(); + if (userConfig.loggedIn) { + model.createEvent(); + } else { + navigationService.pop(); + MainScreenViewModel.scaffoldKey.currentState?.openDrawer(); + } }, child: Text( AppLocalizations.of(context)!.strictTranslate('Add'), @@ -162,14 +169,16 @@ class _CreateEventPageState extends State { }); }, setTime: () async { + print(model.eventStartDate); final time = await customTimePicker( initialTime: model.eventStartTime, ); - + // print(model.eventStartTime); final validationError = Validator.validateEventTime( time, model.eventEndTime, ); + print('hi'); if (validationError != null) { navigationService.showTalawaErrorSnackBar( 'Start time must be before end time', diff --git a/lib/views/after_auth_screens/events/event_calendar.dart b/lib/views/after_auth_screens/events/event_calendar.dart index 067119c6b..8f0a9ea75 100644 --- a/lib/views/after_auth_screens/events/event_calendar.dart +++ b/lib/views/after_auth_screens/events/event_calendar.dart @@ -56,6 +56,7 @@ class _EventCalendarState extends State { @override Widget build(BuildContext context) { + print('hi'); return Scaffold( // header of the page. appBar: AppBar( diff --git a/lib/views/after_auth_screens/feed/organization_feed.dart b/lib/views/after_auth_screens/feed/organization_feed.dart index 459af1c7a..9c378f863 100644 --- a/lib/views/after_auth_screens/feed/organization_feed.dart +++ b/lib/views/after_auth_screens/feed/organization_feed.dart @@ -26,6 +26,7 @@ class OrganizationFeed extends StatelessWidget { return BaseView( onModelReady: (model) => model.initialise(isTest: forTest), builder: (context, model, child) { + print(model.pinnedPosts); return Scaffold( floatingActionButton: FloatingActionButton( shape: const CircleBorder(side: BorderSide.none), @@ -75,7 +76,10 @@ class OrganizationFeed extends StatelessWidget { children: [ // If the organization has pinned posts then renders PinnedPostCarousel widget else Container. model.pinnedPosts.isNotEmpty - ? PinnedPost(pinnedPost: model.pinnedPosts) + ? PinnedPost( + pinnedPost: model.pinnedPosts, + model: homeModel!, + ) : Container(), // If the organization has posts then renders PostListWidget widget else Container. model.posts.isNotEmpty diff --git a/lib/views/after_auth_screens/profile/profile_page.dart b/lib/views/after_auth_screens/profile/profile_page.dart index 36b60b97a..5f8f2864e 100644 --- a/lib/views/after_auth_screens/profile/profile_page.dart +++ b/lib/views/after_auth_screens/profile/profile_page.dart @@ -179,8 +179,10 @@ class ProfilePage extends StatelessWidget { children: [ RaisedRoundedButton( key: homeModel!.keySPDonateUs, - buttonLabel: AppLocalizations.of(context)! - .strictTranslate('Donate to the Community'), + buttonLabel: + AppLocalizations.of(context)!.strictTranslate( + 'Donate to the Community', + ), onTap: () => donate(context, model), textColor: Theme.of(context) .inputDecorationTheme @@ -210,11 +212,11 @@ class ProfilePage extends StatelessWidget { mainAxisSpacing: 5, crossAxisCount: 3, children: [ - Image.asset('assets/images/pfp2.jpeg'), - Image.asset('assets/images/pfp2.jpeg'), - Image.asset('assets/images/pfp2.jpeg'), - Image.asset('assets/images/pfp2.jpeg'), - Image.asset('assets/images/pfp2.jpeg'), + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), ], ), ), diff --git a/lib/views/demo_screens/explore_events_demo.dart b/lib/views/demo_screens/explore_events_demo.dart new file mode 100644 index 000000000..24204d896 --- /dev/null +++ b/lib/views/demo_screens/explore_events_demo.dart @@ -0,0 +1,266 @@ +import 'package:flutter/material.dart'; +import 'package:talawa/constants/routing_constants.dart'; +import 'package:talawa/locator.dart'; +import 'package:talawa/services/size_config.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/view_model/after_auth_view_models/event_view_models/explore_events_view_model.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/views/after_auth_screens/events/explore_event_dialogue.dart'; +import 'package:talawa/widgets/event_card.dart'; + +/// Shows the list of events with options to categorize them. +class DemoExploreEvents extends StatelessWidget { + const DemoExploreEvents({ + required Key key, + this.homeModel, + }) : super(key: key); + + /// [homeModal] is a type of [MainScreenViewModel] which provides methods to handle the data for this component. + final MainScreenViewModel? homeModel; + + @override + Widget build(BuildContext context) { + final model = locator(); + return Scaffold( + appBar: AppBar( + // AppBar returns widget for the header. + backgroundColor: Theme.of(context).primaryColor, + key: const Key("ExploreEventsAppBar"), + elevation: 0.0, + automaticallyImplyLeading: false, + centerTitle: true, + title: Text( + AppLocalizations.of(context)!.strictTranslate('Explore Events'), + style: Theme.of(context).textTheme.titleLarge!.copyWith( + fontWeight: FontWeight.w600, + fontSize: 20, + ), + ), + leading: IconButton( + // returns a button of menu icon to redirect to home. + color: Theme.of(context).iconTheme.color, + icon: const Icon(Icons.menu), + onPressed: () => + MainScreenViewModel.scaffoldKey.currentState!.openDrawer(), + ), + actions: [ + Padding( + padding: EdgeInsets.only( + right: SizeConfig.screenWidth! * 0.027, + ), + // if the events is not empty then renders button for searching the events else renders just a box. + // child: model.events.isNotEmpty + // ? IconButton( + // onPressed: () { + // showSearch( + // context: context, + // delegate: EventSearch( + // eventList: model.events, + // exploreEventsViewModel: model, + // ), + // ); + // }, + // icon: const Icon(Icons.search, size: 20), + // ) + // : const SizedBox(), + child: const SizedBox(), + ), + ], + ), + // if the model is still fetching the events list then renders the Circular Progress Indicator + // else render refresh icon along with the list of searched events for exploration. + body: Stack( + children: [ + SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: SizeConfig.screenWidth! * 0.010, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 3, + child: Card( + color: Theme.of(context).colorScheme.onPrimary, + elevation: 2, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 20, + ), + //width: SizeConfig.screenWidth! * 0.45, + child: DropdownButtonHideUnderline( + child: dropDownList(model, context), + ), + ), + ), + ), + Expanded( + flex: 2, + child: GestureDetector( + onTap: () { + showDialog( + // on tap open the Explore Event Dialog. + context: context, + builder: (_) { + return const ExploreEventDialog( + key: Key('ExploreEvents'), + ); + }, + ); + }, + child: Card( + key: homeModel?.keySEDateFilter, + color: Theme.of(context).colorScheme.onPrimary, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 12, + ), + // width: SizeConfig.screenWidth! * 0.30, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + const Icon( + Icons.calendar_today, + color: Color(0xff524F4F), + ), + const SizedBox( + width: 8, + ), + Text( + AppLocalizations.of(context)! + .strictTranslate( + "Add Date", + ), + ), + ], + ), + ), + ), + ), + ), + Expanded( + flex: 1, + child: Card( + color: Theme.of(context).colorScheme.onPrimary, + child: IconButton( + onPressed: () { + navigationService.pushScreen( + Routes.calendar, + arguments: model.events, + ); + }, + icon: const Icon( + Icons.calendar_month, + ), + ), + ), + ), + ], + ), + SizedBox( + height: SizeConfig.screenHeight! * 0.027, + ), + // if the events model is empty then renders a box with text as "Empty List" + // else renders lists of the all event tile. + model.events.isEmpty + ? SizedBox( + height: SizeConfig.screenHeight! * 0.5, + child: Center( + child: Text(model.emptyListMessage), + ), + ) + : ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: model.events.length, + itemBuilder: (BuildContext context, int index) { + return GestureDetector( + onTap: () { + navigationService.pushScreen( + "/eventInfo", + arguments: { + "event": model.events[index], + "exploreEventViewModel": model, + }, + ); + }, + child: EventCard( + event: model.events[index], + isSearchItem: false, + ), + ); + }, + ), + ], + ), + ), + ), + ], + ), + + floatingActionButton: FloatingActionButton.extended( + key: homeModel?.keySEAdd, + heroTag: "AddEventFab", + backgroundColor: Theme.of(context).colorScheme.background, + onPressed: () { + navigationService.pushScreen( + "/createEventPage", + ); + }, + icon: Icon( + Icons.add, + color: Theme.of(context).colorScheme.secondary, + ), + label: Text( + AppLocalizations.of(context)!.strictTranslate("Event"), + style: Theme.of(context) + .textTheme + .headlineSmall! + .copyWith(color: Theme.of(context).colorScheme.secondary), + ), + ), + ); + } + + /// Shows a list of dropdown taken from `model` and `context`. + /// + /// **params**: + /// * `model`: contains the events data + /// * `context`: the overall context of UI + /// + /// **returns**: + /// * `Widget`: the dropdown + Widget dropDownList(ExploreEventsViewModel model, BuildContext context) { + return DropdownButton( + key: homeModel?.keySECategoryMenu, + value: model.chosenValue, + isExpanded: true, + items: [ + 'All Events', + 'Created Events', + 'Registered Events', + 'Public Events', + 'Private Events', + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text( + AppLocalizations.of(context)!.strictTranslate(value), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(color: Theme.of(context).colorScheme.secondary), + ), + ); + }).toList(), + onChanged: (value) { + model.choseValueFromDropdown(value!); + }, + ); + } +} diff --git a/lib/views/demo_screens/organization_feed_demo.dart b/lib/views/demo_screens/organization_feed_demo.dart new file mode 100644 index 000000000..ec4f9b849 --- /dev/null +++ b/lib/views/demo_screens/organization_feed_demo.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:talawa/models/post/post_model.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/widgets/pinned_post.dart'; + +/// OrganizationFeed returns a widget that shows the feed of the organization. +class DemoOrganizationFeed extends StatelessWidget { + const DemoOrganizationFeed({ + required Key key, + this.homeModel, + this.forTest = false, + }) : super(key: key); + + /// MainScreenViewModel. + final MainScreenViewModel? homeModel; + + /// To implement the test. + final bool forTest; + + /// a_line_ending_with_end_punctuation. + /// + /// more_info_if_required + static const List> pinnedPosts = [ + { + 'text': 'Church Meeting', + '_id': 'hdkahfu567', + 'imageUrl': + 'https://i2-prod.manchestereveningnews.co.uk/incoming/article25630061.ece/ALTERNATES/s615/2_Church-PA.jpg', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'Russia-Ukraine war leads to Hike in Gas prices in Europe.', + '_id': 'hfkajhk669', + 'imageUrl': + 'https://gdb.voanews.com/3B960F7F-786C-452C-8ABD-9D5AEEAED9D9.jpg', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'Flood in near village.', + '_id': 'adadada555', + 'imageUrl': + 'https://www.deccanherald.com/sites/dh/files/styles/article_detail/public/articleimages/2022/08/03/file7m4trf3i92e1krs53cn6-1132513-1659475940.jpg?itok=oVs3TTP8', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'The craze behind auto-tech stocks.', + '_id': 'nvikaebkf', + 'imageUrl': + 'https://akm-img-a-in.tosshub.com/businesstoday/images/assets/202303/stock-market-02136-4-sixteen_nine.jpg', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'High seas treaty', + '_id': 'nfqbkbd', + 'imageUrl': + 'https://ichef.bbci.co.uk/news/976/cpsprodpb/A194/production/_128846314_humpbackwhale.jpg', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'WWE Wrestking and Gambling', + '_id': 'dadadada', + 'imageUrl': + 'https://staticc.sportskeeda.com/editor/2023/03/a9b3a-16783664764772-1920.jpg', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'Dead of Silicon Valley Bank.', + '_id': 'hfkaaddadajhk669', + 'imageUrl': + 'https://thechainsaw.com/wp-content/uploads/2023/03/2023-50.jpg?w=1200', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'What if women were paid for chores', + '_id': 'kofapjfn', + 'imageUrl': + 'https://www.shethepeople.tv/wp-content/uploads/2019/06/household.png', + 'createdAt': '2023-12-14T08:30:00Z', + }, + { + 'text': 'Debate over stocks bybacks.', + '_id': 'agdjvfhsjaf', + 'imageUrl': + 'https://m.wsj.net/video/20200105/wsjglossarystockbuybackssplash/wsjglossarystockbuybackssplash_640x360.jpg', + 'createdAt': '2023-12-14T08:30:00Z', + }, + ]; + + Widget demoOrganisationFeedPage(BuildContext context) { + return Scaffold( + appBar: AppBar( + // AppBar returns a widget for the header of the page. + backgroundColor: Colors.green, + // Theme.of(context).primaryColor, + elevation: 0.0, + centerTitle: true, + title: Text( + "Organisation Name", + key: homeModel?.keySHOrgName, + style: Theme.of(context).textTheme.titleLarge!.copyWith( + fontSize: 20, + color: Colors.white, + ), + ), + leading: IconButton( + key: homeModel?.keySHMenuIcon, + icon: Icon( + Icons.menu, + color: Theme.of(context).iconTheme.color, + ), + onPressed: () { + MainScreenViewModel.scaffoldKey.currentState!.openDrawer(); + }, + ), + ), + // if the model is fetching the data then renders Circular Progress Indicator else renders the result. + body: ListView( + shrinkWrap: true, + children: [ + // If the organization has pinned posts then renders PinnedPostCarousel widget else Container. + PinnedPost( + pinnedPost: pinnedPosts.map((map) => Post.fromJson(map)).toList(), + model: homeModel!, + ), + // If the organization has posts then renders PostListWidget widget else Container. + Container(), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return demoOrganisationFeedPage(context); + } +} diff --git a/lib/views/demo_screens/profile_page_demo.dart b/lib/views/demo_screens/profile_page_demo.dart new file mode 100644 index 000000000..41303f513 --- /dev/null +++ b/lib/views/demo_screens/profile_page_demo.dart @@ -0,0 +1,237 @@ +import 'package:contained_tab_bar_view/contained_tab_bar_view.dart'; +import 'package:flutter/material.dart'; +import 'package:talawa/locator.dart'; +import 'package:talawa/services/size_config.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/widgets/custom_avatar.dart'; +import 'package:talawa/widgets/from_palisadoes.dart'; +import 'package:talawa/widgets/raised_round_edge_button.dart'; + +/// ProfilePage returns a widget that renders a page of user's profile. +class DemoProfilePage extends StatelessWidget { + const DemoProfilePage({ + required Key key, + this.homeModel, + }) : super(key: key); + + /// MainScreenViewModel. + /// + final MainScreenViewModel? homeModel; + + @override + Widget build(BuildContext context) { + print(userConfig.loggedIn); + return Scaffold( + key: const Key('DemoProfilePage'), + appBar: AppBar( + backgroundColor: Colors.green, + // Theme.of(context).primaryColor, + elevation: 0.0, + centerTitle: true, + leading: IconButton( + color: Theme.of(context).iconTheme.color, + icon: const Icon(Icons.menu), + onPressed: () { + MainScreenViewModel.scaffoldKey.currentState!.openDrawer(); + }, + ), + key: const Key("ProfilePageAppBar"), + title: Text( + AppLocalizations.of(context)!.strictTranslate('Profile'), + style: Theme.of(context).textTheme.titleLarge!.copyWith( + // fontWeight: FontWeight.w600, + fontSize: 20, + fontFamily: 'open-sans', + color: Colors.white, + ), + ), + actions: [ + Container(), + ], + ), + // if data fetching is under process then renders Circular Progress Icon + // else renders the widget. + body: guestViewWidget(context), + ); + } + + /// guestViewWidget, this widget is shown if user is not logged in. + /// + /// **params**: + /// * `context`: Build context to perform context related operation + /// + /// **returns**: + /// * `Widget`: Widget + Widget guestViewWidget(BuildContext context) { + return SingleChildScrollView( + child: Column( + children: [ + SizedBox( + height: SizeConfig.screenHeight! * 0.01, + ), + Row( + children: [ + Expanded( + flex: 1, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: CustomAvatar( + isImageNull: true, + firstAlphabet: "U", + imageUrl: null, + fontSize: Theme.of(context).textTheme.titleLarge!.fontSize, + maxRadius: 30, + ), + ), + ), + const Expanded( + flex: 3, + child: Padding( + padding: EdgeInsets.all(8.0), + child: Text( + 'User', + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontFamily: 'open-sans', + ), + ), + ), + ), + // Expanded( + // flex: 1, + // child: IconButton( + // icon: Icon( + // Icons.share, + // color: + // Theme.of(context).colorScheme.secondary, + // ), + // onPressed: () => model.invite(context), + // ), + // ), + ], + ), + const SizedBox( + height: 20, + ), + RaisedRoundedButton( + key: homeModel!.keySPDonateUs, + buttonLabel: AppLocalizations.of(context)!.strictTranslate( + 'Donate to the Community', + ), + onTap: () { + MainScreenViewModel.scaffoldKey.currentState?.openDrawer(); + }, + textColor: Theme.of(context) + .inputDecorationTheme + .focusedBorder! + .borderSide + .color, + backgroundColor: Theme.of(context).colorScheme.secondaryContainer, + ), + SizedBox( + height: 600, + width: double.infinity, + child: ContainedTabBarView( + tabs: [ + const Tab(text: 'Posts'), + const Tab(text: 'Events'), + const Tab(text: 'Tasks'), + ], + views: [ + ColoredBox( + color: Theme.of(context).colorScheme.background, + child: GridView.count( + mainAxisSpacing: 5, + crossAxisCount: 3, + children: [ + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), + Image.asset('assets/images/pfp2.png'), + ], + ), + ), + Container( + color: Theme.of(context).colorScheme.background, + ), + Container( + color: Theme.of(context).colorScheme.onPrimary, + ), + ], + ), + ), + SizedBox( + height: SizeConfig.screenHeight! * 0.67, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: SizeConfig.screenHeight! * 0.01, + ), + SizedBox( + height: SizeConfig.screenHeight! * 0.05, + ), + + /// `Donation` acts as plugin. If visible is true the it will be always visible. + /// even if it's uninstalled by the admin (for development purposes) + //TODO: custom tile for Invitation. + // CustomListTile( + // key: homeModel!.keySPInvite, + // index: 3, + // type: TileType.option, + // option: Options( + // icon: Icon( + // Icons.share, + // color: + // Theme.of(context).colorScheme.secondary, + // size: 30, + // ), + // // title + // title: AppLocalizations.of(context)! + // .strictTranslate('Invite'), + // // subtitle + // subtitle: AppLocalizations.of(context)! + // .strictTranslate('Invite to org'), + // ), + // // on tap call the invite function + // onTapOption: () => model.invite(context), + // ), + SizedBox( + height: SizeConfig.screenHeight! * 0.05, + ), + // Custom tile for Logout option. + //TODO: logout + // CustomListTile( + // key: homeModel!.keySPLogout, + // index: 3, + // type: TileType.option, + // option: Options( + // icon: Icon( + // Icons.logout, + // color: + // Theme.of(context).colorScheme.secondary, + // size: 30, + // ), + // title: AppLocalizations.of(context)! + // .strictTranslate('Log out'), + // subtitle: AppLocalizations.of(context)! + // .strictTranslate('Log out from Talawa'), + // ), + // // on tap calls the logout function + // onTapOption: () => model.logout(context), + // ), + SizedBox( + height: SizeConfig.screenHeight! * 0.05, + ), + FromPalisadoes(key: homeModel!.keySPPalisadoes), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/views/main_screen.dart b/lib/views/main_screen.dart index 204d5fdf4..52a8c6a05 100644 --- a/lib/views/main_screen.dart +++ b/lib/views/main_screen.dart @@ -1,14 +1,17 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - import 'package:flutter/material.dart'; +import 'package:talawa/constants/routing_constants.dart'; +import 'package:talawa/locator.dart'; import 'package:talawa/models/mainscreen_navigation_args.dart'; +import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/view_model/main_screen_view_model.dart'; import 'package:talawa/views/base_view.dart'; import 'package:talawa/widgets/custom_drawer.dart'; +/// This widget is responsible for displaying the main screen of the application. class MainScreen extends StatefulWidget { const MainScreen({super.key, required this.mainScreenArgs}); + + /// Holds data for the MainScreenArgs model, providing information to MainScreen. final MainScreenArgs mainScreenArgs; @override @@ -24,22 +27,70 @@ class _MainScreenState extends State { context, fromSignUp: widget.mainScreenArgs.fromSignUp, mainScreenIndex: widget.mainScreenArgs.mainScreenIndex, + demoMode: widget.mainScreenArgs.toggleDemoMode, ); }, builder: (context, model, child) { // Checks for updates in plugins from the server. // Will continously hit the server and fetch plugin information. model.fetchAndAddPlugins(context); - return Scaffold( key: MainScreenViewModel.scaffoldKey, drawer: CustomDrawer( homeModel: model, key: const Key("Custom Drawer"), ), - body: IndexedStack( - index: model.currentPageIndex, - children: model.pages, + body: Stack( + children: [ + IndexedStack( + index: model.currentPageIndex, + children: model.pages, + ), + widget.mainScreenArgs.toggleDemoMode + ? Positioned( + bottom: 0, // Adjust this value as per your UI + left: 0, + right: 0, + child: InkWell( + key: const Key('banner'), + onTap: () => navigationService + .pushScreen(Routes.setUrlScreen, arguments: ''), + child: Container( + height: 30.0, // Set the desired height of the banner + color: Theme.of(context) + .canvasColor, // Change color as needed + child: Center( + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: AppLocalizations.of(context)! + .strictTranslate( + 'For complete access, please', + ), + style: + Theme.of(context).textTheme.bodySmall, + ), + TextSpan( + text: AppLocalizations.of(context)! + .strictTranslate( + ' join an organization.', + ), + style: TextStyle( + color: Theme.of(context) + .colorScheme + .secondary, + ), + ), + ], + ), + ), + ), + ), + ), + ) + : Container(), + ], ), bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, diff --git a/lib/views/pre_auth_screens/select_language.dart b/lib/views/pre_auth_screens/select_language.dart index e0bd6c297..ef71ca2b1 100644 --- a/lib/views/pre_auth_screens/select_language.dart +++ b/lib/views/pre_auth_screens/select_language.dart @@ -1,6 +1,3 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:talawa/constants/constants.dart'; @@ -9,6 +6,7 @@ import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/view_model/lang_view_model.dart'; /// This widget enables us to select a different language. +/// /// The default language is English. We can choose among the options to switch the language. /// There is a text button at the right bottom of the screen which changes the language when tapped. /// The user finally gets redirected to the previous screen. @@ -139,7 +137,7 @@ class _SelectLanguageState extends State { height: SizeConfig.screenHeight! * 0.08, alignment: Alignment.centerRight, child: TextButton( - key: const Key('NavigateToUrlPage'), + key: const Key('NavigateToMainScreen'), onPressed: () async { Provider.of(context, listen: false) .selectLanguagePress(); diff --git a/lib/views/pre_auth_screens/set_url.dart b/lib/views/pre_auth_screens/set_url.dart index b13222ef2..5886b7832 100644 --- a/lib/views/pre_auth_screens/set_url.dart +++ b/lib/views/pre_auth_screens/set_url.dart @@ -30,6 +30,7 @@ class SetUrl extends StatefulWidget { class _SetUrlState extends State { @override Widget build(BuildContext context) { + print("built"); return BaseView( onModelReady: (model) => model.initialise(inviteUrl: widget.uri), builder: (context, model, child) { @@ -107,7 +108,7 @@ class _SetUrlState extends State { .translate(Validator.validateURL(value)), decoration: InputDecoration( labelText: - '${AppLocalizations.of(context)!.translate("Enter Organization URL")} *', + '${AppLocalizations.of(context)!.translate("Enter Community URL")} *', labelStyle: Theme.of(context).textTheme.titleMedium, suffixIcon: InkWell( key: const Key('VerifyButton'), diff --git a/lib/widgets/custom_alert_dialog.dart b/lib/widgets/custom_alert_dialog.dart index d9210a847..e6cc779e8 100644 --- a/lib/widgets/custom_alert_dialog.dart +++ b/lib/widgets/custom_alert_dialog.dart @@ -1,5 +1,4 @@ -// ignore_for_file: talawa_api_doc, avoid_dynamic_calls -// ignore_for_file: talawa_good_doc_comments +// ignore_for_file: avoid_dynamic_calls import 'package:flutter/material.dart'; import 'package:talawa/locator.dart'; @@ -7,11 +6,22 @@ import 'package:talawa/services/size_config.dart'; import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/widgets/raised_round_edge_button.dart'; -/// This Class returns CustomAlertDialog widget. Custom Alert Dialog is a popup +/// This Class returns CustomAlertDialog widget. Custom Alert Dialog is a popup. +/// /// that appeared in the screen showing Alert message along with the event buttons. /// This extends stateless widget that means it cannot change its state during the /// runtime of a application. class CustomAlertDialog extends StatelessWidget { + /// Constructs a [CustomAlertDialog] widget. + /// + /// [reverse] indicates whether the order of action buttons should be reversed. + /// [success] is the function triggered upon tapping the primary action button. + /// [secondaryButtonTap] is the function triggered upon tapping the secondary action button. + /// [successText] is the text displayed on the primary action button. + /// [dialogTitle] is the title displayed in the dialog (default value is 'Confirmation'). + /// [dialogSubTitle] is the subtitle or message content of the dialog. + /// [secondaryButtonText] is the text displayed on the secondary action button (default value is 'Close'). + const CustomAlertDialog({ super.key, this.successText, @@ -22,12 +32,26 @@ class CustomAlertDialog extends StatelessWidget { required this.success, required this.dialogSubTitle, }); + + /// Indicates whether the order of action buttons should be reversed. final bool reverse; + + /// Function triggered upon tapping the primary action button. final Function success; + + /// Function triggered upon tapping the secondary action button. final Function? secondaryButtonTap; + + /// Text displayed on the primary action button. final String? successText; + + /// Title displayed in the dialog (default value is 'Confirmation'). final String? dialogTitle; + + /// Subtitle or message content of the dialog. final String dialogSubTitle; + + /// Text displayed on the secondary action button (default value is 'Close'). final String secondaryButtonText; @override @@ -35,7 +59,11 @@ class CustomAlertDialog extends StatelessWidget { final List actions = [ RaisedRoundedButton( key: const Key('Close'), - onTap: () => secondaryButtonTap ?? navigationService.pop(), + onTap: () { + secondaryButtonTap != null + ? secondaryButtonTap!() + : navigationService.pop(); + }, buttonLabel: AppLocalizations.of(context)!.strictTranslate(secondaryButtonText), textColor: Colors.white, diff --git a/lib/widgets/custom_drawer.dart b/lib/widgets/custom_drawer.dart index aee5ab526..2c5d1f8bb 100644 --- a/lib/widgets/custom_drawer.dart +++ b/lib/widgets/custom_drawer.dart @@ -111,12 +111,24 @@ class CustomDrawer extends StatelessWidget { ), ], ), + const Divider(), // A Tile to join a new organization ListTile( key: MainScreenViewModel.keyDrawerJoinOrg, - onTap: () => navigationService - .popAndPushScreen(Routes.joinOrg, arguments: '-1'), + onTap: () { + if (userConfig.loggedIn) { + navigationService.popAndPushScreen( + Routes.joinOrg, + arguments: '-1', + ); + } else { + navigationService.popAndPushScreen( + Routes.setUrlScreen, + arguments: '', + ); + } + }, leading: const Icon( Icons.add, size: 30, @@ -126,15 +138,18 @@ class CustomDrawer extends StatelessWidget { .strictTranslate("Join new Organization"), ), ), - ListTile( - key: MainScreenViewModel.keyDrawerLeaveCurrentOrg, - onTap: () => exitButton(), - leading: const Icon(Icons.logout, size: 30), - title: Text( - AppLocalizations.of(context)! - .strictTranslate("Leave Current Organization"), - ), - ), + userConfig.loggedIn + ? ListTile( + key: MainScreenViewModel.keyDrawerLeaveCurrentOrg, + onTap: () => exitButton(), + leading: const Icon(Icons.logout, size: 30), + title: Text( + AppLocalizations.of(context)!.strictTranslate( + "Leave Current Organization", + ), + ), + ) + : Container(), SizedBox( key: const Key("Sized Box Drawer"), height: SizeConfig.screenHeight! * 0.03, diff --git a/lib/widgets/event_card.dart b/lib/widgets/event_card.dart index ded310471..b6566c53e 100644 --- a/lib/widgets/event_card.dart +++ b/lib/widgets/event_card.dart @@ -1,6 +1,3 @@ -// ignore_for_file: talawa_api_doc -// ignore_for_file: talawa_good_doc_comments - import 'dart:math'; import 'dart:ui'; import 'package:flutter/material.dart'; @@ -18,11 +15,19 @@ class EventCard extends StatelessWidget { this.eventTitleNormalText, required this.isSearchItem, }); - // variables + + /// instance of an event. final Event event; + + /// Highlighted text of the event. final String? eventTitleHighlightedText; + + /// Eventtile normal text. final String? eventTitleNormalText; + + /// This flag indicates that if this event is searchable. final bool isSearchItem; + @override Widget build(BuildContext context) { final bool isRegistered = event.isRegistered ?? false; @@ -54,9 +59,7 @@ class EventCard extends StatelessWidget { image: const DecorationImage( fit: BoxFit.fitWidth, alignment: FractionalOffset.topCenter, - image: NetworkImage( - 'https://picsum.photos/id/1022/200/300', - ), + image: AssetImage('assets/images/pfp2.png'), ), ), child: ClipRRect( @@ -117,9 +120,11 @@ class EventCard extends StatelessWidget { size: 13, ), const Spacer(), - Text( - "${event.startDate!} - ${event.endDate!}", - style: Theme.of(context).textTheme.bodySmall, + Expanded( + child: Text( + "${event.startDate!} - ${event.endDate!}", + style: Theme.of(context).textTheme.bodySmall, + ), ), ], ), diff --git a/lib/widgets/pinned_post.dart b/lib/widgets/pinned_post.dart index 16a77aef0..c442a3585 100644 --- a/lib/widgets/pinned_post.dart +++ b/lib/widgets/pinned_post.dart @@ -2,18 +2,22 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:talawa/models/post/post_model.dart'; import 'package:talawa/services/size_config.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; import 'package:talawa/views/after_auth_screens/feed/pinned_post_screen.dart'; /// a_line_ending_with_end_punctuation. /// /// more_info_if_required class PinnedPost extends StatelessWidget { - const PinnedPost({super.key, required this.pinnedPost}); + const PinnedPost({super.key, required this.pinnedPost, required this.model}); /// contains the pinned post. /// final List pinnedPost; + /// gives access mainScreenViewModel's attributes. + final MainScreenViewModel model; + @override Widget build(BuildContext context) { return Container( @@ -26,6 +30,7 @@ class PinnedPost extends StatelessWidget { shrinkWrap: true, scrollDirection: Axis.horizontal, itemBuilder: (context, index) => Padding( + key: index == 0 ? model.keySHPinnedPost : const Key(''), padding: const EdgeInsets.only( left: 10, top: 7, diff --git a/lib/widgets/talawa_error_dialog.dart b/lib/widgets/talawa_error_dialog.dart index 7b0e0be8e..f7a252467 100644 --- a/lib/widgets/talawa_error_dialog.dart +++ b/lib/widgets/talawa_error_dialog.dart @@ -22,12 +22,15 @@ class TalawaErrorDialog extends StatelessWidget { @override Widget build(BuildContext context) { + final screenWidth = MediaQuery.of(context).size.width; return SizedBox( + width: screenWidth * 0.8, // Adjust the width based on screen size child: AlertDialog( content: SizedBox( width: SizeConfig.screenWidth! * 0.65, height: SizeConfig.screenWidth! * 0.38, child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( messageType == MessageType.error @@ -70,7 +73,8 @@ class TalawaErrorDialog extends StatelessWidget { : messageType == MessageType.info ? Colors.green : Colors.red, - fontSize: 20, + fontSize: screenWidth * + 0.04, // Adjust the font size based on screen width ), textAlign: TextAlign.center, ), @@ -91,8 +95,6 @@ class TalawaErrorDialog extends StatelessWidget { ), ), actions: [ - // Expanded( - // child: TextButton( style: TextButton.styleFrom( backgroundColor: messageType == MessageType.error @@ -118,7 +120,6 @@ class TalawaErrorDialog extends StatelessWidget { Navigator.of(context).pop(); }, ), - // ), ], ), ); diff --git a/pubspec.lock b/pubspec.lock index b296a8328..84599fbfb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1835,4 +1835,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.2.0-194.0.dev <3.13.0" - flutter: ">=3.13.0" + flutter: ">=3.13.0" \ No newline at end of file diff --git a/test/helpers/test_helpers.dart b/test/helpers/test_helpers.dart index 55e967133..6bafa6645 100644 --- a/test/helpers/test_helpers.dart +++ b/test/helpers/test_helpers.dart @@ -53,6 +53,7 @@ import 'package:talawa/view_model/theme_view_model.dart'; import 'package:talawa/view_model/widgets_view_models/custom_drawer_view_model.dart'; import 'package:talawa/view_model/widgets_view_models/like_button_view_model.dart'; import 'package:talawa/view_model/widgets_view_models/progress_dialog_view_model.dart'; +import '../views/main_screen_test.dart'; import 'test_helpers.mocks.dart'; @GenerateMocks( @@ -126,6 +127,7 @@ NavigationService getAndRegisterNavigationService() { when(service.pushScreen(any, arguments: anyNamed('arguments'))) .thenAnswer((_) async {}); when(service.popAndPushScreen(any, arguments: '-1')).thenAnswer((_) async {}); + when(service.pushDialog(any)).thenAnswer((_) async {}); locator.registerSingleton(service); return service; } @@ -204,6 +206,9 @@ ChatService getAndRegisterChatService() { AppLanguage getAndRegisterAppLanguage() { _removeRegistrationIfExists(); final service = MockAppLanguage(); + + when(service.appLocal).thenReturn(const Locale('en')); + locator.registerSingleton(service); return service; } @@ -314,6 +319,14 @@ UserConfig getAndRegisterUserConfig() { (realInvocation) => Future.value(false), ); + when(service.currentUser).thenReturn( + User( + id: 'id', + firstName: 'john', + lastName: 'snow', + ), + ); + //Mock Data for current organizaiton. when(service.currentOrg).thenReturn( OrgInfo( @@ -565,7 +578,7 @@ CreateEventViewModel getAndRegisterCreateEventModel() { id: "fakeUser1", firstName: 'r', lastName: 'p', - image: 'www.image.com', + // image: 'www.image.com', ); final mapType = {user1.id!: true}; @@ -586,6 +599,10 @@ CreateEventViewModel getAndRegisterCreateEventModel() { when(cachedViewModel.selectedMembers).thenReturn([]); }); + when(cachedViewModel.createEvent()).thenAnswer((realInvocation) async { + print('called'); + }); + // when(cachedViewModel.removeUserFromList(userId: "fakeUser2")) // .thenAnswer((realInvocation) async { // when(cachedViewModel.selectedAdmins).thenReturn([]); @@ -633,6 +650,31 @@ DirectChatViewModel getAndRegisterDirectChatViewModel() { return cachedViewModel; } +ExploreEventsViewModel getAndRegisterExploreEventsViewModel() { + _removeRegistrationIfExists(); + final cachedViewModel = MockExploreEventsViewModel(); + + const String chosenValue = 'All Events'; + const String emptyListMessage = "Looks like there aren't any events."; + + final EventService mockEventService = EventService(); + + when(cachedViewModel.eventService).thenReturn(mockEventService); + when(cachedViewModel.chosenValue).thenReturn(chosenValue); + when(cachedViewModel.emptyListMessage).thenReturn(emptyListMessage); + + locator.registerSingleton(cachedViewModel); + return cachedViewModel; +} + +MainScreenViewModel getAndRegisterMainViewModel() { + _removeRegistrationIfExists(); + final cachedViewModel = MockMainScreenViewModel(); + + locator.registerSingleton(cachedViewModel); + return cachedViewModel; +} + void registerServices() { getAndRegisterNavigationService(); getAndRegisterAppLanguage(); diff --git a/test/helpers/test_helpers.mocks.dart b/test/helpers/test_helpers.mocks.dart index 055d9bad0..a5557bb59 100644 --- a/test/helpers/test_helpers.mocks.dart +++ b/test/helpers/test_helpers.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.3.2 from annotations +// Mocks generated by Mockito 5.4.3 from annotations // in talawa/test/helpers/test_helpers.dart. // Do not manually edit this file. @@ -7,17 +7,18 @@ import 'dart:async' as _i4; import 'dart:io' as _i18; import 'dart:ui' as _i9; -import 'package:connectivity_plus/connectivity_plus.dart' as _i25; +import 'package:connectivity_plus/connectivity_plus.dart' as _i26; import 'package:connectivity_plus_platform_interface/connectivity_plus_platform_interface.dart' - as _i26; + as _i27; import 'package:flutter/material.dart' as _i1; import 'package:graphql_flutter/graphql_flutter.dart' as _i3; -import 'package:image_cropper/image_cropper.dart' as _i40; +import 'package:image_cropper/image_cropper.dart' as _i41; import 'package:image_picker/image_picker.dart' as _i12; import 'package:mockito/mockito.dart' as _i2; -import 'package:qr_code_scanner/src/qr_code_scanner.dart' as _i31; -import 'package:qr_code_scanner/src/types/barcode.dart' as _i32; -import 'package:qr_code_scanner/src/types/camera.dart' as _i33; +import 'package:mockito/src/dummies.dart' as _i24; +import 'package:qr_code_scanner/src/qr_code_scanner.dart' as _i32; +import 'package:qr_code_scanner/src/types/barcode.dart' as _i33; +import 'package:qr_code_scanner/src/types/camera.dart' as _i34; import 'package:qr_code_scanner/src/types/features.dart' as _i11; import 'package:talawa/enums/enums.dart' as _i13; import 'package:talawa/models/chats/chat_list_tile_data_model.dart' as _i21; @@ -25,36 +26,38 @@ import 'package:talawa/models/chats/chat_message.dart' as _i22; import 'package:talawa/models/events/event_model.dart' as _i19; import 'package:talawa/models/organization/org_info.dart' as _i5; import 'package:talawa/models/post/post_model.dart' as _i16; -import 'package:talawa/models/task/task_model.dart' as _i37; +import 'package:talawa/models/task/task_model.dart' as _i38; import 'package:talawa/models/user/user_info.dart' as _i6; import 'package:talawa/services/chat_service.dart' as _i20; -import 'package:talawa/services/comment_service.dart' as _i34; +import 'package:talawa/services/comment_service.dart' as _i35; import 'package:talawa/services/database_mutation_functions.dart' as _i8; import 'package:talawa/services/event_service.dart' as _i10; import 'package:talawa/services/graphql_config.dart' as _i14; import 'package:talawa/services/navigation_service.dart' as _i7; -import 'package:talawa/services/org_service.dart' as _i28; +import 'package:talawa/services/org_service.dart' as _i29; import 'package:talawa/services/post_service.dart' as _i15; -import 'package:talawa/services/task_service.dart' as _i36; +import 'package:talawa/services/task_service.dart' as _i37; import 'package:talawa/services/third_party_service/multi_media_pick_service.dart' as _i17; import 'package:talawa/services/user_config.dart' as _i23; -import 'package:talawa/utils/validators.dart' as _i30; +import 'package:talawa/utils/validators.dart' as _i31; import 'package:talawa/view_model/after_auth_view_models/chat_view_models/direct_chat_view_model.dart' - as _i39; + as _i40; import 'package:talawa/view_model/after_auth_view_models/event_view_models/create_event_view_model.dart' - as _i38; + as _i39; import 'package:talawa/view_model/after_auth_view_models/event_view_models/explore_events_view_model.dart' - as _i29; -import 'package:talawa/view_model/lang_view_model.dart' as _i24; + as _i30; +import 'package:talawa/view_model/lang_view_model.dart' as _i25; import 'package:talawa/view_model/pre_auth_view_models/signup_details_view_model.dart' - as _i27; -import 'package:talawa/view_model/theme_view_model.dart' as _i35; + as _i28; +import 'package:talawa/view_model/theme_view_model.dart' as _i36; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -144,8 +147,8 @@ class _FakeQueryManager_7 extends _i2.SmartFake implements _i3.QueryManager { ); } -class _FakeObservableQuery_8 extends _i2.SmartFake - implements _i3.ObservableQuery { +class _FakeObservableQuery_8 extends _i2.SmartFake + implements _i3.ObservableQuery { _FakeObservableQuery_8( Object parent, Invocation parentInvocation, @@ -155,8 +158,8 @@ class _FakeObservableQuery_8 extends _i2.SmartFake ); } -class _FakeQueryResult_9 extends _i2.SmartFake - implements _i3.QueryResult { +class _FakeQueryResult_9 extends _i2.SmartFake + implements _i3.QueryResult { _FakeQueryResult_9( Object parent, Invocation parentInvocation, @@ -305,19 +308,9 @@ class _FakeDateTime_22 extends _i2.SmartFake implements DateTime { ); } -class _FakeLostData_23 extends _i2.SmartFake implements _i12.LostData { - _FakeLostData_23( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeLostDataResponse_24 extends _i2.SmartFake +class _FakeLostDataResponse_23 extends _i2.SmartFake implements _i12.LostDataResponse { - _FakeLostDataResponse_24( + _FakeLostDataResponse_23( Object parent, Invocation parentInvocation, ) : super( @@ -342,6 +335,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { Invocation.getter(#navigatorKey), ), ) as _i1.GlobalKey<_i1.NavigatorState>); + @override set navigatorKey(_i1.GlobalKey<_i1.NavigatorState>? _navigatorKey) => super.noSuchMethod( @@ -351,6 +345,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { ), returnValueForMissingStub: null, ); + @override _i4.Future pushScreen( String? routeName, { @@ -365,6 +360,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future popAndPushScreen( String? routeName, { @@ -379,6 +375,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future pushReplacementScreen( String? routeName, { @@ -393,21 +390,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); - @override - void fromInviteLink( - List? routeNames, - List? arguments, - ) => - super.noSuchMethod( - Invocation.method( - #fromInviteLink, - [ - routeNames, - arguments, - ], - ), - returnValueForMissingStub: null, - ); + @override _i4.Future removeAllAndPush( String? routeName, @@ -426,6 +409,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void pushDialog(_i1.Widget? dialog) => super.noSuchMethod( Invocation.method( @@ -434,6 +418,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { ), returnValueForMissingStub: null, ); + @override void showSnackBar( String? message, { @@ -447,6 +432,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { ), returnValueForMissingStub: null, ); + @override void showTalawaErrorSnackBar( String? errorMessage, @@ -464,6 +450,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { ), returnValueForMissingStub: null, ); + @override void showTalawaErrorDialog( String? errorMessage, @@ -479,6 +466,7 @@ class MockNavigationService extends _i2.Mock implements _i7.NavigationService { ), returnValueForMissingStub: null, ); + @override void pop() => super.noSuchMethod( Invocation.method( @@ -505,6 +493,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { Invocation.getter(#httpLink), ), ) as _i3.HttpLink); + @override set httpLink(_i3.HttpLink? _httpLink) => super.noSuchMethod( Invocation.setter( @@ -513,6 +502,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { ), returnValueForMissingStub: null, ); + @override _i3.WebSocketLink get webSocketLink => (super.noSuchMethod( Invocation.getter(#webSocketLink), @@ -525,6 +515,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { Invocation.getter(#webSocketLink), ), ) as _i3.WebSocketLink); + @override set webSocketLink(_i3.WebSocketLink? _webSocketLink) => super.noSuchMethod( Invocation.setter( @@ -533,6 +524,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { ), returnValueForMissingStub: null, ); + @override set displayImgRoute(String? _displayImgRoute) => super.noSuchMethod( Invocation.setter( @@ -541,6 +533,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { ), returnValueForMissingStub: null, ); + @override _i4.Future getToken() => (super.noSuchMethod( Invocation.method( @@ -550,6 +543,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void getOrgUrl() => super.noSuchMethod( Invocation.method( @@ -558,6 +552,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { ), returnValueForMissingStub: null, ); + @override _i3.GraphQLClient clientToQuery() => (super.noSuchMethod( Invocation.method( @@ -579,6 +574,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { ), ), ) as _i3.GraphQLClient); + @override _i3.GraphQLClient authClient() => (super.noSuchMethod( Invocation.method( @@ -600,6 +596,7 @@ class MockGraphqlConfig extends _i2.Mock implements _i14.GraphqlConfig { ), ), ) as _i3.GraphQLClient); + @override void test() => super.noSuchMethod( Invocation.method( @@ -626,6 +623,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { Invocation.getter(#defaultPolicies), ), ) as _i3.DefaultPolicies); + @override set defaultPolicies(_i3.DefaultPolicies? _defaultPolicies) => super.noSuchMethod( @@ -635,6 +633,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), returnValueForMissingStub: null, ); + @override _i3.Link get link => (super.noSuchMethod( Invocation.getter(#link), @@ -647,6 +646,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { Invocation.getter(#link), ), ) as _i3.Link); + @override _i3.GraphQLCache get cache => (super.noSuchMethod( Invocation.getter(#cache), @@ -659,6 +659,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { Invocation.getter(#cache), ), ) as _i3.GraphQLCache); + @override _i3.QueryManager get queryManager => (super.noSuchMethod( Invocation.getter(#queryManager), @@ -671,6 +672,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { Invocation.getter(#queryManager), ), ) as _i3.QueryManager); + @override set queryManager(_i3.QueryManager? _queryManager) => super.noSuchMethod( Invocation.setter( @@ -679,6 +681,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), returnValueForMissingStub: null, ); + @override _i3.GraphQLClient copyWith({ _i3.Link? link, @@ -724,6 +727,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), ), ) as _i3.GraphQLClient); + @override _i3.ObservableQuery watchQuery( _i3.WatchQueryOptions? options) => @@ -747,6 +751,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), ), ) as _i3.ObservableQuery); + @override _i3.ObservableQuery watchMutation( _i3.WatchQueryOptions? options) => @@ -770,6 +775,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), ), ) as _i3.ObservableQuery); + @override _i4.Future<_i3.QueryResult> query( _i3.QueryOptions? options) => @@ -795,6 +801,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), )), ) as _i4.Future<_i3.QueryResult>); + @override _i4.Future<_i3.QueryResult> mutate( _i3.MutationOptions? options) => @@ -820,6 +827,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), )), ) as _i4.Future<_i3.QueryResult>); + @override _i4.Stream<_i3.QueryResult> subscribe( _i3.SubscriptionOptions? options) => @@ -831,6 +839,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { returnValue: _i4.Stream<_i3.QueryResult>.empty(), returnValueForMissingStub: _i4.Stream<_i3.QueryResult>.empty(), ) as _i4.Stream<_i3.QueryResult>); + @override _i4.Future<_i3.QueryResult> fetchMore( _i3.FetchMoreOptions? fetchMoreOptions, { @@ -871,6 +880,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), )), ) as _i4.Future<_i3.QueryResult>); + @override Map? readQuery( _i3.Request? request, { @@ -884,6 +894,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), returnValueForMissingStub: null, ) as Map?); + @override Map? readFragment( _i3.FragmentRequest? fragmentRequest, { @@ -897,6 +908,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), returnValueForMissingStub: null, ) as Map?); + @override void writeQuery( _i3.Request? request, { @@ -914,6 +926,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), returnValueForMissingStub: null, ); + @override void writeFragment( _i3.FragmentRequest? fragmentRequest, { @@ -931,6 +944,7 @@ class MockGraphQLClient extends _i2.Mock implements _i3.GraphQLClient { ), returnValueForMissingStub: null, ); + @override _i4.Future?>>? resetStore( {bool? refetchQueries = true}) => @@ -954,12 +968,14 @@ class MockPostService extends _i2.Mock implements _i15.PostService { returnValue: _i4.Stream>.empty(), returnValueForMissingStub: _i4.Stream>.empty(), ) as _i4.Stream>); + @override _i4.Stream<_i16.Post> get updatedPostStream => (super.noSuchMethod( Invocation.getter(#updatedPostStream), returnValue: _i4.Stream<_i16.Post>.empty(), returnValueForMissingStub: _i4.Stream<_i16.Post>.empty(), ) as _i4.Stream<_i16.Post>); + @override void setOrgStreamSubscription() => super.noSuchMethod( Invocation.method( @@ -968,6 +984,7 @@ class MockPostService extends _i2.Mock implements _i15.PostService { ), returnValueForMissingStub: null, ); + @override _i4.Future getPosts() => (super.noSuchMethod( Invocation.method( @@ -977,6 +994,7 @@ class MockPostService extends _i2.Mock implements _i15.PostService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future addLike(String? postID) => (super.noSuchMethod( Invocation.method( @@ -986,6 +1004,7 @@ class MockPostService extends _i2.Mock implements _i15.PostService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future removeLike(String? postID) => (super.noSuchMethod( Invocation.method( @@ -995,6 +1014,7 @@ class MockPostService extends _i2.Mock implements _i15.PostService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addCommentLocally(String? postID) => super.noSuchMethod( Invocation.method( @@ -1016,6 +1036,7 @@ class MockMultiMediaPickerService extends _i2.Mock returnValue: _i4.Stream.empty(), returnValueForMissingStub: _i4.Stream.empty(), ) as _i4.Stream); + @override _i4.Future<_i18.File?> getPhotoFromGallery({bool? camera = false}) => (super.noSuchMethod( @@ -1027,6 +1048,7 @@ class MockMultiMediaPickerService extends _i2.Mock returnValue: _i4.Future<_i18.File?>.value(), returnValueForMissingStub: _i4.Future<_i18.File?>.value(), ) as _i4.Future<_i18.File?>); + @override _i4.Future<_i18.File?> cropImage({required _i18.File? imageFile}) => (super.noSuchMethod( @@ -1050,6 +1072,7 @@ class MockEventService extends _i2.Mock implements _i10.EventService { returnValue: _i4.Stream<_i19.Event>.empty(), returnValueForMissingStub: _i4.Stream<_i19.Event>.empty(), ) as _i4.Stream<_i19.Event>); + @override void setOrgStreamSubscription() => super.noSuchMethod( Invocation.method( @@ -1058,6 +1081,7 @@ class MockEventService extends _i2.Mock implements _i10.EventService { ), returnValueForMissingStub: null, ); + @override _i4.Future getEvents() => (super.noSuchMethod( Invocation.method( @@ -1067,6 +1091,7 @@ class MockEventService extends _i2.Mock implements _i10.EventService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future fetchRegistrantsByEvent(String? eventId) => (super.noSuchMethod( @@ -1077,6 +1102,7 @@ class MockEventService extends _i2.Mock implements _i10.EventService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future registerForAnEvent(String? eventId) => (super.noSuchMethod( @@ -1087,6 +1113,7 @@ class MockEventService extends _i2.Mock implements _i10.EventService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future deleteEvent(String? eventId) => (super.noSuchMethod( Invocation.method( @@ -1096,6 +1123,7 @@ class MockEventService extends _i2.Mock implements _i10.EventService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future editEvent({ required String? eventId, @@ -1113,6 +1141,7 @@ class MockEventService extends _i2.Mock implements _i10.EventService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1133,6 +1162,7 @@ class MockChatService extends _i2.Mock implements _i20.ChatService { returnValue: _i4.Stream<_i3.QueryResult>.empty(), returnValueForMissingStub: _i4.Stream<_i3.QueryResult>.empty(), ) as _i4.Stream<_i3.QueryResult>); + @override set chatStream(_i4.Stream<_i3.QueryResult>? _chatStream) => super.noSuchMethod( @@ -1142,6 +1172,7 @@ class MockChatService extends _i2.Mock implements _i20.ChatService { ), returnValueForMissingStub: null, ); + @override _i4.Stream<_i21.ChatListTileDataModel> get chatListStream => (super.noSuchMethod( @@ -1150,12 +1181,14 @@ class MockChatService extends _i2.Mock implements _i20.ChatService { returnValueForMissingStub: _i4.Stream<_i21.ChatListTileDataModel>.empty(), ) as _i4.Stream<_i21.ChatListTileDataModel>); + @override _i4.Stream<_i22.ChatMessage> get chatMessagesStream => (super.noSuchMethod( Invocation.getter(#chatMessagesStream), returnValue: _i4.Stream<_i22.ChatMessage>.empty(), returnValueForMissingStub: _i4.Stream<_i22.ChatMessage>.empty(), ) as _i4.Stream<_i22.ChatMessage>); + @override _i4.Future sendMessageToDirectChat( String? chatId, @@ -1172,6 +1205,7 @@ class MockChatService extends _i2.Mock implements _i20.ChatService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future getDirectChatsByUserId() => (super.noSuchMethod( Invocation.method( @@ -1181,6 +1215,7 @@ class MockChatService extends _i2.Mock implements _i20.ChatService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future getDirectChatMessagesByChatId(dynamic chatId) => (super.noSuchMethod( @@ -1203,6 +1238,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { returnValue: _i4.Stream<_i5.OrgInfo>.empty(), returnValueForMissingStub: _i4.Stream<_i5.OrgInfo>.empty(), ) as _i4.Stream<_i5.OrgInfo>); + @override _i4.StreamController<_i5.OrgInfo> get currentOrgInfoController => (super.noSuchMethod( @@ -1216,6 +1252,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { Invocation.getter(#currentOrgInfoController), ), ) as _i4.StreamController<_i5.OrgInfo>); + @override _i5.OrgInfo get currentOrg => (super.noSuchMethod( Invocation.getter(#currentOrg), @@ -1228,12 +1265,27 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { Invocation.getter(#currentOrg), ), ) as _i5.OrgInfo); + @override String get currentOrgName => (super.noSuchMethod( Invocation.getter(#currentOrgName), - returnValue: '', - returnValueForMissingStub: '', + returnValue: _i24.dummyValue( + this, + Invocation.getter(#currentOrgName), + ), + returnValueForMissingStub: _i24.dummyValue( + this, + Invocation.getter(#currentOrgName), + ), ) as String); + + @override + bool get loggedIn => (super.noSuchMethod( + Invocation.getter(#loggedIn), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + @override set currentOrg(_i5.OrgInfo? org) => super.noSuchMethod( Invocation.setter( @@ -1242,6 +1294,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { ), returnValueForMissingStub: null, ); + @override _i6.User get currentUser => (super.noSuchMethod( Invocation.getter(#currentUser), @@ -1254,6 +1307,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { Invocation.getter(#currentUser), ), ) as _i6.User); + @override set currentUser(_i6.User? user) => super.noSuchMethod( Invocation.setter( @@ -1262,6 +1316,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { ), returnValueForMissingStub: null, ); + @override void initialiseStream() => super.noSuchMethod( Invocation.method( @@ -1270,6 +1325,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { ), returnValueForMissingStub: null, ); + @override _i4.Future userLoggedIn() => (super.noSuchMethod( Invocation.method( @@ -1279,49 +1335,63 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { returnValue: _i4.Future.value(false), returnValueForMissingStub: _i4.Future.value(false), ) as _i4.Future); + + @override + _i4.Future userLogOut() => (super.noSuchMethod( + Invocation.method( + #userLogOut, + [], + ), + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); + @override - _i4.Future updateUserJoinedOrg(List<_i5.OrgInfo>? orgDetails) => + _i4.Future updateUserJoinedOrg(List<_i5.OrgInfo>? orgDetails) => (super.noSuchMethod( Invocation.method( #updateUserJoinedOrg, [orgDetails], ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + @override - _i4.Future updateUserCreatedOrg(List<_i5.OrgInfo>? orgDetails) => + _i4.Future updateUserCreatedOrg(List<_i5.OrgInfo>? orgDetails) => (super.noSuchMethod( Invocation.method( #updateUserCreatedOrg, [orgDetails], ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + @override - _i4.Future updateUserMemberRequestOrg( - List<_i5.OrgInfo>? orgDetails) => + _i4.Future updateUserMemberRequestOrg(List<_i5.OrgInfo>? orgDetails) => (super.noSuchMethod( Invocation.method( #updateUserMemberRequestOrg, [orgDetails], ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + @override - _i4.Future updateUserAdminOrg(List<_i5.OrgInfo>? orgDetails) => + _i4.Future updateUserAdminOrg(List<_i5.OrgInfo>? orgDetails) => (super.noSuchMethod( Invocation.method( #updateUserAdminOrg, [orgDetails], ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + @override - _i4.Future updateAccessToken({ + _i4.Future updateAccessToken({ required String? accessToken, required String? refreshToken, }) => @@ -1334,9 +1404,10 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { #refreshToken: refreshToken, }, ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + @override _i4.Future updateUser(_i6.User? updatedUserDetails) => (super.noSuchMethod( @@ -1347,6 +1418,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { returnValue: _i4.Future.value(false), returnValueForMissingStub: _i4.Future.value(false), ) as _i4.Future); + @override void saveUserInHive() => super.noSuchMethod( Invocation.method( @@ -1355,6 +1427,7 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { ), returnValueForMissingStub: null, ); + @override void saveCurrentOrgInHive(_i5.OrgInfo? saveOrgAsCurrent) => super.noSuchMethod( @@ -1369,13 +1442,14 @@ class MockUserConfig extends _i2.Mock implements _i23.UserConfig { /// A class which mocks [AppLanguage]. /// /// See the documentation for Mockito's code generation for more information. -class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { +class MockAppLanguage extends _i2.Mock implements _i25.AppLanguage { @override bool get isTest => (super.noSuchMethod( Invocation.getter(#isTest), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override _i7.NavigationService get navigationService => (super.noSuchMethod( Invocation.getter(#navigationService), @@ -1388,6 +1462,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { Invocation.getter(#navigationService), ), ) as _i7.NavigationService); + @override _i8.DataBaseMutationFunctions get databaseFunctions => (super.noSuchMethod( Invocation.getter(#databaseFunctions), @@ -1400,6 +1475,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { Invocation.getter(#databaseFunctions), ), ) as _i8.DataBaseMutationFunctions); + @override _i9.Locale get appLocal => (super.noSuchMethod( Invocation.getter(#appLocal), @@ -1412,24 +1488,28 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { Invocation.getter(#appLocal), ), ) as _i9.Locale); + @override _i13.ViewState get state => (super.noSuchMethod( Invocation.getter(#state), returnValue: _i13.ViewState.idle, returnValueForMissingStub: _i13.ViewState.idle, ) as _i13.ViewState); + @override bool get isBusy => (super.noSuchMethod( Invocation.getter(#isBusy), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override _i4.Future initialize() => (super.noSuchMethod( Invocation.method( @@ -1439,6 +1519,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future fetchLocale() => (super.noSuchMethod( Invocation.method( @@ -1448,6 +1529,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future changeLanguage(_i9.Locale? type) => (super.noSuchMethod( Invocation.method( @@ -1457,6 +1539,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future selectLanguagePress() => (super.noSuchMethod( Invocation.method( @@ -1466,6 +1549,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future dbLanguageUpdate() => (super.noSuchMethod( Invocation.method( @@ -1475,6 +1559,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future appLanguageQuery() => (super.noSuchMethod( Invocation.method( @@ -1484,6 +1569,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future userLanguageQuery(String? userId) => (super.noSuchMethod( Invocation.method( @@ -1493,6 +1579,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void setState(_i13.ViewState? viewState) => super.noSuchMethod( Invocation.method( @@ -1501,6 +1588,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { ), returnValueForMissingStub: null, ); + @override void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1509,6 +1597,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { ), returnValueForMissingStub: null, ); + @override void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1517,6 +1606,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1525,6 +1615,7 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -1538,33 +1629,34 @@ class MockAppLanguage extends _i2.Mock implements _i24.AppLanguage { /// A class which mocks [Connectivity]. /// /// See the documentation for Mockito's code generation for more information. -class MockConnectivity extends _i2.Mock implements _i25.Connectivity { +class MockConnectivity extends _i2.Mock implements _i26.Connectivity { @override - _i4.Stream<_i26.ConnectivityResult> get onConnectivityChanged => + _i4.Stream<_i27.ConnectivityResult> get onConnectivityChanged => (super.noSuchMethod( Invocation.getter(#onConnectivityChanged), - returnValue: _i4.Stream<_i26.ConnectivityResult>.empty(), - returnValueForMissingStub: _i4.Stream<_i26.ConnectivityResult>.empty(), - ) as _i4.Stream<_i26.ConnectivityResult>); + returnValue: _i4.Stream<_i27.ConnectivityResult>.empty(), + returnValueForMissingStub: _i4.Stream<_i27.ConnectivityResult>.empty(), + ) as _i4.Stream<_i27.ConnectivityResult>); + @override - _i4.Future<_i26.ConnectivityResult> checkConnectivity() => + _i4.Future<_i27.ConnectivityResult> checkConnectivity() => (super.noSuchMethod( Invocation.method( #checkConnectivity, [], ), - returnValue: _i4.Future<_i26.ConnectivityResult>.value( - _i26.ConnectivityResult.bluetooth), - returnValueForMissingStub: _i4.Future<_i26.ConnectivityResult>.value( - _i26.ConnectivityResult.bluetooth), - ) as _i4.Future<_i26.ConnectivityResult>); + returnValue: _i4.Future<_i27.ConnectivityResult>.value( + _i27.ConnectivityResult.bluetooth), + returnValueForMissingStub: _i4.Future<_i27.ConnectivityResult>.value( + _i27.ConnectivityResult.bluetooth), + ) as _i4.Future<_i27.ConnectivityResult>); } /// A class which mocks [SignupDetailsViewModel]. /// /// See the documentation for Mockito's code generation for more information. class MockSignupDetailsViewModel extends _i2.Mock - implements _i27.SignupDetailsViewModel { + implements _i28.SignupDetailsViewModel { @override _i1.GlobalKey<_i1.FormState> get formKey => (super.noSuchMethod( Invocation.getter(#formKey), @@ -1577,12 +1669,14 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#formKey), ), ) as _i1.GlobalKey<_i1.FormState>); + @override List> get greeting => (super.noSuchMethod( Invocation.getter(#greeting), returnValue: >[], returnValueForMissingStub: >[], ) as List>); + @override set greeting(List>? _greeting) => super.noSuchMethod( Invocation.setter( @@ -1591,6 +1685,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i5.OrgInfo get selectedOrganization => (super.noSuchMethod( Invocation.getter(#selectedOrganization), @@ -1603,6 +1698,7 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#selectedOrganization), ), ) as _i5.OrgInfo); + @override set selectedOrganization(_i5.OrgInfo? _selectedOrganization) => super.noSuchMethod( @@ -1612,6 +1708,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TextEditingController get confirmPassword => (super.noSuchMethod( Invocation.getter(#confirmPassword), @@ -1624,6 +1721,7 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#confirmPassword), ), ) as _i1.TextEditingController); + @override set confirmPassword(_i1.TextEditingController? _confirmPassword) => super.noSuchMethod( @@ -1633,6 +1731,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TextEditingController get firstName => (super.noSuchMethod( Invocation.getter(#firstName), @@ -1645,6 +1744,7 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#firstName), ), ) as _i1.TextEditingController); + @override set firstName(_i1.TextEditingController? _firstName) => super.noSuchMethod( Invocation.setter( @@ -1653,6 +1753,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TextEditingController get lastName => (super.noSuchMethod( Invocation.getter(#lastName), @@ -1665,6 +1766,7 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#lastName), ), ) as _i1.TextEditingController); + @override set lastName(_i1.TextEditingController? _lastName) => super.noSuchMethod( Invocation.setter( @@ -1673,6 +1775,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TextEditingController get password => (super.noSuchMethod( Invocation.getter(#password), @@ -1685,6 +1788,7 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#password), ), ) as _i1.TextEditingController); + @override set password(_i1.TextEditingController? _password) => super.noSuchMethod( Invocation.setter( @@ -1693,6 +1797,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TextEditingController get email => (super.noSuchMethod( Invocation.getter(#email), @@ -1705,6 +1810,7 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#email), ), ) as _i1.TextEditingController); + @override set email(_i1.TextEditingController? _email) => super.noSuchMethod( Invocation.setter( @@ -1713,12 +1819,14 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.AutovalidateMode get validate => (super.noSuchMethod( Invocation.getter(#validate), returnValue: _i1.AutovalidateMode.disabled, returnValueForMissingStub: _i1.AutovalidateMode.disabled, ) as _i1.AutovalidateMode); + @override set validate(_i1.AutovalidateMode? _validate) => super.noSuchMethod( Invocation.setter( @@ -1727,6 +1835,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.FocusNode get confirmFocus => (super.noSuchMethod( Invocation.getter(#confirmFocus), @@ -1739,6 +1848,7 @@ class MockSignupDetailsViewModel extends _i2.Mock Invocation.getter(#confirmFocus), ), ) as _i1.FocusNode); + @override set confirmFocus(_i1.FocusNode? _confirmFocus) => super.noSuchMethod( Invocation.setter( @@ -1747,12 +1857,14 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override bool get hidePassword => (super.noSuchMethod( Invocation.getter(#hidePassword), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override set hidePassword(bool? _hidePassword) => super.noSuchMethod( Invocation.setter( @@ -1761,24 +1873,28 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i13.ViewState get state => (super.noSuchMethod( Invocation.getter(#state), returnValue: _i13.ViewState.idle, returnValueForMissingStub: _i13.ViewState.idle, ) as _i13.ViewState); + @override bool get isBusy => (super.noSuchMethod( Invocation.getter(#isBusy), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override void initialise(_i5.OrgInfo? org) => super.noSuchMethod( Invocation.method( @@ -1787,6 +1903,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i4.Future signUp() => (super.noSuchMethod( Invocation.method( @@ -1796,6 +1913,7 @@ class MockSignupDetailsViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void setState(_i13.ViewState? viewState) => super.noSuchMethod( Invocation.method( @@ -1804,6 +1922,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1812,6 +1931,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1820,6 +1940,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1828,6 +1949,7 @@ class MockSignupDetailsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -1845,9 +1967,16 @@ class MockPost extends _i2.Mock implements _i16.Post { @override String get sId => (super.noSuchMethod( Invocation.getter(#sId), - returnValue: '', - returnValueForMissingStub: '', + returnValue: _i24.dummyValue( + this, + Invocation.getter(#sId), + ), + returnValueForMissingStub: _i24.dummyValue( + this, + Invocation.getter(#sId), + ), ) as String); + @override set sId(String? _sId) => super.noSuchMethod( Invocation.setter( @@ -1856,6 +1985,7 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override set description(String? _description) => super.noSuchMethod( Invocation.setter( @@ -1864,6 +1994,7 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override set createdAt(DateTime? _createdAt) => super.noSuchMethod( Invocation.setter( @@ -1872,6 +2003,7 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override set imageUrl(String? _imageUrl) => super.noSuchMethod( Invocation.setter( @@ -1880,6 +2012,16 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + + @override + set base64String(String? _base64String) => super.noSuchMethod( + Invocation.setter( + #base64String, + _base64String, + ), + returnValueForMissingStub: null, + ); + @override set videoUrl(String? _videoUrl) => super.noSuchMethod( Invocation.setter( @@ -1888,6 +2030,7 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override set creator(_i6.User? _creator) => super.noSuchMethod( Invocation.setter( @@ -1896,6 +2039,7 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override set organization(_i5.OrgInfo? _organization) => super.noSuchMethod( Invocation.setter( @@ -1904,6 +2048,7 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override set likedBy(List<_i16.LikedBy>? _likedBy) => super.noSuchMethod( Invocation.setter( @@ -1912,6 +2057,7 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override set comments(List<_i16.Comments>? _comments) => super.noSuchMethod( Invocation.setter( @@ -1920,14 +2066,27 @@ class MockPost extends _i2.Mock implements _i16.Post { ), returnValueForMissingStub: null, ); + @override String getPostCreatedDuration() => (super.noSuchMethod( Invocation.method( #getPostCreatedDuration, [], ), - returnValue: '', - returnValueForMissingStub: '', + returnValue: _i24.dummyValue( + this, + Invocation.method( + #getPostCreatedDuration, + [], + ), + ), + returnValueForMissingStub: _i24.dummyValue( + this, + Invocation.method( + #getPostCreatedDuration, + [], + ), + ), ) as String); } @@ -1948,6 +2107,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#clientNonAuth), ), ) as _i3.GraphQLClient); + @override set clientNonAuth(_i3.GraphQLClient? _clientNonAuth) => super.noSuchMethod( Invocation.setter( @@ -1956,6 +2116,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLClient get clientAuth => (super.noSuchMethod( Invocation.getter(#clientAuth), @@ -1968,6 +2129,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#clientAuth), ), ) as _i3.GraphQLClient); + @override set clientAuth(_i3.GraphQLClient? _clientAuth) => super.noSuchMethod( Invocation.setter( @@ -1976,6 +2138,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLError get userNotFound => (super.noSuchMethod( Invocation.getter(#userNotFound), @@ -1988,6 +2151,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#userNotFound), ), ) as _i3.GraphQLError); + @override set userNotFound(_i3.GraphQLError? _userNotFound) => super.noSuchMethod( Invocation.setter( @@ -1996,6 +2160,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLError get userNotAuthenticated => (super.noSuchMethod( Invocation.getter(#userNotAuthenticated), @@ -2008,6 +2173,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#userNotAuthenticated), ), ) as _i3.GraphQLError); + @override set userNotAuthenticated(_i3.GraphQLError? _userNotAuthenticated) => super.noSuchMethod( @@ -2017,6 +2183,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLError get emailAccountPresent => (super.noSuchMethod( Invocation.getter(#emailAccountPresent), @@ -2029,6 +2196,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#emailAccountPresent), ), ) as _i3.GraphQLError); + @override set emailAccountPresent(_i3.GraphQLError? _emailAccountPresent) => super.noSuchMethod( @@ -2038,6 +2206,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLError get wrongCredentials => (super.noSuchMethod( Invocation.getter(#wrongCredentials), @@ -2050,6 +2219,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#wrongCredentials), ), ) as _i3.GraphQLError); + @override set wrongCredentials(_i3.GraphQLError? _wrongCredentials) => super.noSuchMethod( @@ -2059,6 +2229,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLError get organizationNotFound => (super.noSuchMethod( Invocation.getter(#organizationNotFound), @@ -2071,6 +2242,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#organizationNotFound), ), ) as _i3.GraphQLError); + @override set organizationNotFound(_i3.GraphQLError? _organizationNotFound) => super.noSuchMethod( @@ -2080,6 +2252,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLError get refreshAccessTokenExpiredException => (super.noSuchMethod( @@ -2093,6 +2266,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#refreshAccessTokenExpiredException), ), ) as _i3.GraphQLError); + @override set refreshAccessTokenExpiredException( _i3.GraphQLError? _refreshAccessTokenExpiredException) => @@ -2103,6 +2277,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i3.GraphQLError get memberRequestExist => (super.noSuchMethod( Invocation.getter(#memberRequestExist), @@ -2115,6 +2290,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock Invocation.getter(#memberRequestExist), ), ) as _i3.GraphQLError); + @override set memberRequestExist(_i3.GraphQLError? _memberRequestExist) => super.noSuchMethod( @@ -2124,6 +2300,30 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + + @override + _i3.GraphQLError get notifFeatureNotInstalled => (super.noSuchMethod( + Invocation.getter(#notifFeatureNotInstalled), + returnValue: _FakeGraphQLError_18( + this, + Invocation.getter(#notifFeatureNotInstalled), + ), + returnValueForMissingStub: _FakeGraphQLError_18( + this, + Invocation.getter(#notifFeatureNotInstalled), + ), + ) as _i3.GraphQLError); + + @override + set notifFeatureNotInstalled(_i3.GraphQLError? _notifFeatureNotInstalled) => + super.noSuchMethod( + Invocation.setter( + #notifFeatureNotInstalled, + _notifFeatureNotInstalled, + ), + returnValueForMissingStub: null, + ); + @override void init() => super.noSuchMethod( Invocation.method( @@ -2132,6 +2332,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ); + @override bool? encounteredExceptionOrError( _i3.OperationException? exception, { @@ -2145,6 +2346,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock ), returnValueForMissingStub: null, ) as bool?); + @override _i4.Future gqlAuthQuery( String? query, { @@ -2159,6 +2361,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future gqlAuthMutation( String? mutation, { @@ -2173,6 +2376,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future gqlNonAuthMutation( String? mutation, { @@ -2191,6 +2395,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future<_i3.QueryResult?> gqlNonAuthQuery( String? query, { @@ -2206,6 +2411,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock returnValueForMissingStub: _i4.Future<_i3.QueryResult?>.value(), ) as _i4.Future<_i3.QueryResult?>); + @override _i4.Future refreshAccessToken(String? refreshToken) => (super.noSuchMethod( @@ -2216,6 +2422,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock returnValue: _i4.Future.value(false), returnValueForMissingStub: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future fetchOrgById(String? id) => (super.noSuchMethod( Invocation.method( @@ -2231,7 +2438,7 @@ class MockDataBaseMutationFunctions extends _i2.Mock /// /// See the documentation for Mockito's code generation for more information. class MockOrganizationService extends _i2.Mock - implements _i28.OrganizationService { + implements _i29.OrganizationService { @override _i4.Future> getOrgMembersList(String? orgId) => (super.noSuchMethod( @@ -2249,13 +2456,30 @@ class MockOrganizationService extends _i2.Mock /// /// See the documentation for Mockito's code generation for more information. class MockExploreEventsViewModel extends _i2.Mock - implements _i29.ExploreEventsViewModel { + implements _i30.ExploreEventsViewModel { + @override + bool get demoMode => (super.noSuchMethod( + Invocation.getter(#demoMode), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + set demoMode(bool? _demoMode) => super.noSuchMethod( + Invocation.setter( + #demoMode, + _demoMode, + ), + returnValueForMissingStub: null, + ); + @override List<_i19.Event> get events => (super.noSuchMethod( Invocation.getter(#events), returnValue: <_i19.Event>[], returnValueForMissingStub: <_i19.Event>[], ) as List<_i19.Event>); + @override _i10.EventService get eventService => (super.noSuchMethod( Invocation.getter(#eventService), @@ -2268,36 +2492,54 @@ class MockExploreEventsViewModel extends _i2.Mock Invocation.getter(#eventService), ), ) as _i10.EventService); + @override String get emptyListMessage => (super.noSuchMethod( Invocation.getter(#emptyListMessage), - returnValue: '', - returnValueForMissingStub: '', + returnValue: _i24.dummyValue( + this, + Invocation.getter(#emptyListMessage), + ), + returnValueForMissingStub: _i24.dummyValue( + this, + Invocation.getter(#emptyListMessage), + ), ) as String); + @override String get chosenValue => (super.noSuchMethod( Invocation.getter(#chosenValue), - returnValue: '', - returnValueForMissingStub: '', + returnValue: _i24.dummyValue( + this, + Invocation.getter(#chosenValue), + ), + returnValueForMissingStub: _i24.dummyValue( + this, + Invocation.getter(#chosenValue), + ), ) as String); + @override _i13.ViewState get state => (super.noSuchMethod( Invocation.getter(#state), returnValue: _i13.ViewState.idle, returnValueForMissingStub: _i13.ViewState.idle, ) as _i13.ViewState); + @override bool get isBusy => (super.noSuchMethod( Invocation.getter(#isBusy), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override _i4.Future fetchNewEvents() => (super.noSuchMethod( Invocation.method( @@ -2307,6 +2549,7 @@ class MockExploreEventsViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future refreshEvents() => (super.noSuchMethod( Invocation.method( @@ -2316,6 +2559,7 @@ class MockExploreEventsViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future initialise() => (super.noSuchMethod( Invocation.method( @@ -2325,6 +2569,7 @@ class MockExploreEventsViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future checkIfExistsAndAddNewEvent(_i19.Event? newEvent) => (super.noSuchMethod( @@ -2335,6 +2580,7 @@ class MockExploreEventsViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future deleteEvent({required String? eventId}) => (super.noSuchMethod( @@ -2346,6 +2592,7 @@ class MockExploreEventsViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future choseValueFromDropdown(String? value) => (super.noSuchMethod( Invocation.method( @@ -2355,6 +2602,7 @@ class MockExploreEventsViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2363,6 +2611,7 @@ class MockExploreEventsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void setState(_i13.ViewState? viewState) => super.noSuchMethod( Invocation.method( @@ -2371,6 +2620,7 @@ class MockExploreEventsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -2379,6 +2629,7 @@ class MockExploreEventsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -2387,6 +2638,7 @@ class MockExploreEventsViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -2400,7 +2652,7 @@ class MockExploreEventsViewModel extends _i2.Mock /// A class which mocks [Validator]. /// /// See the documentation for Mockito's code generation for more information. -class MockValidator extends _i2.Mock implements _i30.Validator { +class MockValidator extends _i2.Mock implements _i31.Validator { @override _i4.Future validateUrlExistence(String? url) => (super.noSuchMethod( Invocation.method( @@ -2415,41 +2667,45 @@ class MockValidator extends _i2.Mock implements _i30.Validator { /// A class which mocks [QRViewController]. /// /// See the documentation for Mockito's code generation for more information. -class MockQRViewController extends _i2.Mock implements _i31.QRViewController { +class MockQRViewController extends _i2.Mock implements _i32.QRViewController { @override - _i4.Stream<_i32.Barcode> get scannedDataStream => (super.noSuchMethod( + _i4.Stream<_i33.Barcode> get scannedDataStream => (super.noSuchMethod( Invocation.getter(#scannedDataStream), - returnValue: _i4.Stream<_i32.Barcode>.empty(), - returnValueForMissingStub: _i4.Stream<_i32.Barcode>.empty(), - ) as _i4.Stream<_i32.Barcode>); + returnValue: _i4.Stream<_i33.Barcode>.empty(), + returnValueForMissingStub: _i4.Stream<_i33.Barcode>.empty(), + ) as _i4.Stream<_i33.Barcode>); + @override bool get hasPermissions => (super.noSuchMethod( Invocation.getter(#hasPermissions), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override - _i4.Future<_i33.CameraFacing> getCameraInfo() => (super.noSuchMethod( + _i4.Future<_i34.CameraFacing> getCameraInfo() => (super.noSuchMethod( Invocation.method( #getCameraInfo, [], ), returnValue: - _i4.Future<_i33.CameraFacing>.value(_i33.CameraFacing.back), + _i4.Future<_i34.CameraFacing>.value(_i34.CameraFacing.back), returnValueForMissingStub: - _i4.Future<_i33.CameraFacing>.value(_i33.CameraFacing.back), - ) as _i4.Future<_i33.CameraFacing>); + _i4.Future<_i34.CameraFacing>.value(_i34.CameraFacing.back), + ) as _i4.Future<_i34.CameraFacing>); + @override - _i4.Future<_i33.CameraFacing> flipCamera() => (super.noSuchMethod( + _i4.Future<_i34.CameraFacing> flipCamera() => (super.noSuchMethod( Invocation.method( #flipCamera, [], ), returnValue: - _i4.Future<_i33.CameraFacing>.value(_i33.CameraFacing.back), + _i4.Future<_i34.CameraFacing>.value(_i34.CameraFacing.back), returnValueForMissingStub: - _i4.Future<_i33.CameraFacing>.value(_i33.CameraFacing.back), - ) as _i4.Future<_i33.CameraFacing>); + _i4.Future<_i34.CameraFacing>.value(_i34.CameraFacing.back), + ) as _i4.Future<_i34.CameraFacing>); + @override _i4.Future getFlashStatus() => (super.noSuchMethod( Invocation.method( @@ -2459,6 +2715,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future toggleFlash() => (super.noSuchMethod( Invocation.method( @@ -2468,6 +2725,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future pauseCamera() => (super.noSuchMethod( Invocation.method( @@ -2477,6 +2735,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future stopCamera() => (super.noSuchMethod( Invocation.method( @@ -2486,6 +2745,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future resumeCamera() => (super.noSuchMethod( Invocation.method( @@ -2495,6 +2755,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future<_i11.SystemFeatures> getSystemFeatures() => (super.noSuchMethod( Invocation.method( @@ -2518,6 +2779,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { ), )), ) as _i4.Future<_i11.SystemFeatures>); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2526,6 +2788,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { ), returnValueForMissingStub: null, ); + @override _i4.Future scanInvert(bool? isScanInvert) => (super.noSuchMethod( Invocation.method( @@ -2540,7 +2803,7 @@ class MockQRViewController extends _i2.Mock implements _i31.QRViewController { /// A class which mocks [CommentService]. /// /// See the documentation for Mockito's code generation for more information. -class MockCommentService extends _i2.Mock implements _i34.CommentService { +class MockCommentService extends _i2.Mock implements _i35.CommentService { @override _i4.Future createComments( String? postId, @@ -2557,6 +2820,7 @@ class MockCommentService extends _i2.Mock implements _i34.CommentService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future getCommentsForPost(String? postId) => (super.noSuchMethod( Invocation.method( @@ -2571,37 +2835,48 @@ class MockCommentService extends _i2.Mock implements _i34.CommentService { /// A class which mocks [AppTheme]. /// /// See the documentation for Mockito's code generation for more information. -class MockAppTheme extends _i2.Mock implements _i35.AppTheme { +class MockAppTheme extends _i2.Mock implements _i36.AppTheme { @override String get key => (super.noSuchMethod( Invocation.getter(#key), - returnValue: '', - returnValueForMissingStub: '', + returnValue: _i24.dummyValue( + this, + Invocation.getter(#key), + ), + returnValueForMissingStub: _i24.dummyValue( + this, + Invocation.getter(#key), + ), ) as String); + @override bool get isdarkTheme => (super.noSuchMethod( Invocation.getter(#isdarkTheme), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override _i13.ViewState get state => (super.noSuchMethod( Invocation.getter(#state), returnValue: _i13.ViewState.idle, returnValueForMissingStub: _i13.ViewState.idle, ) as _i13.ViewState); + @override bool get isBusy => (super.noSuchMethod( Invocation.getter(#isBusy), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override void initialize() => super.noSuchMethod( Invocation.method( @@ -2610,6 +2885,7 @@ class MockAppTheme extends _i2.Mock implements _i35.AppTheme { ), returnValueForMissingStub: null, ); + @override void switchTheme({required bool? isOn}) => super.noSuchMethod( Invocation.method( @@ -2619,6 +2895,7 @@ class MockAppTheme extends _i2.Mock implements _i35.AppTheme { ), returnValueForMissingStub: null, ); + @override void setState(_i13.ViewState? viewState) => super.noSuchMethod( Invocation.method( @@ -2627,6 +2904,7 @@ class MockAppTheme extends _i2.Mock implements _i35.AppTheme { ), returnValueForMissingStub: null, ); + @override void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -2635,6 +2913,7 @@ class MockAppTheme extends _i2.Mock implements _i35.AppTheme { ), returnValueForMissingStub: null, ); + @override void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -2643,6 +2922,7 @@ class MockAppTheme extends _i2.Mock implements _i35.AppTheme { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2651,6 +2931,7 @@ class MockAppTheme extends _i2.Mock implements _i35.AppTheme { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -2664,13 +2945,14 @@ class MockAppTheme extends _i2.Mock implements _i35.AppTheme { /// A class which mocks [TaskService]. /// /// See the documentation for Mockito's code generation for more information. -class MockTaskService extends _i2.Mock implements _i36.TaskService { +class MockTaskService extends _i2.Mock implements _i37.TaskService { @override _i9.VoidCallback get callbackNotifyListeners => (super.noSuchMethod( Invocation.getter(#callbackNotifyListeners), returnValue: () {}, returnValueForMissingStub: () {}, ) as _i9.VoidCallback); + @override set callbackNotifyListeners(_i9.VoidCallback? _callbackNotifyListeners) => super.noSuchMethod( @@ -2680,12 +2962,14 @@ class MockTaskService extends _i2.Mock implements _i36.TaskService { ), returnValueForMissingStub: null, ); + @override - List<_i37.Task> get tasks => (super.noSuchMethod( + List<_i38.Task> get tasks => (super.noSuchMethod( Invocation.getter(#tasks), - returnValue: <_i37.Task>[], - returnValueForMissingStub: <_i37.Task>[], - ) as List<_i37.Task>); + returnValue: <_i38.Task>[], + returnValueForMissingStub: <_i38.Task>[], + ) as List<_i38.Task>); + @override _i4.Future getTasksForEvent(String? eventId) => (super.noSuchMethod( Invocation.method( @@ -2695,6 +2979,7 @@ class MockTaskService extends _i2.Mock implements _i36.TaskService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future getTasksByUser() => (super.noSuchMethod( Invocation.method( @@ -2704,6 +2989,7 @@ class MockTaskService extends _i2.Mock implements _i36.TaskService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future editTask({ required String? title, @@ -2725,6 +3011,7 @@ class MockTaskService extends _i2.Mock implements _i36.TaskService { returnValue: _i4.Future.value(false), returnValueForMissingStub: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future createTask({ required String? title, @@ -2746,6 +3033,7 @@ class MockTaskService extends _i2.Mock implements _i36.TaskService { returnValue: _i4.Future.value(false), returnValueForMissingStub: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future deleteTask( String? taskId, @@ -2768,7 +3056,7 @@ class MockTaskService extends _i2.Mock implements _i36.TaskService { /// /// See the documentation for Mockito's code generation for more information. class MockCreateEventViewModel extends _i2.Mock - implements _i38.CreateEventViewModel { + implements _i39.CreateEventViewModel { @override _i1.TextEditingController get eventTitleTextController => (super.noSuchMethod( Invocation.getter(#eventTitleTextController), @@ -2781,6 +3069,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#eventTitleTextController), ), ) as _i1.TextEditingController); + @override set eventTitleTextController( _i1.TextEditingController? _eventTitleTextController) => @@ -2791,6 +3080,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TextEditingController get eventLocationTextController => (super.noSuchMethod( @@ -2804,6 +3094,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#eventLocationTextController), ), ) as _i1.TextEditingController); + @override set eventLocationTextController( _i1.TextEditingController? _eventLocationTextController) => @@ -2814,6 +3105,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TextEditingController get eventDescriptionTextController => (super.noSuchMethod( @@ -2827,6 +3119,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#eventDescriptionTextController), ), ) as _i1.TextEditingController); + @override set eventDescriptionTextController( _i1.TextEditingController? _eventDescriptionTextController) => @@ -2837,6 +3130,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TimeOfDay get eventStartTime => (super.noSuchMethod( Invocation.getter(#eventStartTime), @@ -2849,6 +3143,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#eventStartTime), ), ) as _i1.TimeOfDay); + @override set eventStartTime(_i1.TimeOfDay? _eventStartTime) => super.noSuchMethod( Invocation.setter( @@ -2857,6 +3152,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.TimeOfDay get eventEndTime => (super.noSuchMethod( Invocation.getter(#eventEndTime), @@ -2869,6 +3165,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#eventEndTime), ), ) as _i1.TimeOfDay); + @override set eventEndTime(_i1.TimeOfDay? _eventEndTime) => super.noSuchMethod( Invocation.setter( @@ -2877,6 +3174,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override DateTime get eventStartDate => (super.noSuchMethod( Invocation.getter(#eventStartDate), @@ -2889,6 +3187,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#eventStartDate), ), ) as DateTime); + @override set eventStartDate(DateTime? _eventStartDate) => super.noSuchMethod( Invocation.setter( @@ -2897,6 +3196,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override DateTime get eventEndDate => (super.noSuchMethod( Invocation.getter(#eventEndDate), @@ -2909,6 +3209,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#eventEndDate), ), ) as DateTime); + @override set eventEndDate(DateTime? _eventEndDate) => super.noSuchMethod( Invocation.setter( @@ -2917,12 +3218,14 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override bool get isPublicSwitch => (super.noSuchMethod( Invocation.getter(#isPublicSwitch), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override set isPublicSwitch(bool? _isPublicSwitch) => super.noSuchMethod( Invocation.setter( @@ -2931,12 +3234,14 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override bool get isRegisterableSwitch => (super.noSuchMethod( Invocation.getter(#isRegisterableSwitch), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override set isRegisterableSwitch(bool? _isRegisterableSwitch) => super.noSuchMethod( Invocation.setter( @@ -2945,6 +3250,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.FocusNode get titleFocus => (super.noSuchMethod( Invocation.getter(#titleFocus), @@ -2957,6 +3263,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#titleFocus), ), ) as _i1.FocusNode); + @override set titleFocus(_i1.FocusNode? _titleFocus) => super.noSuchMethod( Invocation.setter( @@ -2965,6 +3272,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.FocusNode get locationFocus => (super.noSuchMethod( Invocation.getter(#locationFocus), @@ -2977,6 +3285,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#locationFocus), ), ) as _i1.FocusNode); + @override set locationFocus(_i1.FocusNode? _locationFocus) => super.noSuchMethod( Invocation.setter( @@ -2985,6 +3294,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.FocusNode get descriptionFocus => (super.noSuchMethod( Invocation.getter(#descriptionFocus), @@ -2997,6 +3307,7 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#descriptionFocus), ), ) as _i1.FocusNode); + @override set descriptionFocus(_i1.FocusNode? _descriptionFocus) => super.noSuchMethod( Invocation.setter( @@ -3005,6 +3316,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override set latitude(double? _latitude) => super.noSuchMethod( Invocation.setter( @@ -3013,6 +3325,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override set longitude(double? _longitude) => super.noSuchMethod( Invocation.setter( @@ -3021,12 +3334,14 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override List<_i6.User> get orgMembersList => (super.noSuchMethod( Invocation.getter(#orgMembersList), returnValue: <_i6.User>[], returnValueForMissingStub: <_i6.User>[], ) as List<_i6.User>); + @override set orgMembersList(List<_i6.User>? _orgMembersList) => super.noSuchMethod( Invocation.setter( @@ -3035,6 +3350,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i1.GlobalKey<_i1.FormState> get formKey => (super.noSuchMethod( Invocation.getter(#formKey), @@ -3047,12 +3363,14 @@ class MockCreateEventViewModel extends _i2.Mock Invocation.getter(#formKey), ), ) as _i1.GlobalKey<_i1.FormState>); + @override _i1.AutovalidateMode get validate => (super.noSuchMethod( Invocation.getter(#validate), returnValue: _i1.AutovalidateMode.disabled, returnValueForMissingStub: _i1.AutovalidateMode.disabled, ) as _i1.AutovalidateMode); + @override set validate(_i1.AutovalidateMode? _validate) => super.noSuchMethod( Invocation.setter( @@ -3061,36 +3379,42 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override List<_i6.User> get selectedMembers => (super.noSuchMethod( Invocation.getter(#selectedMembers), returnValue: <_i6.User>[], returnValueForMissingStub: <_i6.User>[], ) as List<_i6.User>); + @override Map get memberCheckedMap => (super.noSuchMethod( Invocation.getter(#memberCheckedMap), returnValue: {}, returnValueForMissingStub: {}, ) as Map); + @override _i13.ViewState get state => (super.noSuchMethod( Invocation.getter(#state), returnValue: _i13.ViewState.idle, returnValueForMissingStub: _i13.ViewState.idle, ) as _i13.ViewState); + @override bool get isBusy => (super.noSuchMethod( Invocation.getter(#isBusy), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override void initialize() => super.noSuchMethod( Invocation.method( @@ -3099,6 +3423,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i4.Future createEvent() => (super.noSuchMethod( Invocation.method( @@ -3108,6 +3433,7 @@ class MockCreateEventViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future getImageFromGallery({bool? camera = false}) => (super.noSuchMethod( @@ -3119,6 +3445,7 @@ class MockCreateEventViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void removeImage() => super.noSuchMethod( Invocation.method( @@ -3127,6 +3454,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i4.Future> getCurrentOrgUsersList() => (super.noSuchMethod( Invocation.method( @@ -3137,6 +3465,7 @@ class MockCreateEventViewModel extends _i2.Mock returnValueForMissingStub: _i4.Future>.value(<_i6.User>[]), ) as _i4.Future>); + @override void buildUserList() => super.noSuchMethod( Invocation.method( @@ -3145,6 +3474,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void removeUserFromList({required String? userId}) => super.noSuchMethod( Invocation.method( @@ -3154,6 +3484,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void setState(_i13.ViewState? viewState) => super.noSuchMethod( Invocation.method( @@ -3162,6 +3493,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -3170,6 +3502,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -3178,6 +3511,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -3186,6 +3520,7 @@ class MockCreateEventViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -3200,7 +3535,7 @@ class MockCreateEventViewModel extends _i2.Mock /// /// See the documentation for Mockito's code generation for more information. class MockDirectChatViewModel extends _i2.Mock - implements _i39.DirectChatViewModel { + implements _i40.DirectChatViewModel { @override _i1.GlobalKey<_i1.AnimatedListState> get listKey => (super.noSuchMethod( Invocation.getter(#listKey), @@ -3213,12 +3548,14 @@ class MockDirectChatViewModel extends _i2.Mock Invocation.getter(#listKey), ), ) as _i1.GlobalKey<_i1.AnimatedListState>); + @override _i13.ChatState get chatState => (super.noSuchMethod( Invocation.getter(#chatState), returnValue: _i13.ChatState.initial, returnValueForMissingStub: _i13.ChatState.initial, ) as _i13.ChatState); + @override set chatState(_i13.ChatState? _chatState) => super.noSuchMethod( Invocation.setter( @@ -3227,6 +3564,7 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override set name(String? _name) => super.noSuchMethod( Invocation.setter( @@ -3235,12 +3573,14 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override List<_i21.ChatListTileDataModel> get chats => (super.noSuchMethod( Invocation.getter(#chats), returnValue: <_i21.ChatListTileDataModel>[], returnValueForMissingStub: <_i21.ChatListTileDataModel>[], ) as List<_i21.ChatListTileDataModel>); + @override Map> get chatMessagesByUser => (super.noSuchMethod( @@ -3248,24 +3588,28 @@ class MockDirectChatViewModel extends _i2.Mock returnValue: >{}, returnValueForMissingStub: >{}, ) as Map>); + @override _i13.ViewState get state => (super.noSuchMethod( Invocation.getter(#state), returnValue: _i13.ViewState.idle, returnValueForMissingStub: _i13.ViewState.idle, ) as _i13.ViewState); + @override bool get isBusy => (super.noSuchMethod( Invocation.getter(#isBusy), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, returnValueForMissingStub: false, ) as bool); + @override void refreshChats() => super.noSuchMethod( Invocation.method( @@ -3274,6 +3618,7 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override _i4.Future initialise() => (super.noSuchMethod( Invocation.method( @@ -3283,6 +3628,7 @@ class MockDirectChatViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future getChatMessages(String? chatId) => (super.noSuchMethod( Invocation.method( @@ -3292,6 +3638,7 @@ class MockDirectChatViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future sendMessageToDirectChat( String? chatId, @@ -3308,6 +3655,7 @@ class MockDirectChatViewModel extends _i2.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -3316,6 +3664,7 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void chatName(dynamic chatId) => super.noSuchMethod( Invocation.method( @@ -3324,6 +3673,7 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void setState(_i13.ViewState? viewState) => super.noSuchMethod( Invocation.method( @@ -3332,6 +3682,7 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -3340,6 +3691,7 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -3348,6 +3700,7 @@ class MockDirectChatViewModel extends _i2.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -3361,24 +3714,24 @@ class MockDirectChatViewModel extends _i2.Mock /// A class which mocks [ImageCropper]. /// /// See the documentation for Mockito's code generation for more information. -class MockImageCropper extends _i2.Mock implements _i40.ImageCropper { +class MockImageCropper extends _i2.Mock implements _i41.ImageCropper { @override - _i4.Future<_i40.CroppedFile?> cropImage({ + _i4.Future<_i41.CroppedFile?> cropImage({ required String? sourcePath, int? maxWidth, int? maxHeight, - _i40.CropAspectRatio? aspectRatio, - List<_i40.CropAspectRatioPreset>? aspectRatioPresets = const [ - _i40.CropAspectRatioPreset.original, - _i40.CropAspectRatioPreset.square, - _i40.CropAspectRatioPreset.ratio3x2, - _i40.CropAspectRatioPreset.ratio4x3, - _i40.CropAspectRatioPreset.ratio16x9, + _i41.CropAspectRatio? aspectRatio, + List<_i41.CropAspectRatioPreset>? aspectRatioPresets = const [ + _i41.CropAspectRatioPreset.original, + _i41.CropAspectRatioPreset.square, + _i41.CropAspectRatioPreset.ratio3x2, + _i41.CropAspectRatioPreset.ratio4x3, + _i41.CropAspectRatioPreset.ratio16x9, ], - _i40.CropStyle? cropStyle = _i40.CropStyle.rectangle, - _i40.ImageCompressFormat? compressFormat = _i40.ImageCompressFormat.jpg, + _i41.CropStyle? cropStyle = _i41.CropStyle.rectangle, + _i41.ImageCompressFormat? compressFormat = _i41.ImageCompressFormat.jpg, int? compressQuality = 90, - List<_i40.PlatformUiSettings>? uiSettings, + List<_i41.PlatformUiSettings>? uiSettings, }) => (super.noSuchMethod( Invocation.method( @@ -3396,18 +3749,19 @@ class MockImageCropper extends _i2.Mock implements _i40.ImageCropper { #uiSettings: uiSettings, }, ), - returnValue: _i4.Future<_i40.CroppedFile?>.value(), - returnValueForMissingStub: _i4.Future<_i40.CroppedFile?>.value(), - ) as _i4.Future<_i40.CroppedFile?>); + returnValue: _i4.Future<_i41.CroppedFile?>.value(), + returnValueForMissingStub: _i4.Future<_i41.CroppedFile?>.value(), + ) as _i4.Future<_i41.CroppedFile?>); + @override - _i4.Future<_i40.CroppedFile?> recoverImage() => (super.noSuchMethod( + _i4.Future<_i41.CroppedFile?> recoverImage() => (super.noSuchMethod( Invocation.method( #recoverImage, [], ), - returnValue: _i4.Future<_i40.CroppedFile?>.value(), - returnValueForMissingStub: _i4.Future<_i40.CroppedFile?>.value(), - ) as _i4.Future<_i40.CroppedFile?>); + returnValue: _i4.Future<_i41.CroppedFile?>.value(), + returnValueForMissingStub: _i4.Future<_i41.CroppedFile?>.value(), + ) as _i4.Future<_i41.CroppedFile?>); } /// A class which mocks [ImagePicker]. @@ -3415,16 +3769,17 @@ class MockImageCropper extends _i2.Mock implements _i40.ImageCropper { /// See the documentation for Mockito's code generation for more information. class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { @override - _i4.Future<_i12.PickedFile?> getImage({ + _i4.Future<_i12.XFile?> pickImage({ required _i12.ImageSource? source, double? maxWidth, double? maxHeight, int? imageQuality, _i12.CameraDevice? preferredCameraDevice = _i12.CameraDevice.rear, + bool? requestFullMetadata = true, }) => (super.noSuchMethod( Invocation.method( - #getImage, + #pickImage, [], { #source: source, @@ -3432,98 +3787,60 @@ class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { #maxHeight: maxHeight, #imageQuality: imageQuality, #preferredCameraDevice: preferredCameraDevice, + #requestFullMetadata: requestFullMetadata, }, ), - returnValue: _i4.Future<_i12.PickedFile?>.value(), - returnValueForMissingStub: _i4.Future<_i12.PickedFile?>.value(), - ) as _i4.Future<_i12.PickedFile?>); + returnValue: _i4.Future<_i12.XFile?>.value(), + returnValueForMissingStub: _i4.Future<_i12.XFile?>.value(), + ) as _i4.Future<_i12.XFile?>); + @override - _i4.Future?> getMultiImage({ + _i4.Future> pickMultiImage({ double? maxWidth, double? maxHeight, int? imageQuality, + bool? requestFullMetadata = true, }) => (super.noSuchMethod( Invocation.method( - #getMultiImage, + #pickMultiImage, [], { #maxWidth: maxWidth, #maxHeight: maxHeight, #imageQuality: imageQuality, + #requestFullMetadata: requestFullMetadata, }, ), - returnValue: _i4.Future?>.value(), - returnValueForMissingStub: _i4.Future?>.value(), - ) as _i4.Future?>); - @override - _i4.Future<_i12.PickedFile?> getVideo({ - required _i12.ImageSource? source, - _i12.CameraDevice? preferredCameraDevice = _i12.CameraDevice.rear, - Duration? maxDuration, - }) => - (super.noSuchMethod( - Invocation.method( - #getVideo, - [], - { - #source: source, - #preferredCameraDevice: preferredCameraDevice, - #maxDuration: maxDuration, - }, - ), - returnValue: _i4.Future<_i12.PickedFile?>.value(), - returnValueForMissingStub: _i4.Future<_i12.PickedFile?>.value(), - ) as _i4.Future<_i12.PickedFile?>); - @override - _i4.Future<_i12.LostData> getLostData() => (super.noSuchMethod( - Invocation.method( - #getLostData, - [], - ), - returnValue: _i4.Future<_i12.LostData>.value(_FakeLostData_23( - this, - Invocation.method( - #getLostData, - [], - ), - )), + returnValue: _i4.Future>.value(<_i12.XFile>[]), returnValueForMissingStub: - _i4.Future<_i12.LostData>.value(_FakeLostData_23( - this, - Invocation.method( - #getLostData, - [], - ), - )), - ) as _i4.Future<_i12.LostData>); + _i4.Future>.value(<_i12.XFile>[]), + ) as _i4.Future>); + @override - _i4.Future<_i12.XFile?> pickImage({ - required _i12.ImageSource? source, + _i4.Future<_i12.XFile?> pickMedia({ double? maxWidth, double? maxHeight, int? imageQuality, - _i12.CameraDevice? preferredCameraDevice = _i12.CameraDevice.rear, bool? requestFullMetadata = true, }) => (super.noSuchMethod( Invocation.method( - #pickImage, + #pickMedia, [], { - #source: source, #maxWidth: maxWidth, #maxHeight: maxHeight, #imageQuality: imageQuality, - #preferredCameraDevice: preferredCameraDevice, #requestFullMetadata: requestFullMetadata, }, ), returnValue: _i4.Future<_i12.XFile?>.value(), returnValueForMissingStub: _i4.Future<_i12.XFile?>.value(), ) as _i4.Future<_i12.XFile?>); + @override - _i4.Future> pickMultiImage({ + _i4.Future> pickMultipleMedia({ double? maxWidth, double? maxHeight, int? imageQuality, @@ -3531,7 +3848,7 @@ class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { }) => (super.noSuchMethod( Invocation.method( - #pickMultiImage, + #pickMultipleMedia, [], { #maxWidth: maxWidth, @@ -3544,6 +3861,7 @@ class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { returnValueForMissingStub: _i4.Future>.value(<_i12.XFile>[]), ) as _i4.Future>); + @override _i4.Future<_i12.XFile?> pickVideo({ required _i12.ImageSource? source, @@ -3563,6 +3881,7 @@ class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { returnValue: _i4.Future<_i12.XFile?>.value(), returnValueForMissingStub: _i4.Future<_i12.XFile?>.value(), ) as _i4.Future<_i12.XFile?>); + @override _i4.Future<_i12.LostDataResponse> retrieveLostData() => (super.noSuchMethod( Invocation.method( @@ -3570,7 +3889,7 @@ class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { [], ), returnValue: - _i4.Future<_i12.LostDataResponse>.value(_FakeLostDataResponse_24( + _i4.Future<_i12.LostDataResponse>.value(_FakeLostDataResponse_23( this, Invocation.method( #retrieveLostData, @@ -3578,7 +3897,7 @@ class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { ), )), returnValueForMissingStub: - _i4.Future<_i12.LostDataResponse>.value(_FakeLostDataResponse_24( + _i4.Future<_i12.LostDataResponse>.value(_FakeLostDataResponse_23( this, Invocation.method( #retrieveLostData, @@ -3586,4 +3905,14 @@ class MockImagePicker extends _i2.Mock implements _i12.ImagePicker { ), )), ) as _i4.Future<_i12.LostDataResponse>); + + @override + bool supportsImageSource(_i12.ImageSource? source) => (super.noSuchMethod( + Invocation.method( + #supportsImageSource, + [source], + ), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); } diff --git a/test/model_tests/app_tour_test.dart b/test/model_tests/app_tour_test.dart new file mode 100644 index 000000000..57579acaf --- /dev/null +++ b/test/model_tests/app_tour_test.dart @@ -0,0 +1,170 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:talawa/locator.dart'; +import 'package:talawa/models/app_tour.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/view_model/lang_view_model.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/views/base_view.dart'; +import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; + +import '../router_test.dart'; + +class CustomTutorialController extends TutorialCoachMarkController { + @override + void next() {} + + @override + void previous() {} + + @override + void skip() {} +} + +class MockTutorialCoachMark extends Mock implements TutorialCoachMark { + @override + void next() {} +} + +class MockAppTour extends Mock implements AppTour { + MockAppTour({ + required this.model, + }); + + @override + TutorialCoachMark get tutorialCoachMark => MockTutorialCoachMark(); + + @override + void showTutorial({ + required Function(TargetFocus p1) onClickTarget, + required Function() onFinish, + required List targets, + }) { + onFinish(); + onClickTarget( + TargetFocus( + identify: MainScreenViewModel.keyDrawerCurOrg, + keyTarget: model.keyBNChat, + ), + ); + } + + @override + MainScreenViewModel model; +} + +void main() { + setupLocator(); + sizeConfig.test(); + // registerServices(); + + group('Tests for FocusTarget', () { + test('Test for FocusTarget model.', () { + final model = MainScreenViewModel(); + model.context = MockBuildContext(); + final focusTarget = FocusTarget( + key: MainScreenViewModel.keyDrawerCurOrg, + keyName: 'keyName', + description: 'description', + appTour: MockAppTour(model: model), + next: () {}, + ); + + focusTarget.focusWidget.contents![0].builder!( + model.context, + CustomTutorialController(), + ); + + focusTarget.focusWidget.contents![1].builder!( + model.context, + CustomTutorialController(), + ); + }); + + testWidgets('Test for showTutorial method.', (tester) async { + AppTour? mockAppTour; + FocusTarget? mockFocusTarget; + final app = BaseView( + onModelReady: (model) => model.initialize(), + builder: (context, langModel, child) { + return MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + home: BaseView( + onModelReady: (model2) => model2.initialise( + context, + fromSignUp: false, + mainScreenIndex: 0, + demoMode: true, + testMode: true, + ), + builder: (context, model2, child) { + mockAppTour = AppTour(model: model2); + mockFocusTarget = FocusTarget( + key: MainScreenViewModel.keyDrawerLeaveCurrentOrg, + keyName: 'keyDrawerLeaveCurrentOrg', + description: 'description', + next: () {}, + appTour: mockAppTour!, + ); + // SizeConfig().init(context); + model2.context = context; + return Scaffold( + drawer: const Drawer(), + key: MainScreenViewModel.scaffoldKey, + body: TextButton( + key: MainScreenViewModel.keyDrawerLeaveCurrentOrg, + child: const Text('tutorial'), + onPressed: () { + MainScreenViewModel.scaffoldKey.currentState! + .openDrawer(); + mockAppTour!.showTutorial( + onClickTarget: (x) {}, + onFinish: () {}, + targets: [ + mockFocusTarget!, + ], + ); + }, + ), + ); + }, + ), + navigatorKey: navigationService.navigatorKey, + // onGenerateRoute: router.generateRoute, + ); + }, + ); + + await tester.pumpWidget(app); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final tutorialBtn = + find.byKey(MainScreenViewModel.keyDrawerLeaveCurrentOrg); + + expect(tutorialBtn, findsOneWidget); + + (tester.widget(tutorialBtn) as TextButton).onPressed!(); + + mockAppTour!.tutorialCoachMark.onSkip!(); + mockAppTour!.tutorialCoachMark.onClickOverlay!( + TargetFocus( + identify: MainScreenViewModel.keyDrawerCurOrg, + keyTarget: MainScreenViewModel.keyDrawerCurOrg, + ), + ); + + (mockFocusTarget!.focusWidget.contents![1].builder!( + MockBuildContext(), + CustomTutorialController(), + ) as GestureDetector) + .onTap!(); + }); + }); +} diff --git a/test/model_tests/mainscreen_navigation_args_test.dart b/test/model_tests/mainscreen_navigation_args_test.dart new file mode 100644 index 000000000..fc25ccb78 --- /dev/null +++ b/test/model_tests/mainscreen_navigation_args_test.dart @@ -0,0 +1,33 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:talawa/models/mainscreen_navigation_args.dart'; + +void main() { + group('MainScreenArgs', () { + test('Equality', () { + // Test 1: Creating two equal instances of MainScreenArgs + final mainScreenArgs1 = MainScreenArgs( + fromSignUp: true, + mainScreenIndex: 1, + toggleDemoMode: false, + ); + final mainScreenArgs2 = MainScreenArgs( + fromSignUp: true, + mainScreenIndex: 1, + toggleDemoMode: false, + ); + + expect(mainScreenArgs1, equals(mainScreenArgs2)); + expect(mainScreenArgs1.hashCode, equals(mainScreenArgs2.hashCode)); + + // Test 2: Creating instances with different properties + final mainScreenArgs3 = MainScreenArgs( + fromSignUp: false, + mainScreenIndex: 2, + toggleDemoMode: true, + ); + + expect(mainScreenArgs1, isNot(equals(mainScreenArgs3))); + expect(mainScreenArgs1.hashCode, isNot(equals(mainScreenArgs3.hashCode))); + }); + }); +} diff --git a/test/router_test.dart b/test/router_test.dart index 34c1abbda..a46d7a2f9 100644 --- a/test/router_test.dart +++ b/test/router_test.dart @@ -33,10 +33,14 @@ import 'package:talawa/views/after_auth_screens/profile/profile_page.dart'; import 'package:talawa/views/after_auth_screens/tasks/create_task_page.dart'; import 'package:talawa/views/after_auth_screens/tasks/event_tasks_page.dart'; import 'package:talawa/views/after_auth_screens/tasks/user_tasks_page.dart'; +import 'package:talawa/views/demo_screens/explore_events_demo.dart'; +import 'package:talawa/views/demo_screens/organization_feed_demo.dart'; +import 'package:talawa/views/demo_screens/profile_page_demo.dart'; import 'package:talawa/views/main_screen.dart'; import 'package:talawa/views/pre_auth_screens/change_password.dart'; import 'package:talawa/views/pre_auth_screens/select_language.dart'; import 'package:talawa/views/pre_auth_screens/select_organization.dart'; +import 'package:talawa/views/pre_auth_screens/set_url.dart'; import 'package:talawa/views/pre_auth_screens/waiting_to_join_private_org.dart'; class MockBuildContext extends Mock implements BuildContext {} @@ -350,6 +354,53 @@ void main() { } }); + testWidgets('Test for setUrl route', (WidgetTester tester) async { + final route = generateRoute( + const RouteSettings(name: Routes.setUrlScreen, arguments: ''), + ); + expect(route, isA()); + if (route is MaterialPageRoute) { + final builder = route.builder; + final widget = builder(MockBuildContext()); + expect(widget, isA()); + } + }); + + testWidgets('Test for demoProfilePage route', (WidgetTester tester) async { + final route = + generateRoute(const RouteSettings(name: Routes.demoProfilePage)); + expect(route, isA()); + if (route is MaterialPageRoute) { + final builder = route.builder; + final widget = builder(MockBuildContext()); + expect(widget, isA()); + } + }); + + testWidgets('Test for demoExploreEventsScreen route', + (WidgetTester tester) async { + final route = generateRoute( + const RouteSettings(name: Routes.demoExploreEventsScreen), + ); + expect(route, isA()); + if (route is MaterialPageRoute) { + final builder = route.builder; + final widget = builder(MockBuildContext()); + expect(widget, isA()); + } + }); + + testWidgets('Test for demoHomeScreen route', (WidgetTester tester) async { + final route = + generateRoute(const RouteSettings(name: Routes.demoHomeScreen)); + expect(route, isA()); + if (route is MaterialPageRoute) { + final builder = route.builder; + final widget = builder(MockBuildContext()); + expect(widget, isA()); + } + }); + testWidgets('Test for default DemoPage route', (WidgetTester tester) async { final route = generateRoute(const RouteSettings(name: 'default')); expect(route, isA()); diff --git a/test/service_tests/navigation_service_test.dart b/test/service_tests/navigation_service_test.dart index 4cd4b64b7..bb361f392 100644 --- a/test/service_tests/navigation_service_test.dart +++ b/test/service_tests/navigation_service_test.dart @@ -473,14 +473,42 @@ void main() { expect(snackBarWidget.behavior, equals(SnackBarBehavior.floating)); expect(snackBarWidget.duration, equals(const Duration(seconds: 3))); }); - testWidgets('showTalawaErrorSnackBar() test', (tester) async { - const String errorMessage = 'Error Message'; + testWidgets('showTalawaErrorSnackBar() test with default duration', + (tester) async { + await tester.pumpWidget( + TalawaErrorWidget( + navigationService: navigationService, + onClick: () { + navigationService.showTalawaErrorSnackBar( + 'Error Message', + MessageType.error, + ); + }, + ), + ); + await tester.pumpAndSettle(); + await tester.tap(find.byType(TextButton)); + await tester.pumpAndSettle(); + expect(find.byType(TalawaErrorSnackBar), findsOneWidget); + final snackBarFinder = find.byType(SnackBar); + final snackBarWidget = tester.widget(snackBarFinder); + expect( + snackBarWidget.duration, + equals(const Duration(milliseconds: 1040)), + ); + expect( + snackBarWidget.backgroundColor, + const Color.fromRGBO(65, 65, 66, 1), + ); + }); + testWidgets('showTalawaErrorSnackBar() test with custom duration', + (tester) async { await tester.pumpWidget( TalawaErrorWidget( navigationService: navigationService, onClick: () { navigationService.showTalawaErrorSnackBar( - errorMessage, + 'Error Message', MessageType.error, ); }, @@ -494,7 +522,7 @@ void main() { final snackBarWidget = tester.widget(snackBarFinder); expect( snackBarWidget.duration, - equals(const Duration(milliseconds: errorMessage.length * 80)), + equals(const Duration(milliseconds: 1040)), ); expect( snackBarWidget.backgroundColor, diff --git a/test/service_tests/user_config_test.dart b/test/service_tests/user_config_test.dart new file mode 100644 index 000000000..8f842156d --- /dev/null +++ b/test/service_tests/user_config_test.dart @@ -0,0 +1,174 @@ +// ignore_for_file: talawa_api_doc +// ignore_for_file: talawa_good_doc_comments + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; +import 'package:hive/hive.dart'; +import 'package:mockito/mockito.dart'; +import 'package:talawa/models/organization/org_info.dart'; +import 'package:talawa/models/user/user_info.dart'; +import 'package:talawa/services/user_config.dart'; +import 'package:talawa/widgets/custom_progress_dialog.dart'; + +import '../helpers/test_helpers.dart'; +import '../helpers/test_locator.dart'; + +class MockBox extends Mock implements Box {} + +// class MockUser extends Mock implements User { +// @override +// void updateJoinedOrg(List orgList) { +// // TODO: implement updateJoinedOrg +// } + +// @override +// void updateMemberRequestOrg(List orgList) { +// // TODO: implement updateMemberRequestOrg +// } +// } + +void main() async { + testSetupLocator(); + + final Directory dir = Directory('test/fixtures/core'); + + Hive + ..init(dir.path) + ..registerAdapter(UserAdapter()) + ..registerAdapter(OrgInfoAdapter()); + + final userBox = await Hive.openBox('currentUser'); + final urlBox = await Hive.openBox('url'); + final orgBox = await Hive.openBox('currentOrg'); + + final mockUser = User( + adminFor: [ + OrgInfo(id: 'org1', name: 'orga'), + OrgInfo(id: 'org2', name: 'orgb'), + ], + createdOrganizations: [ + OrgInfo(id: 'org1', name: 'orga'), + OrgInfo(id: 'org2', name: 'orgb'), + ], + email: 'test@gmail.com', + firstName: 'user', + lastName: 'one', + image: 'sample.jpg', + joinedOrganizations: [ + OrgInfo(id: 'org1', name: 'orga'), + OrgInfo(id: 'org2', name: 'orgb'), + ], + authToken: 'AuthToken', + refreshToken: 'Refreshtoken', + membershipRequests: [ + OrgInfo(id: 'org1', name: 'orga'), + OrgInfo(id: 'org2', name: 'orgb'), + ], + ); + + final mockOrgDetails = [ + OrgInfo(id: 'org3', name: 'orgc'), + OrgInfo(id: 'org4', name: 'orgd'), + ]; + + group('Test UserConfig service', () { + setUpAll(() { + registerServices(); + }); + test('Test for User log out.', () async { + databaseFunctions.init(); + + when(databaseFunctions.gqlAuthMutation(queries.logout())) + .thenAnswer((realInvocation) async { + final data = { + 'logout': true, + }; + return QueryResult( + source: QueryResultSource.network, + data: data, + options: QueryOptions(document: gql(queries.logout())), + ); + }); + + when(navigationService.pop()).thenAnswer((_) async {}); + when( + navigationService.pushDialog( + const CustomProgressDialog( + key: Key('LogoutProgress'), + ), + ), + ).thenAnswer((realInvocation) async {}); + + bool loggedOut = await UserConfig().userLogOut(); + + expect(loggedOut, true); + + verify(navigationService.pop()); + expect(userBox.isEmpty, true); + expect(urlBox.isEmpty, true); + expect(orgBox.isEmpty, true); + + when(databaseFunctions.gqlAuthMutation(queries.logout())) + .thenAnswer((realInvocation) async { + throw Exception('test exception'); + }); + + loggedOut = await UserConfig().userLogOut(); + expect(loggedOut, false); + }); + + test('Test for updateUserJoinedOrg', () async { + final model = UserConfig(); + model.currentUser = mockUser; + + await model.updateUserJoinedOrg(mockOrgDetails); + + expect(mockUser.joinedOrganizations, mockOrgDetails); + }); + + test('Test for updateUserCreatedOrg', () async { + final model = UserConfig(); + model.currentUser = mockUser; + + await model.updateUserCreatedOrg(mockOrgDetails); + + expect(mockUser.createdOrganizations, mockOrgDetails); + }); + + test('Test for updateUserMemberRequestOrg', () async { + final model = UserConfig(); + model.currentUser = mockUser; + final expected = [...mockUser.membershipRequests!, ...mockOrgDetails]; + await model.updateUserMemberRequestOrg(mockOrgDetails); + + expect(mockUser.membershipRequests, expected); + }); + + test('Test for updateUserAdminOrg', () async { + final model = UserConfig(); + model.currentUser = mockUser; + + await model.updateUserAdminOrg(mockOrgDetails); + + expect(mockUser.adminFor, mockOrgDetails); + }); + + test('Test for updateAccessToken', () async { + final model = UserConfig(); + model.currentUser = mockUser; + const newAuthToken = 'newAccessToken'; + const newRefreshToken = 'newRefreshToken'; + + await model.updateAccessToken( + accessToken: newAuthToken, + refreshToken: newRefreshToken, + ); + + expect(mockUser.authToken, newAuthToken); + expect(mockUser.refreshToken, newRefreshToken); + }); + }); +} diff --git a/test/utils/app_localization_test.dart b/test/utils/app_localization_test.dart index a49f11861..6a49121b3 100644 --- a/test/utils/app_localization_test.dart +++ b/test/utils/app_localization_test.dart @@ -20,7 +20,7 @@ void main() { final result = await appLocalizations.load(); expect(result, true); - expect(appLocalizations.strictTranslate("Recover"), "Recover"); + // expect(appLocalizations.strictTranslate("Recover"), "Recover"); }); test("Translate and strict translate", () async { diff --git a/test/view_model_tests/after_auth_view_model_tests/profile_view_model_tests/profile_page_view_model_test.dart b/test/view_model_tests/after_auth_view_model_tests/profile_view_model_tests/profile_page_view_model_test.dart index 5c6af31d3..b4931c9df 100644 --- a/test/view_model_tests/after_auth_view_model_tests/profile_view_model_tests/profile_page_view_model_test.dart +++ b/test/view_model_tests/after_auth_view_model_tests/profile_view_model_tests/profile_page_view_model_test.dart @@ -7,10 +7,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:talawa/enums/enums.dart'; -import 'package:talawa/services/graphql_config.dart'; +import 'package:talawa/router.dart' as router; import 'package:talawa/services/size_config.dart'; import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/view_model/after_auth_view_models/profile_view_models/profile_page_view_model.dart'; +import 'package:talawa/view_model/lang_view_model.dart'; +import 'package:talawa/views/base_view.dart'; import '../../../helpers/test_helpers.dart'; import '../../../helpers/test_locator.dart'; @@ -35,19 +37,18 @@ void verifyInteraction(dynamic x, {required String mockName}) { void main() async { testSetupLocator(); - locator().test(); - locator().test(); - setUp(() { - registerServices(); - locator().test(); - }); + group('ProfilePageViewModel Tests -', () { + setUpAll(() { + registerServices(); + graphqlConfig.test(); + sizeConfig.test(); + }); - tearDown(() { - unregisterServices(); - }); + tearDownAll(() { + unregisterServices(); + }); - group('ProfilePageViewModel Tests -', () { test("Test initialization", () { final model = ProfilePageViewModel(); model.initialize(); @@ -55,6 +56,11 @@ void main() async { expect(model.currentUser, userConfig.currentUser); }); + test('test logout function', () async { + final model = ProfilePageViewModel(); + final context = MockBuildContext(); + await model.logout(context); + }); testWidgets('changeCurrency test', (WidgetTester tester) async { final model = ProfilePageViewModel(); model.initialize(); @@ -99,6 +105,72 @@ void main() async { verify(navigationService.pop()); }); + testWidgets("Test logout dialog when logout successful.", (tester) async { + const userLoggedin = false; + when(userConfig.loggedIn).thenAnswer((_) => userLoggedin); + final model = ProfilePageViewModel(); + + final widget = BaseView( + onModelReady: (model) => model.initialize(), + builder: (context, langModel, child) { + return MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + home: Scaffold( + body: model.logoutDialog(), + ), + navigatorKey: navigationService.navigatorKey, + onGenerateRoute: router.generateRoute, + ); + }, + ); + + await tester.pumpWidget(widget); + await tester.pumpAndSettle(); + + await tester.tap(find.textContaining('Logout')); + await tester.pumpAndSettle(); + + verify(navigationService.navigatorKey); + }); + + testWidgets("Test logout dialog when logout unsuccessful.", (tester) async { + final model = ProfilePageViewModel(); + const userLoggedIn = true; + when(userConfig.loggedIn).thenAnswer((_) => userLoggedIn); + + final widget = BaseView( + onModelReady: (model) => model.initialize(), + builder: (context, langModel, child) { + return MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + home: Scaffold( + body: model.logoutDialog(), + ), + navigatorKey: navigationService.navigatorKey, + onGenerateRoute: router.generateRoute, + ); + }, + ); + + await tester.pumpWidget(widget); + await tester.pumpAndSettle(); + + await tester.tap(find.textContaining('Logout')); + await tester.pumpAndSettle(); + + verify(navigationService.navigatorKey); + }); + test("Test updateSheetHeight function", () { final model = ProfilePageViewModel(); model.initialize(); @@ -201,17 +273,6 @@ void main() async { expect(find.byType(QrImageView), findsOneWidget); }); - testWidgets("Test logout function", (tester) async { - final mockContext = MockBuildContext(); - final model = ProfilePageViewModel(); - final mocknav = getAndRegisterNavigationService(); - model.initialize(); - await model.logout(mockContext); - await tester.pumpAndSettle(); - - //Ensures that naviagation service was called - verifyInteraction(mocknav, mockName: "NavigationService"); - }); testWidgets('attachListener test', (WidgetTester tester) async { final model = ProfilePageViewModel(); model.initialize(); @@ -253,5 +314,20 @@ void main() async { }); expect(bottomSheetHeight, SizeConfig.screenHeight! * 0.68); }); + + // test('logout success', () { + // final model = ProfilePageViewModel(); + // when(userConfig.loggedIn).thenReturn(true); + // model.logoutSuccess(); + + // // when(userConfig.loggedIn).thenReturn(false); + // // model.logoutSuccess(); + + // // verify( navigationService.removeAllAndPush( + // // '/selectLang', + // // '/', + // // arguments: '0', + // // )); + // }); }); } diff --git a/test/view_model_tests/lang_view_model_test.dart b/test/view_model_tests/lang_view_model_test.dart index f9a32365f..0924fdc31 100644 --- a/test/view_model_tests/lang_view_model_test.dart +++ b/test/view_model_tests/lang_view_model_test.dart @@ -5,6 +5,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:talawa/constants/routing_constants.dart'; +import 'package:talawa/models/mainscreen_navigation_args.dart'; import 'package:talawa/services/graphql_config.dart'; import 'package:talawa/view_model/lang_view_model.dart'; @@ -97,22 +99,34 @@ void main() { final model = AppLanguage(isTest: true); await model.initialize(); - // testing selectLanguagePress function - // first considering user is not logged in - when(userConfig.userLoggedIn()).thenAnswer((realInvocation) async { - return false; - }); + // consider if user is not logged in. + when(userConfig.loggedIn).thenReturn(false); - when(navigationService.pushScreen('/setUrl', arguments: '')) - .thenAnswer((_) async {}); + when( + navigationService.pushScreen( + Routes.mainScreen, + arguments: MainScreenArgs( + mainScreenIndex: 0, + fromSignUp: false, + toggleDemoMode: true, + ), + ), + ).thenAnswer((_) async {}); await model.selectLanguagePress(); - verify(navigationService.pushScreen('/setUrl', arguments: '')); + verify( + navigationService.pushScreen( + Routes.mainScreen, + arguments: MainScreenArgs( + mainScreenIndex: 0, + fromSignUp: false, + toggleDemoMode: true, + ), + ), + ); - // now consider user to be logged in - when(userConfig.userLoggedIn()).thenAnswer((realInvocation) async { - return true; - }); + // consider if user is logged in. + when(userConfig.loggedIn).thenReturn(true); when( navigationService.popAndPushScreen( diff --git a/test/view_model_tests/main_screen_view_model_test.dart b/test/view_model_tests/main_screen_view_model_test.dart index 8fb283ec6..3d83f4184 100644 --- a/test/view_model_tests/main_screen_view_model_test.dart +++ b/test/view_model_tests/main_screen_view_model_test.dart @@ -1,17 +1,77 @@ // ignore_for_file: talawa_api_doc // ignore_for_file: talawa_good_doc_comments -import 'package:flutter/cupertino.dart'; +import 'dart:io'; + import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:hive/hive.dart'; import 'package:mockito/mockito.dart'; +import 'package:talawa/router.dart' as router; import 'package:talawa/services/size_config.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/utils/queries.dart'; +import 'package:talawa/view_model/lang_view_model.dart'; import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/view_model/theme_view_model.dart'; +import 'package:talawa/view_model/widgets_view_models/custom_drawer_view_model.dart'; +import 'package:talawa/views/base_view.dart'; +import 'package:talawa/widgets/custom_alert_dialog.dart'; +import 'package:talawa/widgets/custom_drawer.dart'; +import 'package:talawa/widgets/theme_switch.dart'; +import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; + // import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import '../helpers/test_helpers.dart'; // import '../helpers/test_helpers.mocks.dart'; import '../helpers/test_locator.dart'; +import '../model_tests/app_tour_test.dart'; + +Widget createAppTourDialog({bool demoMode = true}) => BaseView( + onModelReady: (model) => model.initialize(), + builder: (context, langModel, child) { + return MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + home: BaseView( + onModelReady: (model2) => model2.initialise( + context, + fromSignUp: false, + mainScreenIndex: 0, + demoMode: demoMode, + testMode: true, + ), + builder: (context, model2, child) { + model2.context = context; + model2.appTour = MockAppTour(model: model2); + model2.pluginPrototypeData.putIfAbsent( + "Plugin1", + () => { + "pluginName": "Plugin1", + "pluginInstallStatus": true, + 'icon': Icons.abc, + 'class': const ChangeThemeTile(), + }, + ); + model2.fetchAndAddPlugins(context); + return Scaffold( + drawer: CustomDrawer(homeModel: model2), + key: MainScreenViewModel.scaffoldKey, + body: model2.appTourDialog(context), + ); + }, + ), + navigatorKey: navigationService.navigatorKey, + onGenerateRoute: router.generateRoute, + ); + }, + ); class MockCallBack extends Mock { void call(); @@ -37,15 +97,47 @@ void verifyInteraction(dynamic x, {required String mockName}) { } } -void main() { +void main() async { + final Directory dir = Directory('test/fixtures/core'); + + Hive.init(dir.path); + // ..registerAdapter(UserAdapter()) + // ..registerAdapter(OrgInfoAdapter()); + + // final userBox = await Hive.openBox('currentUser'); + // final urlBox = await Hive.openBox('url'); + // final orgBox = await Hive.openBox('currentOrg'); + final pluginBox = await Hive.openBox('pluginBox'); + + final List> samplePluginData = [ + { + "pluginName": "Plugin1", + "pluginInstallStatus": true, + }, + // Add more sample plugin data as needed + ]; + + // Store the sample data in the 'plugins' key of 'pluginBox' + pluginBox.put('plugins', samplePluginData); + // No need to change - setUp(() { - locator.registerFactory(() => SizeConfig()); + setUpAll(() { + locator.registerFactory(() => CustomDrawerViewModel()); + locator.registerFactory(() => MainScreenViewModel()); + locator.registerFactory(() => AppTheme()); + locator.registerSingleton(SizeConfig()); + locator.registerFactory(() => Queries()); locator().test(); }); - tearDown(() { + tearDownAll(() { locator.unregister(); + File('test/fixtures/core/currentorg.hive').delete(); + File('test/fixtures/core/currentorg.lock').delete(); + File('test/fixtures/core/currentuser.hive').delete(); + File('test/fixtures/core/currentuser.lock').delete(); + File('test/fixtures/core/pluginbox.hive').delete(); + File('test/fixtures/core/pluginbox.lock').delete(); }); group("MainScreen ViewModel Tests - ", () { @@ -109,6 +201,17 @@ void main() { expect(mainTestModel.currentPageIndex, mainIndex); }); + test('Test for showHome method', () { + final model = getModel(); + + model.showHome( + TargetFocus( + identify: "keyDrawerLeaveCurrentOrg", + keyTarget: MainScreenViewModel.keyDrawerLeaveCurrentOrg, + ), + ); + }); + test( "When fromSignUp is false tourComplete should equal true, tourSkipped and showApptour false", () { @@ -134,6 +237,340 @@ void main() { verifyZeroInteractions(mocknav); }); + testWidgets('Test for apptour dialog skip action.', (tester) async { + await tester.pumpWidget(createAppTourDialog()); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + expect(find.byType(CustomAlertDialog), findsOneWidget); + + // await tester.pumpAndSettle(); + + final skipBtn = find.textContaining('Skip'); + + expect(skipBtn, findsOneWidget); + + await tester.tap(skipBtn); + await tester.pumpAndSettle( + const Duration(seconds: 1), + ); + }); + + testWidgets('Test for apptour dialog success action.', (tester) async { + await tester.pumpWidget(createAppTourDialog()); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final mockUserConfig = getAndRegisterUserConfig(); + when(mockUserConfig.loggedIn).thenReturn(true); + + MainScreenViewModel.scaffoldKey.currentState?.openDrawer(); + + expect(find.byType(CustomAlertDialog), findsOneWidget); + + final startBtn = find.textContaining('Start').last; + + expect(startBtn, findsOneWidget); + + await tester.tap(startBtn); + + await tester.pumpAndSettle(const Duration(seconds: 2)); + }); + + testWidgets('Test for fetchAndAddPlugins when not in demoMode', + (tester) async { + final app = createAppTourDialog(demoMode: false); + + await tester.pumpWidget(app); + await tester.pumpAndSettle(const Duration(seconds: 1)); + }); + + testWidgets('Test for tourhomeTargets.', (tester) async { + final model = getAndRegisterUserConfig(); + const val1 = true; + when(model.loggedIn).thenAnswer((_) => val1); + + // locator.registerFactory(() => CustomDrawerViewModel()); + + late final MainScreenViewModel mainScreenModel; + final app = MaterialApp( + builder: (context, child) => BaseView( + builder: (context, model2, child) { + model2.context = context; + model2.testMode = true; + mainScreenModel = model2; + model2.appTour = MockAppTour(model: model2); + model2.currentPageIndex = 0; + return Scaffold( + key: MainScreenViewModel.scaffoldKey, + drawer: CustomDrawer(homeModel: mainScreenModel), + body: TextButton( + onPressed: () { + model2.showHome( + TargetFocus( + identify: "keySHMenuIcon", + keyTarget: model2.keySHMenuIcon, + ), + ); + model2.tourHomeTargets(); + }, + child: const Text('tour home'), + ), + ); + }, + ), + ); + + await tester.pumpWidget(app); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + expect(find.textContaining('tour home'), findsOneWidget); + + await tester.tap(find.textContaining('tour home')); + + // // ignore: avoid_dynamic_calls + // print(mainScreenModel.targets[1].description); + + // // ignore: avoid_dynamic_calls + // mainScreenModel.targets[5].next!(); + + // verify(navigationService.pop()); + // locator.unregister(); + }); + + // testWidgets('Test for tourhomeTargets.', (tester) async { + // final model = getAndRegisterUserConfig(); + // bool val = false; + // when(model.loggedIn).thenAnswer((_) => val); + + // // locator.registerFactory(() => CustomDrawerViewModel()); + + // late final MainScreenViewModel mainScreenModel; + // final app =BaseView( + // builder: (context, model2, child) { + // model2.context = context; + // model2.testMode = true; + // mainScreenModel = model2; + // model2.currentPageIndex = 0; + // return MaterialApp( + // builder:(context, child) => Scaffold( + // body: Scaffold( + // key: MainScreenViewModel.scaffoldKey, + // drawer: CustomDrawer(homeModel: mainScreenModel), + // body: TextButton(onPressed: () { + // model2.tourHomeTargets(); + // }, child: const Text('tour home')), + // ), + // ) + // ); + // }, + + // ); + + // await tester.pumpWidget(app); + + // await tester.pumpAndSettle(const Duration(seconds: 1)); + + // expect(find.textContaining('tour home'), findsOneWidget); + + // await tester.tap(find.textContaining('tour home')); + + // mainScreenModel.targets[4].next!(); + + // verify(navigationService.pop()); + // }); + + // testWidgets('Test for tourEventTargets.', (tester) async { + // final model = getAndRegisterUserConfig(); + // when(model.loggedIn).thenAnswer((_) => true); + + // final app = BaseView( + // builder: (context, model2, child) { + // model2.context = context; + // model2.testMode = true; + // model2.appTour = MockAppTour(model: model2); + // model2.currentPageIndex = 1; + // return MaterialApp( + // builder: (context, child) => Scaffold( + // body: TextButton( + // onPressed: () { + // model2.tourEventTargets(); + // }, + // child: const Text('tour event targets'), + // ), + // ), + // ); + // }, + // ); + + // await tester.pumpWidget(app); + + // await tester.pumpAndSettle(const Duration(seconds: 1)); + + // expect(find.textContaining('tour event targets'), findsOneWidget); + + // await tester.tap(find.textContaining('tour event targets')); + // }); + + testWidgets('Test for tourChats.', (tester) async { + final model = getAndRegisterUserConfig(); + when(model.loggedIn).thenAnswer((_) => true); + + final app = BaseView( + builder: (context, model2, child) { + model2.context = context; + model2.testMode = true; + model2.appTour = MockAppTour(model: model2); + model2.currentPageIndex = 1; + return MaterialApp( + builder: (context, child) => Scaffold( + body: TextButton( + onPressed: () { + model2.tourChat(); + }, + child: const Text('tour chat targets'), + ), + ), + ); + }, + ); + + await tester.pumpWidget(app); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + expect(find.textContaining('tour chat targets'), findsOneWidget); + + await tester.tap(find.textContaining('tour chat targets')); + }); + + testWidgets('Test for addPost.', (tester) async { + final model = getAndRegisterUserConfig(); + when(model.loggedIn).thenAnswer((_) => true); + + final app = MaterialApp( + builder: (context, child) => BaseView( + builder: (context, model2, child) { + model2.context = context; + model2.testMode = true; + model2.appTour = MockAppTour(model: model2); + model2.currentPageIndex = 1; + return Scaffold( + body: TextButton( + onPressed: () { + model2.tourAddPost(); + }, + child: const Text('tour add post'), + ), + ); + }, + ), + ); + + await tester.pumpWidget(app); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + expect(find.textContaining('tour add post'), findsOneWidget); + + await tester.tap(find.textContaining('tour add post')); + }); + + // testWidgets('Test for profile tour.', (tester) async { + // final model = getAndRegisterUserConfig(); + // when(model.loggedIn).thenAnswer((_) => true); + + // final app = BaseView( + // builder: (context, model2, child) { + // model2.context = context; + // model2.testMode = true; + // model2.appTour = MockAppTour(model: model2); + // model2.currentPageIndex = 1; + // return MaterialApp( + // builder: (context, child) => Scaffold( + // body: TextButton( + // onPressed: () { + // model2.tourProfile(); + // }, + // child: const Text('tour profile'), + // ), + // ), + // ); + // }, + // ); + + // await tester.pumpWidget(app); + + // await tester.pumpAndSettle(const Duration(seconds: 1)); + + // expect(find.textContaining('tour profile'), findsOneWidget); + + // await tester.tap(find.textContaining('tour profile')); + + // // print(mockedModel.targets[5].); + // }); + + // testWidgets('Test for focustarget widget.', (tester) async { + // late MainScreenViewModel mockModel = MainScreenViewModel(); + + // model.focusTarget( model.keyBNChat, 'not', 'ok').contents[] + + // Widget app = BaseView( + // onModelReady: (model) => model.initialize(), + // builder: (context, model, child) { + // return MaterialApp( + // locale: const Locale('en'), + // localizationsDelegates: [ + // const AppLocalizationsDelegate(isTest: true), + // GlobalMaterialLocalizations.delegate, + // GlobalWidgetsLocalizations.delegate, + // ], + // theme: Provider.of(context).isdarkTheme + // ? TalawaTheme.darkTheme + // : TalawaTheme.lightTheme, + // home: BaseView( + // onModelReady: (model2) => model2.initialise(context, fromSignUp: false, mainScreenIndex: 0, testMode: true, demoMode: true), + // builder: (context, model2, child) { + // model2.context = context; + // mockModel = model2; + // return Scaffold( + // body: TextButton( + // child: const Text('press me'), + // onPressed: () { + // model2.tourProfile(); + // model2.showTutorial(onClickTarget: (targetFocus) { + // return TargetFocus(); + // }, onFinish: () { + // return TargetFocus(); + // }); + // }, + // ), + // ); + // }, + // ), + // navigatorKey: navigationService.navigatorKey, + // onGenerateRoute: router.generateRoute, + // ); + // }); + + // await tester.pumpWidget(app); + // await tester.pumpAndSettle(); + + // expect(find.text('press me'), findsOneWidget); + + // await tester.tap(find.text('press me')); + // await tester.pumpAndSettle(); + + // print(mockModel.targets); + + // }); + + // testWidgets('Test for fetchAndAddPlugins.', (tester) async { + + // await tester.pumpWidget(createAppTourDialog(demoMode: false,)); + // await tester.pumpAndSettle(const Duration(seconds: 1)); + + // }); + // test("When fromSignUp is true, App Tour dialog should be displayed", // () async { // final mocknav = getAndRegisterNavigationService(); @@ -157,95 +594,95 @@ void main() { // //Ensures that naviagation service was called // verifyInteraction(mocknav, mockName: "NavigationService"); // }); - }); + // }); + + // group("showTutorial", () { + // final mainTestModel = getModel(); + // test("When called tutorial coach should be assigned a value", () { + // mainTestModel.showTutorial( + // onClickTarget: (TargetFocus x) {}, + // onFinish: () {}, + // ); + // expect(mainTestModel.tutorialCoachMark, isNotNull); + + // // mainTestModel.tutorialCoachMark.skip(); + // }); + // }); - // group("showTutorial", () { - // final mainTestModel = getModel(); - // test("When called tutorial coach should be assigned a value", () { - // mainTestModel.showTutorial( - // onClickTarget: (TargetFocus x) {}, - // onFinish: () {}, - // ); - // expect(mainTestModel.tutorialCoachMark, isNotNull); - - // // mainTestModel.tutorialCoachMark.skip(); - // }); - // }); - - // group("tourHomeTargets", () { - // final mainTestModel = getModel(); - // final TargetFocus testTarget = - // TargetFocus(identify: "TestTarget", keyTarget: mainTestModel.keyBNChat); - // test("target list should be cleared before adding new targets", () { - // //Adding a testtarget before method is called - // mainTestModel.targets.add(testTarget); - // // mainTestModel.context = MockBuildContext(); - // mainTestModel.tourHomeTargets(); - // // targets list should not contain testtarget - // expect(mainTestModel.targets.contains(testTarget), false); - // }); - // }); - - // group("tourEventTargets", () { - // final mainTestModel = getModel(); - // test("target list should be cleared before adding new targets", () { - // final TargetFocus testTarget = TargetFocus( - // identify: "TestTarget", - // keyTarget: mainTestModel.keyBNChat, - // ); - // //Adding a target before method is called - // mainTestModel.targets.add(testTarget); - - // mainTestModel.tourEventTargets(); - // // targets list should not contain target - // expect(mainTestModel.targets.contains(testTarget), false); - // }); - // }); - - // group("tourAddPost", () { - // final mainTestModel = getModel(); - // test("target list should be cleared before adding new targets", () { - // final TargetFocus testTarget = TargetFocus( - // identify: "TestTarget", - // keyTarget: mainTestModel.keyBNChat, - // ); - // //Adding a target before method is called - // mainTestModel.targets.add(testTarget); - - // mainTestModel.tourAddPost(); - // // targets list should not contain target - // expect(mainTestModel.targets.contains(testTarget), false); - // }); - // }); - // group("tourChat", () { - // final mainTestModel = getModel(); - // test("target list should be cleared before adding new targets", () { - // final TargetFocus testTarget = TargetFocus( - // identify: "TestTarget", - // keyTarget: mainTestModel.keyBNChat, - // ); - // //Adding a target before method is called - // mainTestModel.targets.add(testTarget); - - // mainTestModel.tourChat(); - // // targets list should not contain target - // expect(mainTestModel.targets.contains(testTarget), false); - // }); - // }); - - // group("tourProfile", () { - // final mainTestModel = getModel(); - // test("target list should be cleared before adding new targets", () { - // final TargetFocus testTarget = TargetFocus( - // identify: "TestTarget", - // keyTarget: mainTestModel.keyBNChat, - // ); - // //Adding a target before method is called - // mainTestModel.targets.add(testTarget); - - // mainTestModel.tourProfile(); - // // targets list should not contain target - // expect(mainTestModel.targets.contains(testTarget), false); - // }); - // }); + // group("tourHomeTargets", () { + // final mainTestModel = getModel(); + // final TargetFocus testTarget = + // TargetFocus(identify: "TestTarget", keyTarget: mainTestModel.keyBNChat); + // test("target list should be cleared before adding new targets", () { + // //Adding a testtarget before method is called + // mainTestModel.targets.add(testTarget); + // // mainTestModel.context = MockBuildContext(); + // mainTestModel.tourHomeTargets(); + // // targets list should not contain testtarget + // expect(mainTestModel.targets.contains(testTarget), false); + // }); + // }); + + // group("tourEventTargets", () { + // final mainTestModel = getModel(); + // test("target list should be cleared before adding new targets", () { + // final TargetFocus testTarget = TargetFocus( + // identify: "TestTarget", + // keyTarget: mainTestModel.keyBNChat, + // ); + // //Adding a target before method is called + // mainTestModel.targets.add(testTarget); + + // mainTestModel.tourEventTargets(); + // // targets list should not contain target + // expect(mainTestModel.targets.contains(testTarget), false); + // }); + // }); + + // group("tourAddPost", () { + // final mainTestModel = getModel(); + // test("target list should be cleared before adding new targets", () { + // final TargetFocus testTarget = TargetFocus( + // identify: "TestTarget", + // keyTarget: mainTestModel.keyBNChat, + // ); + // //Adding a target before method is called + // mainTestModel.targets.add(testTarget); + + // mainTestModel.tourAddPost(); + // // targets list should not contain target + // expect(mainTestModel.targets.contains(testTarget), false); + // }); + // }); + // group("tourChat", () { + // final mainTestModel = getModel(); + // test("target list should be cleared before adding new targets", () { + // final TargetFocus testTarget = TargetFocus( + // identify: "TestTarget", + // keyTarget: mainTestModel.keyBNChat, + // ); + // //Adding a target before method is called + // mainTestModel.targets.add(testTarget); + + // mainTestModel.tourChat(); + // // targets list should not contain target + // expect(mainTestModel.targets.contains(testTarget), false); + // }); + // }); + + // group("tourProfile", () { + // final mainTestModel = getModel(); + // test("target list should be cleared before adding new targets", () { + // final TargetFocus testTarget = TargetFocus( + // identify: "TestTarget", + // keyTarget: mainTestModel.keyBNChat, + // ); + // //Adding a target before method is called + // mainTestModel.targets.add(testTarget); + + // mainTestModel.tourProfile(); + // // targets list should not contain target + // expect(mainTestModel.targets.contains(testTarget), false); + // }); + }); } diff --git a/test/view_model_tests/pre_auth_view_models/select_organization_view_model_test.dart b/test/view_model_tests/pre_auth_view_models/select_organization_view_model_test.dart index 06c9fc6d4..7d6770aac 100644 --- a/test/view_model_tests/pre_auth_view_models/select_organization_view_model_test.dart +++ b/test/view_model_tests/pre_auth_view_models/select_organization_view_model_test.dart @@ -743,10 +743,16 @@ void main() { (FetchMoreOptions options) async { expected = options.updateQuery( { - "organizationsConnection": [1, 2], + "organizationsConnection": [ + {"one": 1}, + {"two": 2}, + ], }, { - "organizationsConnection": [3, 4], + "organizationsConnection": [ + {"three": 3}, + {"four": 4}, + ], }, ); return Future.value( @@ -761,8 +767,10 @@ void main() { expect(expected, { 'organizationsConnection': [ - [1, 2], - [3, 4], + {"one": 1}, + {"two": 2}, + {"three": 3}, + {"four": 4}, ], }); }); diff --git a/test/views/after_auth_screens/events/create_event_page_test.dart b/test/views/after_auth_screens/events/create_event_page_test.dart index 2e794d78e..1cf338c8b 100644 --- a/test/views/after_auth_screens/events/create_event_page_test.dart +++ b/test/views/after_auth_screens/events/create_event_page_test.dart @@ -18,6 +18,7 @@ import 'package:talawa/views/base_view.dart'; import '../../../helpers/test_helpers.dart'; import '../../../helpers/test_locator.dart'; +import '../../../widget_tests/after_auth_screens/events/create_event_form_test.dart'; class MockCallbackFunction extends Mock { void call(); @@ -136,6 +137,24 @@ void main() { await tester.tap(inkwellFinder.at(2)); await tester.pump(); }); + testWidgets('Test Add Button', (tester) async { + await tester.pumpWidget( + createEventScreen( + themeMode: ThemeMode.dark, + theme: TalawaTheme.darkTheme, + ), + ); + await tester.pumpAndSettle(); + + when(userConfig.loggedIn).thenReturn(true); + + final addBtn = find.byKey(const Key('addButton')); + + await tester.tap(addBtn); + await tester.pumpAndSettle(); + + expect(createEventViewModel.validate, AutovalidateMode.disabled); + }); testWidgets("Checking tap Inkwell for setDate 2 datetime", (tester) async { await tester.pumpWidget( createEventScreen( diff --git a/test/views/after_auth_screens/profile/profile_page_test.dart b/test/views/after_auth_screens/profile/profile_page_test.dart new file mode 100644 index 000000000..8a4e4861b --- /dev/null +++ b/test/views/after_auth_screens/profile/profile_page_test.dart @@ -0,0 +1,82 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:hive/hive.dart'; +import 'package:talawa/constants/custom_theme.dart'; +import 'package:talawa/models/organization/org_info.dart'; +import 'package:talawa/models/user/user_info.dart'; +import 'package:talawa/router.dart' as router; +import 'package:talawa/services/size_config.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/view_model/lang_view_model.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/views/after_auth_screens/profile/profile_page.dart'; +import 'package:talawa/views/base_view.dart'; + +import '../../../helpers/test_helpers.dart'; +import '../../../helpers/test_locator.dart'; + +Widget createProfilePage({required MainScreenViewModel mainScreenViewModel}) { + return BaseView( + onModelReady: (model) => model.initialize(), + builder: (context, langModel, child) { + return MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + home: Scaffold( + body: ProfilePage( + key: const Key('Profile Page'), + homeModel: mainScreenViewModel, + ), + ), + navigatorKey: navigationService.navigatorKey, + onGenerateRoute: router.generateRoute, + theme: TalawaTheme.darkTheme, + ); + }, + ); +} + +void main() async { + testSetupLocator(); + locator().test(); + final Directory dir = Directory('test/fixtures/core'); + group('build', () { + setUpAll(() async { + registerServices(); + getAndRegisterAppTheme(); + Hive + ..init(dir.path) + ..registerAdapter(UserAdapter()) + ..registerAdapter(OrgInfoAdapter()); + await Hive.openBox('currentUser'); + await Hive.openBox('currentOrg'); + final pbox = await Hive.openBox('pluginBox'); + print(pbox.get('plugins')); + // locator.unregister(); + // locator.registerFactory(() => ProfilePageViewModel()); + }); + + tearDownAll(() { + File('test/fixtures/core/currentorg.hive').delete(); + File('test/fixtures/core/currentorg.lock').delete(); + File('test/fixtures/core/currentuser.hive').delete(); + File('test/fixtures/core/currentuser.lock').delete(); + }); + testWidgets('check if profilePage shows up', (tester) async { + // print(); + await tester.pumpWidget( + createProfilePage( + mainScreenViewModel: locator(), + ), + ); + await tester.pumpAndSettle(); + }); + }); +} diff --git a/test/views/demo_screens/explore_events_demo_test.dart b/test/views/demo_screens/explore_events_demo_test.dart new file mode 100644 index 000000000..599982920 --- /dev/null +++ b/test/views/demo_screens/explore_events_demo_test.dart @@ -0,0 +1,226 @@ +// ignore_for_file: talawa_api_doc +// ignore_for_file: talawa_good_doc_comments + +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:talawa/constants/routing_constants.dart'; +import 'package:talawa/models/events/event_model.dart'; +import 'package:talawa/models/user/user_info.dart'; +import 'package:talawa/router.dart' as router; +import 'package:talawa/services/size_config.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/view_model/after_auth_view_models/event_view_models/explore_events_view_model.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/views/after_auth_screens/events/explore_event_dialogue.dart'; +import 'package:talawa/views/demo_screens/explore_events_demo.dart'; +import 'package:talawa/widgets/custom_drawer.dart'; +import 'package:talawa/widgets/event_card.dart'; + +import '../../helpers/test_helpers.dart'; +import '../../helpers/test_locator.dart'; + +// class MockBuildContext extends Mock implements BuildContext {} + +Widget createExploreEventsScreen(MainScreenViewModel model) => MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + key: const Key('Root'), + home: Scaffold( + key: MainScreenViewModel.scaffoldKey, + drawer: CustomDrawer( + homeModel: model, + ), + body: const DemoExploreEvents( + key: Key('ExploreEvents'), + ), + ), + navigatorKey: navigationService.navigatorKey, + onGenerateRoute: router.generateRoute, + ); + +void main() async { + SizeConfig().test(); + + final mockEvents = [ + Event( + id: 'event1', + admins: [User(id: 'admin1')], + creator: User(id: 'admin2'), + startTime: DateTime.now().day.toString(), + endTime: DateTime.now().day.toString(), + title: 'event title', + startDate: DateTime.now().day.toString(), + endDate: DateTime.now().day.toString(), + location: 'location', + description: 'description', + isPublic: true, + ), + ]; + + late ExploreEventsViewModel exploreEventsViewModel; + group('Test for DemoExploreEventsPage', () { + setUpAll(() { + registerServices(); + registerViewModels(); + exploreEventsViewModel = getAndRegisterExploreEventsViewModel(); + }); + tearDownAll(() { + unregisterServices(); + unregisterViewModels(); + }); + testWidgets('Test for menu button.', (tester) async { + final model = MainScreenViewModel(); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final menuButton = find.byIcon(Icons.menu); + + await tester.tap(menuButton); + await tester.pumpAndSettle(); + + expect(find.byType(CustomDrawer), findsOneWidget); + }); + + testWidgets('Test for AddDate button.', (tester) async { + final model = MainScreenViewModel(); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final addDateButton = find.textContaining('Add Date'); + + await tester.tap(addDateButton); + await tester.pumpAndSettle(); + + expect(find.byType(ExploreEventDialog), findsOneWidget); + }); + + testWidgets('Test for Calendar button', (tester) async { + final model = MainScreenViewModel(); + final mockModel = ExploreEventsViewModel(); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final calendarBtn = find.byIcon(Icons.calendar_month); + + expect(calendarBtn, findsOneWidget); + + await tester.tap(calendarBtn); + await tester.pumpAndSettle(); + + verify( + navigationService.pushScreen( + Routes.calendar, + arguments: mockModel.events, + ), + ); + }); + + testWidgets('Test for floatingAction button', (tester) async { + final model = MainScreenViewModel(); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final floatingBtn = find.byType(FloatingActionButton); + + expect(floatingBtn, findsOneWidget); + + await tester.tap(floatingBtn); + await tester.pumpAndSettle(); + + verify( + navigationService.pushScreen( + "/createEventPage", + ), + ); + }); + + testWidgets('Test for eventCard.', (tester) async { + final model = MainScreenViewModel(); + when(exploreEventsViewModel.events).thenAnswer((_) { + return mockEvents; + }); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final eventCard = find.byType(EventCard).first; + + expect(eventCard, findsOneWidget); + + await tester.tap(eventCard); + await tester.pumpAndSettle(); + + verify( + navigationService.navigatorKey, + ); + }); + + testWidgets('Test for dropDown button', (tester) async { + final model = MainScreenViewModel(); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final dropDownBtn = find.byType(DropdownButton); + + await tester.tap(dropDownBtn); + await tester.pumpAndSettle(); + + final createEventsBtn = find.textContaining('Created Events'); + + expect(createEventsBtn, findsOneWidget); + + await tester.tap(createEventsBtn); + await tester.pumpAndSettle(); + }); + + testWidgets('Test for ExploreEvent dialog', (tester) async { + final model = MainScreenViewModel(); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final dropDownBtn = find.byType(DropdownButton); + + await tester.tap(dropDownBtn); + await tester.pumpAndSettle(); + + final createEventsBtn = find.textContaining('Created Events'); + + expect(createEventsBtn, findsOneWidget); + + await tester.tap(createEventsBtn); + await tester.pumpAndSettle(); + }); + + testWidgets('Test for layout when zero events', (tester) async { + final model = MainScreenViewModel(); + when(exploreEventsViewModel.events).thenReturn([]); + await tester.pumpWidget(createExploreEventsScreen(model)); + + await tester.pumpAndSettle(); + + final dropDownBtn = find.byType(DropdownButton); + + await tester.tap(dropDownBtn); + await tester.pumpAndSettle(); + + final createEventsBtn = find.textContaining('Created Events'); + + expect(createEventsBtn, findsOneWidget); + + await tester.tap(createEventsBtn); + await tester.pumpAndSettle(); + }); + }); +} diff --git a/test/views/demo_screens/organization_feed_demo_test.dart b/test/views/demo_screens/organization_feed_demo_test.dart new file mode 100644 index 000000000..0767d0bea --- /dev/null +++ b/test/views/demo_screens/organization_feed_demo_test.dart @@ -0,0 +1,64 @@ +// ignore_for_file: talawa_api_doc +// ignore_for_file: talawa_good_doc_comments + +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:talawa/constants/custom_theme.dart'; +import 'package:talawa/models/mainscreen_navigation_args.dart'; +import 'package:talawa/services/graphql_config.dart'; +import 'package:talawa/services/size_config.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/views/main_screen.dart'; + +import '../../helpers/test_helpers.dart'; +import '../../helpers/test_locator.dart'; + +class MockBuildContext extends Mock implements BuildContext {} + +Widget createHomeScreen({required bool demoMode}) { + return MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + themeMode: ThemeMode.light, + theme: TalawaTheme.lightTheme, + home: MainScreen( + key: const Key('MainScreen'), + mainScreenArgs: MainScreenArgs( + mainScreenIndex: 0, + fromSignUp: false, + toggleDemoMode: demoMode, + ), + ), + ); +} + +void main() async { + testSetupLocator(); + + setUp(() { + registerServices(); + locator().test(); + locator().test(); + }); + + group('Home Page tests', () { + testWidgets('Test for menu button.', (tester) async { + await tester.pumpWidget(createHomeScreen(demoMode: true)); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final menuButton = find.byIcon(Icons.menu); + + await tester.tap(menuButton); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key("Drawer")), findsOneWidget); + }); + }); +} diff --git a/test/views/demo_screens/profile_page_demo_test.dart b/test/views/demo_screens/profile_page_demo_test.dart new file mode 100644 index 000000000..bfe863406 --- /dev/null +++ b/test/views/demo_screens/profile_page_demo_test.dart @@ -0,0 +1,77 @@ +// ignore_for_file: talawa_api_doc +// ignore_for_file: talawa_good_doc_comments + +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:talawa/constants/custom_theme.dart'; +import 'package:talawa/models/mainscreen_navigation_args.dart'; +import 'package:talawa/services/graphql_config.dart'; +import 'package:talawa/services/size_config.dart'; +import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/views/main_screen.dart'; + +import '../../helpers/test_helpers.dart'; +import '../../helpers/test_locator.dart'; + +class MockBuildContext extends Mock implements BuildContext {} + +Widget createProfileScreen({required bool demoMode}) { + return MaterialApp( + locale: const Locale('en'), + localizationsDelegates: [ + const AppLocalizationsDelegate(isTest: true), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + themeMode: ThemeMode.light, + theme: TalawaTheme.lightTheme, + home: MainScreen( + key: const Key('MainScreen'), + mainScreenArgs: MainScreenArgs( + mainScreenIndex: 2, + fromSignUp: false, + toggleDemoMode: demoMode, + ), + ), + ); +} + +void main() async { + testSetupLocator(); + + setUp(() { + registerServices(); + locator().test(); + locator().test(); + }); + + group('Profile Page tests', () { + testWidgets('Test for donate button.', (tester) async { + await tester.pumpWidget(createProfileScreen(demoMode: true)); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final donateButton = find.textContaining('Donate to the Community'); + + await tester.tap(donateButton); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key("Drawer")), findsOneWidget); + }); + + testWidgets('Test for menu button.', (tester) async { + await tester.pumpWidget(createProfileScreen(demoMode: true)); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final menuButton = find.byIcon(Icons.menu); + + await tester.tap(menuButton); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key("Drawer")), findsOneWidget); + }); + }); +} diff --git a/test/views/main_screen_test.dart b/test/views/main_screen_test.dart index 4c1e2d512..f9a5afc12 100644 --- a/test/views/main_screen_test.dart +++ b/test/views/main_screen_test.dart @@ -12,6 +12,7 @@ import 'package:mockito/mockito.dart'; // import 'package:mocktail_image_network/mocktail_image_network.dart'; import 'package:provider/provider.dart'; import 'package:talawa/constants/custom_theme.dart'; +import 'package:talawa/constants/routing_constants.dart'; import 'package:talawa/models/mainscreen_navigation_args.dart'; import 'package:talawa/models/organization/org_info.dart'; import 'package:talawa/models/user/user_info.dart'; @@ -21,6 +22,7 @@ import 'package:talawa/services/navigation_service.dart'; import 'package:talawa/services/size_config.dart'; import 'package:talawa/utils/app_localization.dart'; import 'package:talawa/view_model/lang_view_model.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; import 'package:talawa/view_model/theme_view_model.dart'; // import 'package:talawa/views/after_auth_screens/add_post_page.dart'; // import 'package:talawa/views/after_auth_screens/events/explore_events.dart'; @@ -33,7 +35,7 @@ import 'package:talawa/views/main_screen.dart'; import '../helpers/test_helpers.dart'; import '../helpers/test_locator.dart'; -Widget createMainScreen() { +Widget createMainScreen({bool demoMode = true}) { return BaseView( onModelReady: (model) => model.initialize(), builder: (context, model, child) { @@ -56,6 +58,7 @@ Widget createMainScreen() { mainScreenArgs: MainScreenArgs( fromSignUp: false, mainScreenIndex: 0, + toggleDemoMode: demoMode, ), ), ), @@ -68,6 +71,29 @@ Widget createMainScreen() { ); } +class MockMainScreenViewModel extends Mock implements MainScreenViewModel { + @override + int get currentPageIndex => 0; + + @override + List get pages => [const Test(key: Key('key'))]; + + @override + List get navBarItems => [ + const BottomNavigationBarItem(icon: Icon(Icons.abc), label: 'label1'), + const BottomNavigationBarItem(icon: Icon(Icons.abc), label: 'label2'), + ]; +} + +class Test extends StatelessWidget { + const Test({super.key}); + + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} + void main() async { testSetupLocator(); registerServices(); @@ -93,6 +119,9 @@ void main() async { setUp(() { registerServices(); locator().test(); + locator.unregister(); + locator + .registerFactory(() => MockMainScreenViewModel()); graphQLClient = locator(); when( @@ -119,9 +148,21 @@ void main() async { }); group("Test for main_screen.dart", () { - // testWidgets("Check if MainScreen shows up", (tester) async { - // await tester.pumpWidget(createMainScreen()); - // await tester.pump(); + testWidgets('Test join org banner.', (tester) async { + await tester.pumpWidget(createMainScreen()); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + final bannerFinder = find.byKey(const Key('banner')); + + await tester.tap(bannerFinder); + + verify(navigationService.pushScreen(Routes.setUrlScreen, arguments: '')); + }); + + testWidgets("Test if Join Org banner not visible.", (tester) async { + await tester.pumpWidget(createMainScreen(demoMode: false)); + await tester.pump(); + }); // // // Don't call pumpAndSettle as the BottomNavigationBar // // of this widget builds itself repeatedly, causing an infinite diff --git a/test/widget_tests/after_auth_screens/add_post_page_test.dart b/test/widget_tests/after_auth_screens/add_post_page_test.dart index af7e69778..f9f15117c 100644 --- a/test/widget_tests/after_auth_screens/add_post_page_test.dart +++ b/test/widget_tests/after_auth_screens/add_post_page_test.dart @@ -7,9 +7,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import 'package:talawa/services/size_config.dart'; import 'package:talawa/services/third_party_service/multi_media_pick_service.dart'; import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/view_model/after_auth_view_models/add_post_view_models/add_post_view_model.dart'; import 'package:talawa/view_model/main_screen_view_model.dart'; import 'package:talawa/views/after_auth_screens/add_post_page.dart'; @@ -17,6 +17,38 @@ import '../../helpers/test_helpers.dart'; import '../../helpers/test_locator.dart'; final homeModel = locator(); +bool removeImageCalled = false; + +class MockAddPostViewModel extends Mock implements AddPostViewModel { + final _textHashTagController = TextEditingController(text: ''); + final _controller = TextEditingController(text: ''); + final _titleController = TextEditingController(text: ''); + + @override + File? get imageFile { + return File('example'); + } + + @override + String get userName => 'UserName'; + + @override + String get orgName => 'orgName'; + + @override + TextEditingController get textHashTagController => _textHashTagController; + + @override + TextEditingController get controller => _controller; + + @override + TextEditingController get titleController => _titleController; + + // @override + // void removeImage() { + // removeImageCalled = true; + // } +} Widget createAddPostScreen({ bool reverse = false, @@ -53,7 +85,7 @@ Widget createAddPostScreen({ } void main() { - SizeConfig().test(); + // SizeConfig().test(); testSetupLocator(); // locator.registerSingleton(LikeButtonViewModel()); @@ -419,5 +451,23 @@ void main() { await tester.tap(finder); await tester.pump(); }); + + testWidgets('check if remove Image button works', (tester) async { + locator.unregister(); + final mockModel = + locator.registerSingleton(MockAddPostViewModel()); + + when(mockModel.removeImage()).thenAnswer((_) {}); + + await tester.pumpWidget(createAddPostScreen()); + await tester.pump(); + + final removeImageBtn = + tester.widget(find.byKey(const Key('remove_icon'))) as IconButton; + + removeImageBtn.onPressed!(); + + verify(mockModel.removeImage()); + }); }); } diff --git a/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart b/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart index a209bcdd7..f2c5d7bd0 100644 --- a/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart +++ b/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart @@ -103,6 +103,18 @@ Future main() async { .scaffoldBackgroundColor, TalawaTheme.darkTheme.scaffoldBackgroundColor, ); + + final backButton = find.byIcon(Icons.arrow_back); + + await tester.tap(backButton); + await tester.pumpAndSettle(); + + expect( + find.byKey( + const Key('AppSettingScaffold'), + ), + findsNothing, + ); }); testWidgets( "Testing if Settings Screen shows up in dark mode with Theme selection tile", diff --git a/test/widget_tests/after_auth_screens/feed/organization_feed_test.dart b/test/widget_tests/after_auth_screens/feed/organization_feed_test.dart index f60b6f6c5..bc08c8142 100644 --- a/test/widget_tests/after_auth_screens/feed/organization_feed_test.dart +++ b/test/widget_tests/after_auth_screens/feed/organization_feed_test.dart @@ -102,81 +102,84 @@ void main() { }); TestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('check if createOrganizationFeedScreen shows up', (tester) async { - final model = locator(); - await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); - await tester.pump(); + group('tests for Organizaiton feed Screen', () { + testWidgets('check if createOrganizationFeedScreen shows up', + (tester) async { + final model = locator(); + await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); + await tester.pump(); - final finder = find.byType(Scaffold); + final finder = find.byType(Scaffold); - expect(finder, findsNWidgets(2)); - }); - testWidgets('check if orgname is displayed shows up', (tester) async { - final model = locator(); - await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); - await tester.pump(); - - final finder = find.byType(Text); - expect(finder, findsNWidgets(9)); - // expect(text, findsOneWidget); - }); - testWidgets('check if side drawer shows up', (tester) async { - final model = locator(); - await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); - await tester.pump(); + expect(finder, findsNWidgets(2)); + }); + testWidgets('check if orgname is displayed shows up', (tester) async { + final model = locator(); + await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); + await tester.pump(); + + final finder = find.byType(Text); + expect(finder, findsNWidgets(9)); + // expect(text, findsOneWidget); + }); + testWidgets('check if side drawer shows up', (tester) async { + final model = locator(); + await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); + await tester.pump(); - final finder = find.byIcon(Icons.menu); + final finder = find.byIcon(Icons.menu); - await tester.tap(finder); - await tester.pump(); - }); - testWidgets('check if post shows up when model.posts.isNotEmpty is true', - (tester) async { - final model = locator(); - await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); - await tester.pump(); + await tester.tap(finder); + await tester.pump(); + }); + testWidgets('check if post shows up when model.posts.isNotEmpty is true', + (tester) async { + final model = locator(); + await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); + await tester.pump(); - final finder = find.byIcon(Icons.menu); + final finder = find.byIcon(Icons.menu); - await tester.tap(finder); - await tester.pump(); - }); - testWidgets('check if refresh indicator is launched on dragging', - (tester) async { - final model = locator(); - await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); - await tester.pump(); - final postservice = locator(); - bool refreshed = false; - - when(postservice.getPosts()).thenAnswer((_) async { - refreshed = true; + await tester.tap(finder); + await tester.pump(); }); + testWidgets('check if refresh indicator is launched on dragging', + (tester) async { + final model = locator(); + await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); + await tester.pump(); + final postservice = locator(); + bool refreshed = false; + + when(postservice.getPosts()).thenAnswer((_) async { + refreshed = true; + }); + + await tester.drag( + find.byType(RefreshIndicator), + const Offset(0, 200), + ); + await tester.pumpAndSettle(); - await tester.drag( - find.byType(RefreshIndicator), - const Offset(0, 200), - ); - await tester.pumpAndSettle(); - - expect(refreshed, true); - }); - testWidgets( - 'check if post shows up when model.posts.isNotEmpty is true and post', - (tester) async { - final model = locator(); - await tester.pumpWidget(createOrganizationFeedScreen2(homeModel: model)); - await tester.pumpAndSettle(const Duration(seconds: 1)); - }); - testWidgets('check if floating action button is visible and functional', - (tester) async { - final model = locator(); - await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); - await tester.pump(); - final fabFinder = find.byKey(const Key('floating_action_btn')); - expect(fabFinder, findsOneWidget); - await tester.tap(fabFinder); - await tester.pump(); - verify(navigationService.pushScreen('/addpostscreen')).called(1); + expect(refreshed, true); + }); + testWidgets( + 'check if post shows up when model.posts.isNotEmpty is true and post', + (tester) async { + final model = locator(); + await tester.pumpWidget(createOrganizationFeedScreen2(homeModel: model)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + }); + testWidgets('check if floating action button is visible and functional', + (tester) async { + final model = locator(); + await tester.pumpWidget(createOrganizationFeedScreen(homeModel: model)); + await tester.pump(); + final fabFinder = find.byKey(const Key('floating_action_btn')); + expect(fabFinder, findsOneWidget); + await tester.tap(fabFinder); + await tester.pump(); + verify(navigationService.pushScreen('/addpostscreen')).called(1); + }); }); } diff --git a/test/widget_tests/pre_auth_screens/select_language_page_test.dart b/test/widget_tests/pre_auth_screens/select_language_page_test.dart index 4d72642db..cafd870c4 100644 --- a/test/widget_tests/pre_auth_screens/select_language_page_test.dart +++ b/test/widget_tests/pre_auth_screens/select_language_page_test.dart @@ -165,11 +165,11 @@ Future main() async { BoxDecoration(color: const Color(0xFFC4C4C4).withOpacity(0.15)), ); }); - testWidgets("Testing to navigate to url page", (tester) async { + testWidgets("Testing to navigate to MainScreen", (tester) async { await tester.pumpWidget(createSelectLanguageScreenLight()); await tester.pumpAndSettle(); - final findAppNameWidget = find.byKey(const Key('NavigateToUrlPage')); + final findAppNameWidget = find.byKey(const Key('NavigateToMainScreen')); await tester.tap(findAppNameWidget); await tester.pumpAndSettle(const Duration(seconds: 3)); @@ -287,9 +287,9 @@ Future main() async { testWidgets("Testing to navigate to url page", (tester) async { await tester.pumpWidget(createSelectLanguageScreenDark()); await tester.pumpAndSettle(); - final findAppNameWidget = find.byKey(const Key('NavigateToUrlPage')); + final findAppNameWidget = find.byKey(const Key('NavigateToMainScreen')); await tester.tap(findAppNameWidget); - await tester.pumpAndSettle(); + await tester.pumpAndSettle(const Duration(seconds: 3)); expect(findAppNameWidget, findsNothing); }); }); diff --git a/test/widget_tests/widgets/custom_drawer_test.dart b/test/widget_tests/widgets/custom_drawer_test.dart index 55303f3d6..850a49985 100644 --- a/test/widget_tests/widgets/custom_drawer_test.dart +++ b/test/widget_tests/widgets/custom_drawer_test.dart @@ -1,18 +1,27 @@ // ignore_for_file: talawa_api_doc // ignore_for_file: talawa_good_doc_comments +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:hive/hive.dart'; import 'package:mockito/mockito.dart'; import 'package:talawa/constants/custom_theme.dart'; +import 'package:talawa/constants/routing_constants.dart'; import 'package:talawa/models/mainscreen_navigation_args.dart'; +import 'package:talawa/models/organization/org_info.dart'; +import 'package:talawa/models/user/user_info.dart'; import 'package:talawa/services/graphql_config.dart'; // import 'package:talawa/services/navigation_service.dart'; import 'package:talawa/services/size_config.dart'; import 'package:talawa/utils/app_localization.dart'; +import 'package:talawa/view_model/main_screen_view_model.dart'; +import 'package:talawa/view_model/widgets_view_models/custom_drawer_view_model.dart'; // import 'package:talawa/view_model/main_screen_view_model.dart'; import 'package:talawa/views/main_screen.dart'; +import 'package:talawa/widgets/custom_alert_dialog.dart'; // import 'package:talawa/widgets/custom_alert_dialog.dart'; import '../../helpers/test_helpers.dart'; // import '../../helpers/test_helpers.mocks.dart'; @@ -20,7 +29,34 @@ import '../../helpers/test_locator.dart'; class MockBuildContext extends Mock implements BuildContext {} -Widget createHomePageScreen() { +bool _switchOrgcalled = false; + +class MockCustomDrawerViewModel extends Mock implements CustomDrawerViewModel { + final _scrollController = ScrollController(); + @override + ScrollController get controller => _scrollController; + @override + List get switchAbleOrg { + print("hi"); + return [OrgInfo(id: 'test1', name: 'name')]; + } + + @override + OrgInfo get selectedOrg => OrgInfo(id: 'test1', name: 'name'); + @override + void switchOrg(OrgInfo orginfo) { + _switchOrgcalled = true; + } +} + +class MockScrollController extends Mock implements ScrollController { + @override + ScrollPosition get position => MockScrollPosition(); +} + +class MockScrollPosition extends Mock implements ScrollPosition {} + +Widget createHomePageScreen({required bool demoMode}) { return MaterialApp( locale: const Locale('en'), localizationsDelegates: [ @@ -32,12 +68,16 @@ Widget createHomePageScreen() { theme: TalawaTheme.lightTheme, home: MainScreen( key: const Key('MainScreen'), - mainScreenArgs: MainScreenArgs(mainScreenIndex: 0), + mainScreenArgs: MainScreenArgs( + mainScreenIndex: 0, + fromSignUp: false, + toggleDemoMode: demoMode, + ), ), ); } -void main() { +void main() async { testSetupLocator(); setUp(() { @@ -46,6 +86,19 @@ void main() { locator().test(); }); + final Directory dir = Directory('test/fixtures/core'); + + Hive + ..init(dir.path) + ..registerAdapter(UserAdapter()) + ..registerAdapter(OrgInfoAdapter()); + + await Hive.openBox('currentUser'); + await Hive.openBox('currentOrg'); + + await Hive.openBox('pluginBox'); + await Hive.openBox('url'); + group('Exit Button', () { /* testWidgets("Tapping Tests for Exit", (tester) async { await tester.pumpWidget(createHomePageScreen()); @@ -65,6 +118,138 @@ void main() { dialogPopUP[0].success(); });*/ }); + + group('Test Organization action Buttons', () { + testWidgets('Test Join Organization Button when user not logged in.', + (tester) async { + await tester.pumpWidget(createHomePageScreen(demoMode: true)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // if user not logged in + when(userConfig.loggedIn).thenReturn(false); + + MainScreenViewModel.scaffoldKey.currentState?.openDrawer(); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key('Drawer')), findsOneWidget); + + final buttonFinder = find.byKey(MainScreenViewModel.keyDrawerJoinOrg); + + await tester.tap(buttonFinder); + await tester.pumpAndSettle(); + + when( + navigationService.popAndPushScreen( + Routes.setUrlScreen, + arguments: '', + ), + ).thenAnswer((_) async {}); + + verify( + navigationService.popAndPushScreen( + Routes.setUrlScreen, + arguments: '', + ), + ); + }); + + testWidgets('Test leave current Organization Button.', (tester) async { + await tester.pumpWidget(createHomePageScreen(demoMode: true)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // if user not logged in + when(userConfig.loggedIn).thenReturn(true); + + MainScreenViewModel.scaffoldKey.currentState?.openDrawer(); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key('Drawer')), findsOneWidget); + + final buttonFinder = find.byKey( + MainScreenViewModel.keyDrawerLeaveCurrentOrg, + ); + + final tmp = CustomAlertDialog( + key: const Key("Exit?"), + reverse: true, + dialogSubTitle: 'Are you sure you want to exit this organization?', + successText: 'Exit', + success: () { + //Exit org + }, + ); + + when( + navigationService.pushDialog(tmp), + ).thenAnswer((realInvocation) async {}); + + await tester.ensureVisible(buttonFinder); + await tester.pumpAndSettle(); + + await tester.tap(buttonFinder); + await tester.pumpAndSettle(); + + verifyNever(navigationService.pushDialog(tmp)).called(0); + // expect(find.text('Exit'), findsOneWidget); + }); + + testWidgets('Test Join Organization Button when user logged in.', + (tester) async { + await tester.pumpWidget(createHomePageScreen(demoMode: true)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // if user not logged in + when(userConfig.loggedIn).thenReturn(true); + + MainScreenViewModel.scaffoldKey.currentState?.openDrawer(); + await tester.pumpAndSettle(); + + final buttonFinder = find.byKey(MainScreenViewModel.keyDrawerJoinOrg); + + await tester.tap(buttonFinder); + await tester.pumpAndSettle(); + + when( + navigationService.popAndPushScreen( + Routes.joinOrg, + arguments: '-1', + ), + ).thenAnswer((_) async {}); + + verify( + navigationService.popAndPushScreen( + Routes.joinOrg, + arguments: '-1', + ), + ); + }); + + testWidgets('Test Switch org list.', (tester) async { + await tester.pumpWidget(createHomePageScreen(demoMode: true)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + locator.unregister(); + + locator.registerSingleton( + MockCustomDrawerViewModel(), + ); + + // if user not logged in + when(userConfig.loggedIn).thenReturn(false); + + MainScreenViewModel.scaffoldKey.currentState?.openDrawer(); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key('Switching Org')), findsOneWidget); + + final buttonFinder = find.byKey(const Key('Org')); + + await tester.tap(buttonFinder); + + expect(_switchOrgcalled, true); + }); + }); + group('Custom Drawer Test', () { /*testWidgets("Widget Testing", (tester) async { // pumping the Widget diff --git a/test/widget_tests/widgets/pinned_post_test.dart b/test/widget_tests/widgets/pinned_post_test.dart index 4d1a4d9fd..ff49dad00 100644 --- a/test/widget_tests/widgets/pinned_post_test.dart +++ b/test/widget_tests/widgets/pinned_post_test.dart @@ -1,12 +1,12 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:talawa/locator.dart'; import 'package:talawa/models/post/post_model.dart'; import 'package:talawa/services/size_config.dart'; import 'package:talawa/views/after_auth_screens/feed/pinned_post_screen.dart'; import 'package:talawa/widgets/pinned_post.dart'; import '../../helpers/test_helpers.dart'; +import '../../helpers/test_locator.dart'; /// List of pinned posts. /// @@ -74,7 +74,7 @@ List get pinnedPosts { /// None void main() { TestWidgetsFlutterBinding.ensureInitialized(); - setupLocator(); + testSetupLocator(); locator().test(); setUp(() { registerServices(); @@ -88,7 +88,10 @@ void main() { (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); await widgetTester.pump(const Duration(seconds: 5)); @@ -99,7 +102,10 @@ void main() { (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); await widgetTester.pump(const Duration(seconds: 5)); @@ -109,7 +115,10 @@ void main() { testWidgets('Text widget displays the correct text', (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); await widgetTester.pump(const Duration(seconds: 5)); @@ -119,7 +128,10 @@ void main() { testWidgets('Tapping on a post triggers navigation', (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); await widgetTester.pump(const Duration(seconds: 5)); @@ -132,8 +144,8 @@ void main() { testWidgets('Container comes if list is empty', (widgetTester) async { await widgetTester.pumpWidget( - const MaterialApp( - home: PinnedPost(pinnedPost: []), + MaterialApp( + home: PinnedPost(pinnedPost: [], model: mainScreenViewModel), ), ); await widgetTester.pump(); @@ -143,7 +155,10 @@ void main() { (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); await widgetTester.pump(const Duration(seconds: 5)); @@ -160,7 +175,10 @@ void main() { (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); @@ -185,7 +203,10 @@ void main() { (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); await widgetTester.pump(const Duration(seconds: 5)); @@ -204,7 +225,10 @@ void main() { (widgetTester) async { await widgetTester.pumpWidget( MaterialApp( - home: PinnedPost(pinnedPost: pinnedPosts), + home: PinnedPost( + pinnedPost: pinnedPosts, + model: mainScreenViewModel, + ), ), ); await widgetTester.pump(const Duration(seconds: 5));