diff --git a/app/assets/icons/graduation-cap.svg b/app/assets/icons/graduation-cap.svg deleted file mode 100644 index a7dc456ab..000000000 --- a/app/assets/icons/graduation-cap.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/app/ios/Podfile.lock b/app/ios/Podfile.lock index fdbc037a0..d2259ba2b 100644 --- a/app/ios/Podfile.lock +++ b/app/ios/Podfile.lock @@ -684,7 +684,7 @@ SPEC CHECKSUMS: GTMSessionFetcher: 8000756fc1c19d2e5697b90311f7832d2e33f6cd image_picker_ios: b545a5f16c0fa88e3ecbbce3ed4de45567a8ec18 in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d - integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4 + integration_test: 13825b8a9334a850581300559b8839134b124670 leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28 libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d diff --git a/app/lib/dashboard/tips/dashboard_tip_system.dart b/app/lib/dashboard/tips/dashboard_tip_system.dart index 012426af4..7934119d8 100644 --- a/app/lib/dashboard/tips/dashboard_tip_system.dart +++ b/app/lib/dashboard/tips/dashboard_tip_system.dart @@ -10,7 +10,6 @@ import 'package:bloc_base/bloc_base.dart'; import 'package:rxdart/rxdart.dart'; import 'package:sharezone/dashboard/tips/cache/dashboard_tip_cache.dart'; import 'package:sharezone/dashboard/tips/models/rate_our_app_tip.dart'; -import 'package:sharezone/dashboard/tips/models/wrapped_tip.dart'; import 'package:sharezone/navigation/logic/navigation_bloc.dart'; import 'package:sharezone/settings/src/bloc/user_tips_bloc.dart'; @@ -37,16 +36,12 @@ class DashboardTipSystem extends BlocBase { UserTipsBloc userTipsBloc, ) { final rateOurAppTip = RateOurAppTip(cache); - final wrappedTip = - SharezoneWrappedTip(cache, userTipsBloc.streamAccountCreatedOn()); - final tips = [rateOurAppTip, wrappedTip]; + final tips = [rateOurAppTip]; return CombineLatestStream(tips.map((tip) => tip.shouldShown()).toList(), (streamValues) { final showRateOurAppCard = streamValues[0]; - final showWrappedTip = streamValues[1]; - if (showWrappedTip) return wrappedTip; if (showRateOurAppCard) return rateOurAppTip; return null; }); diff --git a/app/lib/dashboard/tips/models/wrapped_tip.dart b/app/lib/dashboard/tips/models/wrapped_tip.dart deleted file mode 100644 index bb61781fb..000000000 --- a/app/lib/dashboard/tips/models/wrapped_tip.dart +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2022 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:flutter/material.dart' hide Action; -import 'package:rxdart/rxdart.dart'; -import 'package:sharezone/dashboard/tips/cache/dashboard_tip_cache.dart'; -import 'package:sharezone/dashboard/tips/models/action.dart'; -import 'package:sharezone/dashboard/tips/models/dashboard_tip.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_page.dart'; - -class SharezoneWrappedTip implements DashboardTip { - static const _showedDashboardRatingCardKey = - "dashboard-showed-wrapped-23-24-tip"; - - final DashboardTipCache cache; - final Stream accountCreatedOn; - - SharezoneWrappedTip(this.cache, this.accountCreatedOn); - - @override - Action get action => Action( - title: "Ansehen", - onTap: (context) => - Navigator.pushNamed(context, SharezoneWrappedPage.tag)); - - @override - String get text => - "Das Schuljahr ist vorbei! Sieh dir dein Sharezone Wrapped 23/24 (dein Schuljahr in Zahlen) an 🎉"; - - @override - String get title => "Sharezone Wrapped 23/24"; - - @override - Stream shouldShown() { - return CombineLatestStream([ - cache.showedTip(_showedDashboardRatingCardKey), - accountCreatedOn, - ], (streamValues) { - final showedDashboardCounterCard = streamValues[0] as bool? ?? false; - final createdOn = streamValues[1] as DateTime?; - - // New user shouldn't see the Sharezone Wrapped tip because their Wrapped - // will be mostly empty. - final isOldUser = createdOn?.isBefore(DateTime(2024, 5, 1)) == true; - - return !showedDashboardCounterCard && isOldUser; - }); - } - - @override - void markAsShown() => cache.markTipAsShown(_showedDashboardRatingCardKey); -} diff --git a/app/lib/main/plugin_initializations.dart b/app/lib/main/plugin_initializations.dart index dc5cdc682..524b6b939 100644 --- a/app/lib/main/plugin_initializations.dart +++ b/app/lib/main/plugin_initializations.dart @@ -81,8 +81,7 @@ class PluginInitializations { 'firebase_messaging_vapid_key': 'BNT7Da6B6wi-mUBcGrt-9HxeIJZsPTsPpmR8cae_LhgJPcSFb5j0T8o-r-oFV1xAtXVXfRPIZlgUJR3tx8mLbbA', 'stripe_checkout_session_function_url': - 'https://europe-west1-sharezone-c2bd8.cloudfunctions.net/createStripeCheckoutSession', - 'show_sz_wrapped_23_24': true, + 'https://europe-west1-sharezone-c2bd8.cloudfunctions.net/createStripeCheckoutSession' }); try { diff --git a/app/lib/main/sharezone_app.dart b/app/lib/main/sharezone_app.dart index 5f80e19c3..e64a7e91f 100644 --- a/app/lib/main/sharezone_app.dart +++ b/app/lib/main/sharezone_app.dart @@ -55,7 +55,6 @@ import 'package:sharezone/settings/src/subpages/notification.dart'; import 'package:sharezone/settings/src/subpages/theme/theme_page.dart'; import 'package:sharezone/settings/src/subpages/timetable/timetable_settings_page.dart'; import 'package:sharezone/settings/src/subpages/web_app.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_page.dart'; import 'package:sharezone/sharezone_v2/sz_v2_announcement_dialog.dart'; import 'package:sharezone/support/support_page.dart'; import 'package:sharezone/timetable/timetable_add/timetable_add_page.dart'; @@ -205,8 +204,6 @@ class _SharezoneAppState extends State ICalLinksDialog.tag: (context) => const ICalLinksDialog(), CreateTermPage.tag: (context) => const CreateTermPage(), GradesDialog.tag: (context) => const GradesDialog(), - SharezoneWrappedPage.tag: (context) => - const SharezoneWrappedPage(), }, navigatorKey: navigationService.navigatorKey, ), diff --git a/app/lib/main/sharezone_bloc_providers.dart b/app/lib/main/sharezone_bloc_providers.dart index 48e58ccea..467a5f53a 100644 --- a/app/lib/main/sharezone_bloc_providers.dart +++ b/app/lib/main/sharezone_bloc_providers.dart @@ -33,7 +33,6 @@ import 'package:http/http.dart' as http; import 'package:key_value_store/in_memory_key_value_store.dart'; import 'package:provider/provider.dart'; import 'package:provider/single_child_widget.dart'; -import 'package:remote_configuration/remote_configuration.dart'; import 'package:sharezone/account/account_page_bloc_factory.dart'; import 'package:sharezone/account/change_data_bloc.dart'; import 'package:sharezone/account/type_of_user_bloc.dart'; @@ -116,8 +115,6 @@ import 'package:sharezone/sharezone_plus/page/sharezone_plus_page_controller.dar import 'package:sharezone/sharezone_plus/subscription_service/is_buying_enabled.dart'; import 'package:sharezone/sharezone_plus/subscription_service/revenue_cat_sharezone_plus_service.dart'; import 'package:sharezone/sharezone_plus/subscription_service/subscription_service.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_controller.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_repository.dart'; import 'package:sharezone/support/support_page_controller.dart'; import 'package:sharezone/timetable/src/bloc/timetable_bloc.dart'; import 'package:sharezone/timetable/src/models/lesson_length/lesson_length_cache.dart'; @@ -351,9 +348,6 @@ class _SharezoneBlocProvidersState extends State { create: (context) => api.user.authUserStream, initialData: null, ), - Provider( - create: (context) => widget.blocDependencies.remoteConfiguration, - ), ChangeNotifierProvider( create: (context) => SharezonePlusPageController( buyingFlagApi: BuyingEnabledApi(client: http.Client()), @@ -487,19 +481,7 @@ class _SharezoneBlocProvidersState extends State { courseMemberAccessor: FirestoreCourseMemberAccessor(api.references.firestore), ), - ), - Provider( - create: (context) => SharezoneWrappedController( - repository: SharezoneWrappedRepository( - firestore: firestore, - userId: api.userId, - connectionsGateway: api.connectionsGateway, - clock: clock, - ), - crashAnalytics: crashAnalytics, - analytics: analytics, - ), - ), + ) ]; mainBlocProviders = [ diff --git a/app/lib/settings/settings_page.dart b/app/lib/settings/settings_page.dart index 41ebaf819..aa6acb12c 100644 --- a/app/lib/settings/settings_page.dart +++ b/app/lib/settings/settings_page.dart @@ -10,8 +10,6 @@ import 'package:analytics/analytics.dart'; import 'package:bloc_provider/bloc_provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:provider/provider.dart'; -import 'package:remote_configuration/remote_configuration.dart'; import 'package:sharezone/legal/terms_of_service/terms_of_service_page.dart'; import 'package:sharezone/main/application_bloc.dart'; import 'package:sharezone/navigation/logic/navigation_bloc.dart'; @@ -21,13 +19,11 @@ import 'package:sharezone/settings/src/subpages/changelog_page.dart'; import 'package:sharezone/settings/src/subpages/notification.dart'; import 'package:sharezone/settings/src/subpages/about/about_page.dart'; import 'package:sharezone/settings/src/subpages/theme/theme_page.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_page.dart'; import 'package:sharezone/support/support_page.dart'; import 'package:sharezone/settings/src/subpages/timetable/timetable_settings_page.dart'; import 'package:sharezone/settings/src/subpages/web_app.dart'; import 'package:sharezone/legal/privacy_policy/privacy_policy_page.dart'; import 'package:platform_check/platform_check.dart'; -import 'package:sharezone/widgets/limited_chip.dart'; import 'package:sharezone_utils/launch_link.dart'; import 'package:sharezone_widgets/sharezone_widgets.dart'; @@ -149,38 +145,29 @@ class _LegalSection extends StatelessWidget { class _AppSettingsSection extends StatelessWidget { @override Widget build(BuildContext context) { - final remoteConfig = context.read(); - final showWrapped = remoteConfig.getBool('show_sz_wrapped_23_24'); - return _SettingsSection( + return const _SettingsSection( title: 'App-Einstellungen', children: [ - const _SettingsOption( + _SettingsOption( title: "Mein Konto", icon: Icon(Icons.account_circle), tag: MyProfilePage.tag, ), - const _SettingsOption( + _SettingsOption( title: "Benachrichtigungen", icon: Icon(Icons.notifications_active), tag: NotificationPage.tag, ), - const _SettingsOption( + _SettingsOption( title: "Erscheinungsbild", icon: Icon(Icons.color_lens), tag: ThemePage.tag, ), - const _SettingsOption( + _SettingsOption( title: "Stundenplan", icon: Icon(Icons.access_time), tag: TimetableSettingsPage.tag, - ), - if (showWrapped) - const _SettingsOption( - title: "Schuljahr 23/24 Sharezone Wrapped", - icon: Icon(Icons.fast_rewind), - tag: SharezoneWrappedPage.tag, - trailing: LimitedChip(), - ) + ) ], ); } @@ -262,13 +249,11 @@ class _SettingsOption extends StatelessWidget { this.icon, this.onTap, this.tag, - this.trailing, }); final String? title; final Widget? icon; final GestureTapCallback? onTap; - final Widget? trailing; final String? tag; @override @@ -277,7 +262,6 @@ class _SettingsOption extends StatelessWidget { title: Text(title!), leading: icon, onTap: onTap ?? () => Navigator.pushNamed(context, tag!), - trailing: trailing, ); } } diff --git a/app/lib/settings/src/bloc/user_tips_bloc.dart b/app/lib/settings/src/bloc/user_tips_bloc.dart index 02e553271..60a23df0d 100644 --- a/app/lib/settings/src/bloc/user_tips_bloc.dart +++ b/app/lib/settings/src/bloc/user_tips_bloc.dart @@ -19,10 +19,6 @@ class UserTipsBloc extends BlocBase { return _userGateway.userStream.map((user) => user?.userTipData); } - Stream streamAccountCreatedOn() { - return _userGateway.userStream.map((user) => user?.createdOn); - } - void enableUserTip(UserTipKey tipKey) { _updateUserTip(tipKey, true); } diff --git a/app/lib/sharezone_wrapped/sharezone_wrapped_controller.dart b/app/lib/sharezone_wrapped/sharezone_wrapped_controller.dart deleted file mode 100644 index 3d0f25739..000000000 --- a/app/lib/sharezone_wrapped/sharezone_wrapped_controller.dart +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:analytics/analytics.dart'; -import 'package:collection/collection.dart'; -import 'package:common_domain_models/common_domain_models.dart'; -import 'package:crash_analytics/crash_analytics.dart'; -import 'package:date/weektype.dart'; -import 'package:equatable/equatable.dart'; -import 'package:group_domain_models/group_domain_models.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_repository.dart'; -import 'package:sharezone/timetable/src/models/lesson.dart'; - -class SharezoneWrappedController { - final CrashAnalytics crashAnalytics; - final Analytics analytics; - final SharezoneWrappedRepository repository; - - const SharezoneWrappedController({ - required this.repository, - required this.crashAnalytics, - required this.analytics, - }); - - Future getValues() async { - try { - final courses = repository.getCourses(); - final courseIds = courses.map((course) => CourseId(course.id)).toList(); - - final ( - lessons, - totalAmountOfHomeworks, - totalAmountOfExams, - homeworkTopThreeCourses, - examTopThreeCourses, - ) = await ( - repository.getLessons(), - repository.getTotalAmountOfHomeworks(), - repository.getTotalAmountOfExams(), - _getHomeworkTopThreeCourses(courseIds), - _getExamTopThreeCourses(courseIds), - ).wait; - - final totalAmountOfLessonHours = _getTotalAmountOfLessonHours(lessons); - final lessonHoursTopThreeCourses = - _getLessonHoursTopThreeCourses(courseIds, lessons); - - _logGenerationAnalytics(); - - return SharezoneWrappedValues( - totalAmountOfLessonHours: totalAmountOfLessonHours, - amountOfLessonHoursTopThreeCourses: - lessonHoursTopThreeCourses.withCourseName(courses), - totalAmountOfHomeworks: totalAmountOfHomeworks ?? 0, - amountOfHomeworksTopThreeCourses: - homeworkTopThreeCourses.withCourseName(courses), - totalAmountOfExams: totalAmountOfExams ?? 0, - amountOfExamsTopThreeCourses: - examTopThreeCourses.withCourseName(courses), - ); - } catch (e, s) { - crashAnalytics.recordError( - 'Failed to get values for SharezoneWrapped: $e', s); - rethrow; - } - } - - void _logGenerationAnalytics() { - analytics.log(NamedAnalyticsEvent(name: 'sz_wrapped_generated')); - } - - /// Calculates the amount of lesson hours per course per school year. - /// - /// The amount of lesson hours is calculated by summing up the duration of all - /// lessons per course. - /// - /// We assume that a student has 40 school weeks per year. Source: - /// https://www.perplexity.ai/search/Wie-viele-Schulwochen-PKOcR28uRe2vga9SuurUcA#0 - List<(CourseId, int)> _getAmountOfLessonHoursPerCourse(List lessons) { - final lessonMinutesPerCourse = {}; - for (final lesson in lessons) { - final courseId = CourseId(lesson.groupID); - int lessonMinutes = lesson.endTime.differenceInMinutes(lesson.startTime); - - if (lesson.weektype != WeekType.always) { - // When the lesson is only every second week, we only count half of the - // lesson minutes. - // - // This calculation will break if support a,b,c or a,b,c,d week types. - lessonMinutes = lessonMinutes ~/ 2; - } - - lessonMinutesPerCourse[courseId] = - (lessonMinutesPerCourse[courseId] ?? 0) + lessonMinutes; - } - - return lessonMinutesPerCourse.entries - // Divide by 60 to get the amount of hours. - .map((entry) => (entry.key, ((entry.value / 60) * 40).toInt())) - .toList(); - } - - int _getTotalAmountOfLessonHours(List lessons) { - final perCourses = _getAmountOfLessonHoursPerCourse(lessons); - return perCourses.map((entry) => entry.$2).fold(0, (a, b) => a + b); - } - - List<(CourseId, int)> _getLessonHoursTopThreeCourses( - List courseIds, List lessons) { - final perCourses = _getAmountOfLessonHoursPerCourse(lessons); - final sorted = perCourses.toList()..sort((a, b) => b.$2.compareTo(a.$2)); - return sorted.take(3).toList(); - } - - Future> _getHomeworkTopThreeCourses( - List courseIds) async { - return _getTopThreeCourses( - courseIds, - (courseId) => repository.getAmountOfHomeworksFor(courseId: courseId), - ); - } - - // get top exam courses - Future> _getExamTopThreeCourses( - List courseIds) async { - return _getTopThreeCourses( - courseIds, - (courseId) => repository.getAmountOfExamsFor(courseId: courseId), - ); - } - - Future> _getTopThreeCourses( - List courseIds, - Future Function(CourseId) getAmount, - ) async { - final amounts = await Future.wait(courseIds.map((courseId) { - return getAmount(courseId); - })); - final amountsSorted = amounts - .asMap() - .entries - .map((entry) => MapEntry(courseIds[entry.key], entry.value)) - .toList(); - amountsSorted.sort((a, b) => (b.value ?? 0).compareTo(a.value ?? 0)); - final topThreeCourses = amountsSorted.take(3).toList(); - return topThreeCourses - .map((entry) => (entry.key, entry.value ?? 0)) - .toList(); - } -} - -extension on List<(CourseId, int)> { - List<(CourseId, CourseName, int)> withCourseName(List courses) { - return map((entry) { - final course = - courses.firstWhereOrNull((course) => course.id == entry.$1.value); - return (entry.$1, course?.name ?? '?', entry.$2); - }).toList(); - } -} - -class SharezoneWrappedValues extends Equatable { - final int totalAmountOfLessonHours; - final List<(CourseId, CourseName, int)> amountOfLessonHoursTopThreeCourses; - final int totalAmountOfHomeworks; - final List<(CourseId, CourseName, int)> amountOfHomeworksTopThreeCourses; - final int totalAmountOfExams; - final List<(CourseId, CourseName, int)> amountOfExamsTopThreeCourses; - - const SharezoneWrappedValues({ - required this.totalAmountOfLessonHours, - required this.amountOfLessonHoursTopThreeCourses, - required this.totalAmountOfHomeworks, - required this.amountOfHomeworksTopThreeCourses, - required this.totalAmountOfExams, - required this.amountOfExamsTopThreeCourses, - }); - - @override - List get props => [ - totalAmountOfLessonHours, - amountOfLessonHoursTopThreeCourses, - totalAmountOfHomeworks, - amountOfHomeworksTopThreeCourses, - totalAmountOfExams, - amountOfExamsTopThreeCourses, - ]; -} diff --git a/app/lib/sharezone_wrapped/sharezone_wrapped_image.dart b/app/lib/sharezone_wrapped/sharezone_wrapped_image.dart deleted file mode 100644 index 74d96fdea..000000000 --- a/app/lib/sharezone_wrapped/sharezone_wrapped_image.dart +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_view.dart'; -import 'package:sharezone_widgets/sharezone_widgets.dart'; - -class SharezoneWrappedImage extends StatelessWidget { - const SharezoneWrappedImage({ - super.key, - required this.view, - }); - - final SharezoneWrappedView view; - - @override - Widget build(BuildContext context) { - const width = 540.0; - const height = 960.0; - return SizedBox( - height: height, - width: width, - child: Material( - color: blueColor, - child: Padding( - padding: const EdgeInsets.all(12), - child: Center( - child: DefaultTextStyle.merge( - textAlign: TextAlign.center, - style: const TextStyle(height: 1.2), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const _Icon(), - const _MySchoolYearTitle(), - const _CreatedWithSharezoneText(), - const SizedBox(height: 32), - Container( - padding: const EdgeInsets.all(12), - width: width, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(20), - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AutoSizeText( - view.totalAmountOfLessonHours, - maxLines: 1, - style: const TextStyle( - fontSize: 120, - fontWeight: FontWeight.w500, - color: Colors.black, - ), - ), - const Text( - 'Stunden im Schulunterricht verbracht', - style: TextStyle( - fontSize: 32, - color: Colors.black, - ), - ), - const SizedBox(height: 8), - Text( - view.amountOfLessonHoursTopThreeCourses.join('\n'), - style: const TextStyle( - fontSize: 18, - color: Colors.grey, - ), - textAlign: TextAlign.center, - ), - ], - ), - ), - const SizedBox(height: 16), - Row( - children: [ - Container( - width: (width / 2) - 18, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - padding: const EdgeInsets.all(16), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AutoSizeText( - view.totalAmountOfHomeworks, - maxLines: 1, - style: const TextStyle( - fontSize: 80, - fontWeight: FontWeight.w500, - color: Colors.black, - ), - ), - const Text( - 'Hausaufgaben', - style: TextStyle( - color: Colors.black, - fontSize: 20, - ), - ), - const SizedBox(height: 8), - Text( - view.amountOfHomeworksTopThreeCourses.join('\n'), - textAlign: TextAlign.center, - style: const TextStyle( - color: Colors.grey, - fontSize: 16, - ), - ), - ], - ), - ), - const SizedBox(width: 12), - Container( - width: (width / 2) - 18, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - padding: const EdgeInsets.all(16), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AutoSizeText( - view.totalAmountOfExams, - maxLines: 1, - style: const TextStyle( - fontSize: 80, - fontWeight: FontWeight.w500, - color: Colors.black, - ), - ), - const Text( - 'Prüfungen', - style: TextStyle( - color: Colors.black, - fontSize: 20, - ), - ), - const SizedBox(height: 8), - Text( - view.amountOfExamsTopThreeCourses.join('\n'), - textAlign: TextAlign.center, - style: const TextStyle( - color: Colors.grey, - fontSize: 16, - ), - ), - ], - ), - ), - ], - ), - const SizedBox(height: 32), - const SharezoneLogo( - logoColor: LogoColor.white, - height: 45, - width: 100, - ) - ], - ), - ), - ), - ), - ), - ); - } -} - -class _CreatedWithSharezoneText extends StatelessWidget { - const _CreatedWithSharezoneText(); - - @override - Widget build(BuildContext context) { - return const Text( - 'Erstellt mit der App "Sharezone"', - style: TextStyle( - fontSize: 16, - color: Colors.white70, - ), - textAlign: TextAlign.center, - ); - } -} - -class _MySchoolYearTitle extends StatelessWidget { - const _MySchoolYearTitle(); - - @override - Widget build(BuildContext context) { - return const Text( - 'Mein Schuljahr 23/24', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.w500, - color: Colors.white, - ), - textAlign: TextAlign.center, - ); - } -} - -class _Icon extends StatelessWidget { - const _Icon(); - - @override - Widget build(BuildContext context) { - return SvgPicture.asset( - 'assets/icons/graduation-cap.svg', - width: 140, - height: 140, - ); - } -} diff --git a/app/lib/sharezone_wrapped/sharezone_wrapped_page.dart b/app/lib/sharezone_wrapped/sharezone_wrapped_page.dart deleted file mode 100644 index 6e9d8f8af..000000000 --- a/app/lib/sharezone_wrapped/sharezone_wrapped_page.dart +++ /dev/null @@ -1,375 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'dart:typed_data'; - -import 'package:analytics/analytics.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:platform_check/platform_check.dart'; -import 'package:provider/provider.dart'; -import 'package:screenshot/screenshot.dart'; -import 'package:share_plus/share_plus.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_controller.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_image.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_view.dart'; -import 'package:sharezone/support/support_page.dart'; -import 'package:sharezone_widgets/sharezone_widgets.dart'; - -class SharezoneWrappedPage extends StatefulWidget { - const SharezoneWrappedPage({super.key}); - - static const tag = "sharezone-wrapped-page"; - - @override - State createState() => _SharezoneWrappedPageState(); -} - -class _SharezoneWrappedPageState extends State { - Uint8List? _imageData; - bool get hasLoaded => _imageData != null; - String? error; - - SharezoneWrappedValues? values; - late ScreenshotController _screenshotController; - - @override - void initState() { - super.initState(); - _screenshotController = ScreenshotController(); - - WidgetsBinding.instance.addPostFrameCallback((_) async { - generateWrapped(); - }); - } - - Future fetchValues() async { - try { - final controller = context.read(); - values = await controller.getValues(); - - setState(() { - error = null; - }); - } catch (e) { - setState(() { - error = '$e'; - }); - } - } - - Future generateWrapped() async { - await fetchValues(); - - final hasNotFailedToFetchValues = values != null; - if (hasNotFailedToFetchValues) { - final capture = await _screenshotController.captureFromLongWidget( - SharezoneWrappedImage( - view: SharezoneWrappedView.fromValues( - totalAmountOfLessonHours: values?.totalAmountOfLessonHours ?? 0, - amountOfLessonHoursTopThreeCourses: - values?.amountOfLessonHoursTopThreeCourses ?? [], - totalAmountOfHomeworks: values?.totalAmountOfHomeworks ?? 0, - amountOfHomeworksTopThreeCourses: - values?.amountOfHomeworksTopThreeCourses ?? [], - totalAmountOfExams: values?.totalAmountOfExams ?? 0, - amountOfExamsTopThreeCourses: - values?.amountOfExamsTopThreeCourses ?? [], - ), - ), - ); - setState(() { - _imageData = capture; - }); - } - } - - Future share(BuildContext context) async { - if (PlatformCheck.isWeb) { - showDialog( - context: context, - builder: (_) => const _OnlyAvailableOnMobileDialog(), - ); - return; - } - - showSnackSec( - context: context, - text: 'Teilen wird vorbereitet...', - ); - - try { - final image = XFile.fromData( - _imageData!, - mimeType: 'image/png', - ); - - final box = context.findRenderObject() as RenderBox; - final result = await Share.shareXFiles( - [image], - sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size, - ); - - if (mounted) { - // ignore: use_build_context_synchronously - final analytics = context.read(); - analytics.log( - NamedAnalyticsEvent(name: 'sz_wrapped_shared_${result.status.name}'), - ); - // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - } - } on Exception catch (e) { - showSnack( - // ignore: use_build_context_synchronously - context: context, - text: 'Share failed: $e', - ); - } - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(), - body: Center( - child: Stack( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(12), - child: SafeArea( - child: MaxWidthConstraintBox( - maxWidth: 550, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // Idea: when opening the page: creating an actual image and - // displaying it. - Container( - // add border - decoration: BoxDecoration( - border: Border.all( - color: darkBlueColor, - width: 4, - ), - ), - child: InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => Theme( - data: getDarkTheme(), - child: Scaffold( - appBar: AppBar( - leading: const CloseButton(), - ), - body: Center( - child: Hero( - tag: 'sharezone-wrapped-image', - child: Image.memory( - _imageData!, - fit: BoxFit.contain, - semanticLabel: 'Sharezone Wrapped', - ), - ), - ), - ), - ), - ), - ); - }, - child: _imageData == null - ? Container() - : Hero( - tag: 'sharezone-wrapped-image', - child: Image.memory( - _imageData!, - semanticLabel: 'Sharezone Wrapped', - height: MediaQuery.of(context).size.height * - 0.55, - ), - ), - ), - ), - const SizedBox(height: 8), - const Text( - 'Wrapped', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.w500, - ), - ), - const Text( - 'Schuljahr 23/24', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w500, - ), - ), - const SizedBox(height: 4), - Text( - 'Hier ist dein Schuljahr in Zahlen. Teile es mit deinen Freunden auf Instagram, TikTok und Co.', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - color: Theme.of(context) - .colorScheme - .onSurface - .withOpacity(0.6), - fontWeight: FontWeight.w400, - ), - ), - const SizedBox(height: 12), - Builder( - // Builder is required to set sharePositionOrigin - // correctly in the share parameters. - builder: (context) { - return ElevatedButton.icon( - icon: Icon( - themeIconData(Icons.share, - cupertinoIcon: CupertinoIcons.share), - ), - onPressed: () => share(context), - label: const Text("Teilen"), - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - ), - ); - }, - ), - const SizedBox(height: 12), - const _FAQ(), - ], - ), - ), - ), - ), - if (!hasLoaded) const _LoadingScreen(), - if (error != null) - _ErrorScreen( - error: error!, - onRetryPressed: () => generateWrapped(), - ) - ], - ), - ), - ); - } -} - -class _LoadingScreen extends StatelessWidget { - const _LoadingScreen(); - - @override - Widget build(BuildContext context) { - return Container( - height: MediaQuery.of(context).size.height, - width: MediaQuery.of(context).size.width, - color: Theme.of(context).scaffoldBackgroundColor, - child: const Center( - child: SingleChildScrollView( - child: MaxWidthConstraintBox( - maxWidth: 300, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - SizedBox(height: 16), - Text( - "Dein Sharezone Wrapped wird erstellt 👩‍🍳 Das kann ein paar Sekunden dauern...", - textAlign: TextAlign.center, - ), - ], - ), - ), - ), - ), - ); - } -} - -class _OnlyAvailableOnMobileDialog extends StatelessWidget { - const _OnlyAvailableOnMobileDialog(); - - @override - Widget build(BuildContext context) { - return AlertDialog( - title: const Text('Nur auf iOS & Android verfügbar'), - content: const Text( - 'Du kannst dein Sharezone Wrapped nur mit der Sharezone iOS- und Android-App teilen. Lade dir dafür die Sharezone-App aus dem App Store / Play Store herunter.', - ), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: const Text('Alles klar'), - ), - ], - ); - } -} - -class _ErrorScreen extends StatelessWidget { - const _ErrorScreen({ - required this.error, - required this.onRetryPressed, - }); - - final String error; - final VoidCallback onRetryPressed; - - @override - Widget build(BuildContext context) { - return Container( - height: MediaQuery.of(context).size.height, - width: MediaQuery.of(context).size.width, - color: Theme.of(context).scaffoldBackgroundColor, - child: Center( - child: MaxWidthConstraintBox( - // The column is a workaround to avoid that the error card takes the - // full width of the screen. - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ErrorCard( - message: Text(error), - onRetryPressed: onRetryPressed, - onContactSupportPressed: () => - Navigator.pushNamed(context, SupportPage.tag), - ), - ], - ), - ), - ), - ); - } -} - -class _FAQ extends StatelessWidget { - const _FAQ(); - - @override - Widget build(BuildContext context) { - return const Column( - children: [ - ExpansionCard( - header: Text('Wie wurden die Schulstunden berechnet?'), - body: Text( - 'Die Angabe der Schulstunden aus deinem Schuljahr sind eine Hochrechnung auf Basis von deinem aktuellen Stundenplan. Es wurde angenommen, dass es 40 Schulwochen gibt. Feiertage wurden nicht berücksichtigt.'), - ), - SizedBox(height: 12), - ExpansionCard( - header: Text('Ich habe nicht alle Prüfungen eingetragen. Was nun?'), - body: Text( - 'Wenn du nicht alle Prüfungen eingetragen hast, kannst du diese nachtragen. Wenn du erneut auf diese Seite öffnest (über die Einstellungen), wird dein Sharezone Wrapped aktualisiert.'), - ), - ], - ); - } -} diff --git a/app/lib/sharezone_wrapped/sharezone_wrapped_repository.dart b/app/lib/sharezone_wrapped/sharezone_wrapped_repository.dart deleted file mode 100644 index 5b655f010..000000000 --- a/app/lib/sharezone_wrapped/sharezone_wrapped_repository.dart +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:clock/clock.dart'; -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:common_domain_models/common_domain_models.dart'; -import 'package:date/date.dart'; -import 'package:group_domain_models/group_domain_models.dart'; -import 'package:retry/retry.dart'; -import 'package:sharezone/timetable/src/models/lesson.dart'; -import 'package:sharezone/util/api/connections_gateway.dart'; - -class SharezoneWrappedRepository { - final FirebaseFirestore firestore; - final ConnectionsGateway connectionsGateway; - final UserId userId; - final Clock clock; - - const SharezoneWrappedRepository({ - required this.firestore, - required this.userId, - required this.connectionsGateway, - required this.clock, - }); - - /// Returns the minimum date for createdOn to be used in queries because we - /// only want to consider data from the current school year. - /// - /// Using a fixed date for now, because we don't have a school year concept - /// yet. - DateTime _minimumCreatedAt() { - return clock.now().subtract(const Duration(days: 365)); - } - - Future getTotalAmountOfHomeworks() async { - return _retry(() async { - final res = await firestore - .collection('Homework') - .where('assignedUserArrays.allAssignedUids', arrayContains: '$userId') - .where('createdOn', isGreaterThan: _minimumCreatedAt()) - .count() - .get(); - return res.count; - }); - } - - Future getAmountOfHomeworksFor({required CourseId courseId}) async { - return _retry(() async { - final res = await firestore - .collection('Homework') - .where('courseID', isEqualTo: '$courseId') - .where('assignedUserArrays.allAssignedUids', arrayContains: '$userId') - .where('createdOn', isGreaterThan: _minimumCreatedAt()) - .count() - .get(); - return res.count; - }); - } - - Future getTotalAmountOfExams() async { - return _retry(() async { - final res = await firestore - .collection('Events') - .where('users', arrayContains: '$userId') - .where('eventType', isEqualTo: 'exam') - // createdOn was added Feb 2024, we can't use it for this year. - .where('date', - isGreaterThan: _minimumCreatedAt().toDate().toDateString) - .count() - .get(); - return res.count; - }); - } - - Future getAmountOfExamsFor({required CourseId courseId}) async { - return _retry(() async { - final res = await firestore - .collection('Events') - .where('users', arrayContains: '$userId') - .where('groupID', isEqualTo: '$courseId') - // createdOn was added Feb 2024, we can't use it for this year. - .where('date', - isGreaterThan: _minimumCreatedAt().toDate().toDateString) - .where('eventType', isEqualTo: 'exam') - .count() - .get(); - return res.count; - }); - } - - Future> getLessons() async { - return _retry(() async { - // Technical debt: We already load all lessons for the timetable. We could - // reuse this data here to avoid unnecessary Firestore reads. Haven't done - // this yet, to move faster. - final res = await firestore - .collection('Lessons') - .where('users', arrayContains: '$userId') - .get(); - return res.docs.map((e) => Lesson.fromData(e.data(), id: e.id)).toList(); - }); - } - - List getCourses() { - return connectionsGateway - .current() - ?.courses - .entries - .map((e) => e.value.copyWith(id: e.key)) - .toList() ?? - []; - } - - Future _retry(Future Function() fn) { - return retry( - () => fn(), - maxAttempts: 3, - ); - } -} diff --git a/app/lib/sharezone_wrapped/sharezone_wrapped_view.dart b/app/lib/sharezone_wrapped/sharezone_wrapped_view.dart deleted file mode 100644 index 8774b3feb..000000000 --- a/app/lib/sharezone_wrapped/sharezone_wrapped_view.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:collection/collection.dart'; -import 'package:common_domain_models/common_domain_models.dart'; -import 'package:flutter/material.dart'; -import 'package:group_domain_models/group_domain_models.dart'; -import 'package:intl/intl.dart'; - -class SharezoneWrappedView { - /// The total amount of lesson hours formatted as [String]. - /// - /// Example: `91.234` - final String totalAmountOfLessonHours; - - /// The amount of lesson hours for the top three courses formatted as - /// [List]. - /// - /// Example: - /// ``` - /// [ - /// '1. Deutsch: 12.345 Std.', - /// '2. Mathematik: 9.876 Std.', - /// '3. Englisch: 8.765 Std.', - /// ] - /// ``` - final List amountOfLessonHoursTopThreeCourses; - - /// The total amount of homeworks formatted as [String]. - /// - /// Example: `1.002` - final String totalAmountOfHomeworks; - - /// The amount of homeworks for the top three courses formatted as - /// [List]. - /// - /// Example: - /// ``` - /// [ - /// '1. Deutsch: 123', - /// '2. Mathematik: 98', - /// '3. Englisch: 87', - /// ] - /// ``` - final List amountOfHomeworksTopThreeCourses; - - /// The total amount of exams formatted as [String]. - /// - /// Example: `1,001` - final String totalAmountOfExams; - - /// The amount of exams for the top three courses formatted as - /// [List]. - /// - /// Example: - /// ``` - /// [ - /// '1. Deutsch: 123', - /// '2. Mathematik: 98', - /// '3. Englisch: 87', - /// ] - /// ``` - final List amountOfExamsTopThreeCourses; - - SharezoneWrappedView({ - required this.totalAmountOfLessonHours, - required this.amountOfLessonHoursTopThreeCourses, - required this.totalAmountOfHomeworks, - required this.amountOfHomeworksTopThreeCourses, - required this.amountOfExamsTopThreeCourses, - required this.totalAmountOfExams, - }); - - static String getShortenedCourseName(String courseName) { - final characters = courseName.characters; - const maxLength = 19; - if (characters.length <= maxLength) return courseName; - return '${courseName.characters.take(maxLength)}...'; - } - - factory SharezoneWrappedView.fromValues({ - required int totalAmountOfLessonHours, - required List<(CourseId, CourseName, int)> - amountOfLessonHoursTopThreeCourses, - required int totalAmountOfHomeworks, - required List<(CourseId, CourseName, int)> amountOfHomeworksTopThreeCourses, - required int totalAmountOfExams, - required List<(CourseId, CourseName, int)> amountOfExamsTopThreeCourses, - }) { - final formatter = NumberFormat.decimalPattern('de_DE'); - return SharezoneWrappedView( - totalAmountOfLessonHours: formatter.format(totalAmountOfLessonHours), - amountOfLessonHoursTopThreeCourses: - amountOfLessonHoursTopThreeCourses.mapIndexed((index, value) { - return '${index + 1}. ${getShortenedCourseName(value.$2)}: ${formatter.format(value.$3)} Std.'; - }).toList(), - totalAmountOfHomeworks: formatter.format(totalAmountOfHomeworks), - amountOfHomeworksTopThreeCourses: amountOfHomeworksTopThreeCourses - .mapIndexed((index, value) => - '${index + 1}. ${getShortenedCourseName(value.$2)}: ${formatter.format(value.$3)}') - .toList(), - totalAmountOfExams: formatter.format(totalAmountOfExams), - amountOfExamsTopThreeCourses: amountOfExamsTopThreeCourses - .mapIndexed((index, value) => - '${index + 1}. ${getShortenedCourseName(value.$2)}: ${formatter.format(value.$3)}') - .toList(), - ); - } -} diff --git a/app/lib/widgets/limited_chip.dart b/app/lib/widgets/limited_chip.dart deleted file mode 100644 index e1ae513d1..000000000 --- a/app/lib/widgets/limited_chip.dart +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:flutter/material.dart'; - -class LimitedChip extends StatelessWidget { - const LimitedChip({ - super.key, - this.backgroundColor, - this.foregroundColor, - }); - - final Color? backgroundColor; - final Color? foregroundColor; - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - color: - backgroundColor ?? Theme.of(context).primaryColor.withOpacity(0.2), - borderRadius: BorderRadius.circular(7.5), - ), - child: const Padding( - padding: EdgeInsets.fromLTRB(8, 4, 10, 4), - child: Text('LIMITED'), - ), - ); - } -} diff --git a/app/pubspec.lock b/app/pubspec.lock index 88f2b3819..174a0e63e 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -1865,14 +1865,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.27.7" - screenshot: - dependency: "direct main" - description: - name: screenshot - sha256: "63817697a7835e6ce82add4228e15d233b74d42975c143ad8cfe07009fab866b" - url: "https://pub.dev" - source: hosted - version: "3.0.0" scrollable_positioned_list: dependency: "direct main" description: @@ -2574,4 +2566,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=3.22.0" + flutter: ">=3.19.0" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index bdd4ba4dd..d7a47c54f 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -154,7 +154,6 @@ dependencies: path: ../lib/remote_configuration retry: ^3.1.2 rxdart: ^0.27.1 - screenshot: ^3.0.0 scrollable_positioned_list: ^0.3.8 share_plus: ^9.0.0 shared_preferences: ^2.2.3 diff --git a/app/test/homework/homework_dialog_test.mocks.dart b/app/test/homework/homework_dialog_test.mocks.dart index 78e6fb034..57118d0ec 100644 --- a/app/test/homework/homework_dialog_test.mocks.dart +++ b/app/test/homework/homework_dialog_test.mocks.dart @@ -1032,16 +1032,6 @@ class MockUserGateway extends _i1.Mock implements _i12.UserGateway { returnValueForMissingStub: _i24.Future.value(), ) as _i24.Future); - @override - _i24.Future sendVerificationEmail() => (super.noSuchMethod( - Invocation.method( - #sendVerificationEmail, - [], - ), - returnValue: _i24.Future.value(), - returnValueForMissingStub: _i24.Future.value(), - ) as _i24.Future); - @override _i24.Future deleteUser(_i3.SharezoneGateway? gateway) => (super.noSuchMethod( diff --git a/app/test/settings/notifications/notification_test.mocks.dart b/app/test/settings/notifications/notification_test.mocks.dart index 4e1c0ae85..08d3836ed 100644 --- a/app/test/settings/notifications/notification_test.mocks.dart +++ b/app/test/settings/notifications/notification_test.mocks.dart @@ -342,16 +342,6 @@ class MockUserGateway extends _i1.Mock implements _i5.UserGateway { returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); - @override - _i7.Future sendVerificationEmail() => (super.noSuchMethod( - Invocation.method( - #sendVerificationEmail, - [], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - @override _i7.Future deleteUser(_i12.SharezoneGateway? gateway) => (super.noSuchMethod( diff --git a/app/test/sharezone_wrapped/sharezone_wrapped_controller_test.dart b/app/test/sharezone_wrapped/sharezone_wrapped_controller_test.dart deleted file mode 100644 index ca0ecf62b..000000000 --- a/app/test/sharezone_wrapped/sharezone_wrapped_controller_test.dart +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'dart:math'; - -import 'package:analytics/analytics.dart'; -import 'package:common_domain_models/common_domain_models.dart'; -import 'package:crash_analytics/crash_analytics.dart'; -import 'package:date/date.dart'; -import 'package:date/weekday.dart'; -import 'package:date/weektype.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:group_domain_models/group_domain_models.dart'; -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_controller.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_repository.dart'; -import 'package:sharezone/timetable/src/models/lesson.dart'; -import 'package:time/time.dart'; - -import 'sharezone_wrapped_controller_test.mocks.dart'; - -@GenerateNiceMocks([ - MockSpec(), - MockSpec(), - MockSpec(), -]) -void main() { - late MockSharezoneWrappedRepository repository; - late MockCrashAnalytics crashAnalytics; - late MockAnalytics analytics; - late SharezoneWrappedController controller; - - late Course math; - late Course english; - late Course history; - late Course biology; - late Course physics; - - late List courses; - - late Random random; - - Course generateCourse({GroupId? groupId, String? name}) { - return Course.create().copyWith( - id: '$groupId', - name: name, - ); - } - - Lesson generateLesson({ - required GroupId groupId, - required Time startTime, - required Time endTime, - required Date date, - required WeekDay weekday, - required WeekType weekType, - }) { - return Lesson( - createdOn: DateTime(2024, 1, 1), - startTime: startTime, - endTime: endTime, - startDate: date, - endDate: date, - groupID: groupId.value, - groupType: GroupType.course, - lessonID: Id.generate(random: random).value, - weekday: weekday, - place: null, - teacher: null, - weektype: weekType, - periodNumber: null, - substitutions: {}, - ); - } - - setUp(() { - repository = MockSharezoneWrappedRepository(); - crashAnalytics = MockCrashAnalytics(); - analytics = MockAnalytics(); - controller = SharezoneWrappedController( - repository: repository, - crashAnalytics: crashAnalytics, - analytics: analytics, - ); - - random = Random(42); - - math = generateCourse(groupId: const GroupId('1'), name: 'Math'); - english = generateCourse(groupId: const GroupId('2'), name: 'English'); - history = generateCourse(groupId: const GroupId('3'), name: 'History'); - biology = generateCourse(groupId: const GroupId('4'), name: 'Biology'); - physics = generateCourse(groupId: const GroupId('5'), name: 'Physics'); - - courses = [math, english, history, biology, physics]; - }); - - group(SharezoneWrappedController, () { - test('calculates the top three lesson courses', () async { - when(repository.getCourses()).thenAnswer((_) => courses); - when(repository.getLessons()).thenAnswer( - (_) async => [ - for (var i = 0; i < 5; i++) - generateLesson( - groupId: CourseId(math.id), - startTime: Time(hour: 8 + i, minute: 0), - endTime: Time(hour: 9 + i, minute: 0), - date: Date('2024-01-01'), - weekday: WeekDay.monday, - weekType: WeekType.always, - ), - for (var i = 0; i < 3; i++) - generateLesson( - groupId: CourseId(biology.id), - startTime: Time(hour: 8 + i, minute: 0), - endTime: Time(hour: 9 + i, minute: 0), - date: Date('2024-01-01'), - weekday: WeekDay.monday, - weekType: WeekType.always, - ), - for (var i = 0; i < 6; i++) - generateLesson( - groupId: CourseId(physics.id), - startTime: Time(hour: 8 + i, minute: 0), - endTime: Time(hour: 9 + i, minute: 0), - date: Date('2024-01-01'), - weekday: WeekDay.monday, - weekType: WeekType.always, - ), - for (var i = 0; i < 2; i++) - generateLesson( - groupId: CourseId(history.id), - startTime: Time(hour: 8 + i, minute: 0), - endTime: Time(hour: 9 + i, minute: 0), - date: Date('2024-01-01'), - weekday: WeekDay.monday, - weekType: WeekType.always, - ), - ], - ); - - final values = await controller.getValues(); - - // See comment in implementation for explanation - const schoolWeeksPerYear = 40; - - const mathHours = 5 * schoolWeeksPerYear; - const biologyHours = 3 * schoolWeeksPerYear; - const physicsHours = 6 * schoolWeeksPerYear; - - expect(values.amountOfLessonHoursTopThreeCourses, [ - (CourseId(physics.id), physics.name, physicsHours), - (CourseId(math.id), math.name, mathHours), - (CourseId(biology.id), biology.name, biologyHours), - ]); - }); - - test('calculates total amount of lessons', () async { - when(repository.getCourses()).thenAnswer((_) => courses); - when(repository.getLessons()).thenAnswer( - (_) async => [ - for (final course in courses) - for (var i = 0; i < 5; i++) - generateLesson( - groupId: CourseId(course.id), - startTime: Time(hour: 8 + i, minute: 0), - endTime: Time(hour: 9 + i, minute: 0), - date: Date('2024-01-01'), - weekday: WeekDay.monday, - weekType: WeekType.always, - ), - generateLesson( - groupId: CourseId(math.id), - startTime: Time(hour: 7, minute: 0), - endTime: Time(hour: 8, minute: 0), - date: Date('2024-01-01'), - weekday: WeekDay.monday, - weekType: WeekType.a, - ), - ], - ); - - final values = await controller.getValues(); - - // See comment in implementation for explanation - const schoolWeeksPerYear = 40; - - // Every course has 5 lessons per week - const hoursPerCourse = 5 * schoolWeeksPerYear; - - // We have one course that only has lessons every second week - const abWeekHours = 1 * (schoolWeeksPerYear / 2); - - const totalHours = (hoursPerCourse * 5) + abWeekHours; - - expect(values.totalAmountOfLessonHours, totalHours.toInt()); - }); - - test('calculates the top three homework courses', () async { - when(repository.getCourses()).thenAnswer((_) => courses); - when(repository.getAmountOfHomeworksFor(courseId: CourseId(english.id))) - .thenAnswer((_) async => 20); - when(repository.getAmountOfHomeworksFor(courseId: CourseId(math.id))) - .thenAnswer((_) async => 10); - when(repository.getAmountOfHomeworksFor(courseId: CourseId(history.id))) - .thenAnswer((_) async => 30); - when(repository.getAmountOfHomeworksFor(courseId: CourseId(physics.id))) - .thenAnswer((_) async => 50); - when(repository.getAmountOfHomeworksFor(courseId: CourseId(biology.id))) - .thenAnswer((_) async => 40); - - final values = await controller.getValues(); - expect(values.amountOfHomeworksTopThreeCourses, [ - (CourseId(physics.id), physics.name, 50), - (CourseId(biology.id), biology.name, 40), - (CourseId(history.id), history.name, 30), - ]); - }); - - test('calculates the top three exam courses', () async { - when(repository.getCourses()).thenAnswer((_) => courses); - when(repository.getAmountOfExamsFor(courseId: CourseId(english.id))) - .thenAnswer((_) async => 20); - when(repository.getAmountOfExamsFor(courseId: CourseId(math.id))) - .thenAnswer((_) async => 10); - when(repository.getAmountOfExamsFor(courseId: CourseId(history.id))) - .thenAnswer((_) async => 30); - when(repository.getAmountOfExamsFor(courseId: CourseId(physics.id))) - .thenAnswer((_) async => 50); - when(repository.getAmountOfExamsFor(courseId: CourseId(biology.id))) - .thenAnswer((_) async => 40); - - final values = await controller.getValues(); - expect(values.amountOfExamsTopThreeCourses, [ - (CourseId(physics.id), physics.name, 50), - (CourseId(biology.id), biology.name, 40), - (CourseId(history.id), history.name, 30), - ]); - }); - - test('fetches total amount of exams', () async { - when(repository.getTotalAmountOfExams()).thenAnswer((_) async => 42); - - final values = await controller.getValues(); - expect(values.totalAmountOfExams, 42); - }); - - test('fetches total amount of homeworks correct', () async { - when(repository.getTotalAmountOfHomeworks()).thenAnswer((_) async => 42); - - final values = await controller.getValues(); - expect(values.totalAmountOfHomeworks, 42); - }); - - test('log analytics when wrapped generated', () async { - await controller.getValues(); - - verify(analytics.log(NamedAnalyticsEvent(name: 'sz_wrapped_generated'))); - }); - }); -} diff --git a/app/test/sharezone_wrapped/sharezone_wrapped_controller_test.mocks.dart b/app/test/sharezone_wrapped/sharezone_wrapped_controller_test.mocks.dart deleted file mode 100644 index ad91bfe7b..000000000 --- a/app/test/sharezone_wrapped/sharezone_wrapped_controller_test.mocks.dart +++ /dev/null @@ -1,362 +0,0 @@ -// Mocks generated by Mockito 5.4.4 from annotations -// in sharezone/test/sharezone_wrapped/sharezone_wrapped_controller_test.dart. -// Do not manually edit this file. - -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i7; - -import 'package:analytics/src/analytics/analytics.dart' as _i12; -import 'package:clock/clock.dart' as _i5; -import 'package:cloud_firestore/cloud_firestore.dart' as _i2; -import 'package:common_domain_models/common_domain_models.dart' as _i4; -import 'package:crash_analytics/src/crash_analytics.dart' as _i10; -import 'package:flutter/foundation.dart' as _i11; -import 'package:group_domain_models/group_domain_models.dart' as _i9; -import 'package:mockito/mockito.dart' as _i1; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_repository.dart' - as _i6; -import 'package:sharezone/timetable/src/models/lesson.dart' as _i8; -import 'package:sharezone/util/api/connections_gateway.dart' as _i3; - -// 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 -// ignore_for_file: unnecessary_parenthesis -// ignore_for_file: camel_case_types -// ignore_for_file: subtype_of_sealed_class - -class _FakeFirebaseFirestore_0 extends _i1.SmartFake - implements _i2.FirebaseFirestore { - _FakeFirebaseFirestore_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeConnectionsGateway_1 extends _i1.SmartFake - implements _i3.ConnectionsGateway { - _FakeConnectionsGateway_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeUserId_2 extends _i1.SmartFake implements _i4.UserId { - _FakeUserId_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeClock_3 extends _i1.SmartFake implements _i5.Clock { - _FakeClock_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -/// A class which mocks [SharezoneWrappedRepository]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockSharezoneWrappedRepository extends _i1.Mock - implements _i6.SharezoneWrappedRepository { - @override - _i2.FirebaseFirestore get firestore => (super.noSuchMethod( - Invocation.getter(#firestore), - returnValue: _FakeFirebaseFirestore_0( - this, - Invocation.getter(#firestore), - ), - returnValueForMissingStub: _FakeFirebaseFirestore_0( - this, - Invocation.getter(#firestore), - ), - ) as _i2.FirebaseFirestore); - - @override - _i3.ConnectionsGateway get connectionsGateway => (super.noSuchMethod( - Invocation.getter(#connectionsGateway), - returnValue: _FakeConnectionsGateway_1( - this, - Invocation.getter(#connectionsGateway), - ), - returnValueForMissingStub: _FakeConnectionsGateway_1( - this, - Invocation.getter(#connectionsGateway), - ), - ) as _i3.ConnectionsGateway); - - @override - _i4.UserId get userId => (super.noSuchMethod( - Invocation.getter(#userId), - returnValue: _FakeUserId_2( - this, - Invocation.getter(#userId), - ), - returnValueForMissingStub: _FakeUserId_2( - this, - Invocation.getter(#userId), - ), - ) as _i4.UserId); - - @override - _i5.Clock get clock => (super.noSuchMethod( - Invocation.getter(#clock), - returnValue: _FakeClock_3( - this, - Invocation.getter(#clock), - ), - returnValueForMissingStub: _FakeClock_3( - this, - Invocation.getter(#clock), - ), - ) as _i5.Clock); - - @override - _i7.Future getTotalAmountOfHomeworks() => (super.noSuchMethod( - Invocation.method( - #getTotalAmountOfHomeworks, - [], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future getAmountOfHomeworksFor({required _i4.CourseId? courseId}) => - (super.noSuchMethod( - Invocation.method( - #getAmountOfHomeworksFor, - [], - {#courseId: courseId}, - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future getTotalAmountOfExams() => (super.noSuchMethod( - Invocation.method( - #getTotalAmountOfExams, - [], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future getAmountOfExamsFor({required _i4.CourseId? courseId}) => - (super.noSuchMethod( - Invocation.method( - #getAmountOfExamsFor, - [], - {#courseId: courseId}, - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future> getLessons() => (super.noSuchMethod( - Invocation.method( - #getLessons, - [], - ), - returnValue: _i7.Future>.value(<_i8.Lesson>[]), - returnValueForMissingStub: - _i7.Future>.value(<_i8.Lesson>[]), - ) as _i7.Future>); - - @override - List<_i9.Course> getCourses() => (super.noSuchMethod( - Invocation.method( - #getCourses, - [], - ), - returnValue: <_i9.Course>[], - returnValueForMissingStub: <_i9.Course>[], - ) as List<_i9.Course>); -} - -/// A class which mocks [CrashAnalytics]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockCrashAnalytics extends _i1.Mock implements _i10.CrashAnalytics { - @override - set enableInDevMode(bool? _enableInDevMode) => super.noSuchMethod( - Invocation.setter( - #enableInDevMode, - _enableInDevMode, - ), - returnValueForMissingStub: null, - ); - - @override - void crash() => super.noSuchMethod( - Invocation.method( - #crash, - [], - ), - returnValueForMissingStub: null, - ); - - @override - _i7.Future recordFlutterError(_i11.FlutterErrorDetails? details) => - (super.noSuchMethod( - Invocation.method( - #recordFlutterError, - [details], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future recordError( - dynamic exception, - StackTrace? stack, { - bool? fatal = false, - }) => - (super.noSuchMethod( - Invocation.method( - #recordError, - [ - exception, - stack, - ], - {#fatal: fatal}, - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - void log(String? msg) => super.noSuchMethod( - Invocation.method( - #log, - [msg], - ), - returnValueForMissingStub: null, - ); - - @override - _i7.Future setCustomKey( - String? key, - dynamic value, - ) => - (super.noSuchMethod( - Invocation.method( - #setCustomKey, - [ - key, - value, - ], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future setUserIdentifier(String? identifier) => (super.noSuchMethod( - Invocation.method( - #setUserIdentifier, - [identifier], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future setCrashAnalyticsEnabled(bool? enabled) => - (super.noSuchMethod( - Invocation.method( - #setCrashAnalyticsEnabled, - [enabled], - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); -} - -/// A class which mocks [Analytics]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockAnalytics extends _i1.Mock implements _i12.Analytics { - @override - void log(_i12.AnalyticsEvent? event) => super.noSuchMethod( - Invocation.method( - #log, - [event], - ), - returnValueForMissingStub: null, - ); - - @override - void setAnalyticsCollectionEnabled(bool? value) => super.noSuchMethod( - Invocation.method( - #setAnalyticsCollectionEnabled, - [value], - ), - returnValueForMissingStub: null, - ); - - @override - _i7.Future logSignUp({required String? signUpMethod}) => - (super.noSuchMethod( - Invocation.method( - #logSignUp, - [], - {#signUpMethod: signUpMethod}, - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future setCurrentScreen({required String? screenName}) => - (super.noSuchMethod( - Invocation.method( - #setCurrentScreen, - [], - {#screenName: screenName}, - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); - - @override - _i7.Future setUserProperty({ - required String? name, - required String? value, - }) => - (super.noSuchMethod( - Invocation.method( - #setUserProperty, - [], - { - #name: name, - #value: value, - }, - ), - returnValue: _i7.Future.value(), - returnValueForMissingStub: _i7.Future.value(), - ) as _i7.Future); -} diff --git a/app/test/sharezone_wrapped/sharezone_wrapped_view_test.dart b/app/test/sharezone_wrapped/sharezone_wrapped_view_test.dart deleted file mode 100644 index 22097809e..000000000 --- a/app/test/sharezone_wrapped/sharezone_wrapped_view_test.dart +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) -// Licensed under the EUPL-1.2-or-later. -// -// You may obtain a copy of the Licence at: -// https://joinup.ec.europa.eu/software/page/eupl -// -// SPDX-License-Identifier: EUPL-1.2 - -import 'package:common_domain_models/common_domain_models.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:sharezone/sharezone_wrapped/sharezone_wrapped_view.dart'; - -void main() { - group(SharezoneWrappedView, () { - test('should format totalAmountOfLessonHours correctly', () { - final view = SharezoneWrappedView.fromValues( - totalAmountOfLessonHours: 91234, - amountOfLessonHoursTopThreeCourses: [], - totalAmountOfHomeworks: 0, - amountOfHomeworksTopThreeCourses: [], - totalAmountOfExams: 0, - amountOfExamsTopThreeCourses: [], - ); - expect(view.totalAmountOfLessonHours, '91.234'); - }); - - test('should format amountOfLessonHoursTopThreeCourses correctly', () { - final view = SharezoneWrappedView.fromValues( - totalAmountOfLessonHours: 0, - amountOfLessonHoursTopThreeCourses: [ - (const CourseId('1'), 'Deutsch', 12345), - (const CourseId('2'), 'Mathematik', 9876), - (const CourseId('3'), 'Englisch', 8765), - ], - totalAmountOfHomeworks: 0, - amountOfHomeworksTopThreeCourses: [], - totalAmountOfExams: 0, - amountOfExamsTopThreeCourses: [], - ); - expect(view.amountOfLessonHoursTopThreeCourses, [ - '1. Deutsch: 12.345 Std.', - '2. Mathematik: 9.876 Std.', - '3. Englisch: 8.765 Std.', - ]); - }); - - test('should format totalAmountOfHomeworks correctly', () { - final view = SharezoneWrappedView.fromValues( - totalAmountOfLessonHours: 0, - amountOfLessonHoursTopThreeCourses: [], - totalAmountOfHomeworks: 1002, - amountOfHomeworksTopThreeCourses: [], - totalAmountOfExams: 0, - amountOfExamsTopThreeCourses: [], - ); - expect(view.totalAmountOfHomeworks, '1.002'); - }); - - test('should format amountOfHomeworksTopThreeCourses correctly', () { - final view = SharezoneWrappedView.fromValues( - totalAmountOfLessonHours: 0, - amountOfLessonHoursTopThreeCourses: [], - totalAmountOfHomeworks: 0, - amountOfHomeworksTopThreeCourses: [ - (const CourseId('1'), 'Deutsch', 1234), - (const CourseId('2'), 'Mathematik', 98), - (const CourseId('3'), 'Englisch', 87), - ], - totalAmountOfExams: 0, - amountOfExamsTopThreeCourses: [], - ); - expect(view.amountOfHomeworksTopThreeCourses, [ - '1. Deutsch: 1.234', - '2. Mathematik: 98', - '3. Englisch: 87', - ]); - }); - - test('should format totalAmountOfExams correctly', () { - final view = SharezoneWrappedView.fromValues( - totalAmountOfLessonHours: 0, - amountOfLessonHoursTopThreeCourses: [], - totalAmountOfHomeworks: 0, - amountOfHomeworksTopThreeCourses: [], - totalAmountOfExams: 1001, - amountOfExamsTopThreeCourses: [], - ); - expect(view.totalAmountOfExams, '1.001'); - }); - - test('should format amountOfExamsTopThreeCourses correctly', () { - final view = SharezoneWrappedView.fromValues( - totalAmountOfLessonHours: 0, - amountOfLessonHoursTopThreeCourses: [], - totalAmountOfHomeworks: 0, - amountOfHomeworksTopThreeCourses: [], - totalAmountOfExams: 0, - amountOfExamsTopThreeCourses: [ - (const CourseId('1'), 'Deutsch', 1234), - (const CourseId('2'), 'Mathematik', 98), - (const CourseId('3'), 'Englisch', 87), - ], - ); - expect(view.amountOfExamsTopThreeCourses, [ - '1. Deutsch: 1.234', - '2. Mathematik: 98', - '3. Englisch: 87', - ]); - }); - }); -} diff --git a/app/test_goldens/settings/settings_page_test.dart b/app/test_goldens/settings/settings_page_test.dart index 58f36613f..ca5d71b68 100644 --- a/app/test_goldens/settings/settings_page_test.dart +++ b/app/test_goldens/settings/settings_page_test.dart @@ -11,28 +11,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:golden_toolkit/golden_toolkit.dart'; import 'package:mockito/annotations.dart'; -import 'package:provider/provider.dart'; -import 'package:remote_configuration/remote_configuration.dart'; import 'package:sharezone/main/application_bloc.dart'; import 'package:sharezone/settings/settings_page.dart'; import 'package:sharezone_widgets/sharezone_widgets.dart'; import 'settings_page_test.mocks.dart'; -@GenerateNiceMocks([ - MockSpec(), - MockSpec(), -]) +@GenerateNiceMocks([MockSpec()]) void main() { group(SettingsPageBody, () { Future pushSettingsPage(WidgetTester tester, ThemeData theme) async { await tester.pumpWidgetBuilder( BlocProvider( bloc: MockSharezoneContext(), - child: Provider.value( - value: MockRemoteConfiguration(), - child: const SettingsPageBody(), - ), + child: const SettingsPageBody(), ), wrapper: materialAppWrapper(theme: theme), ); diff --git a/app/test_goldens/settings/settings_page_test.mocks.dart b/app/test_goldens/settings/settings_page_test.mocks.dart index c86f87b4d..35fb5e1e0 100644 --- a/app/test_goldens/settings/settings_page_test.mocks.dart +++ b/app/test_goldens/settings/settings_page_test.mocks.dart @@ -3,12 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i9; - import 'package:analytics/analytics.dart' as _i3; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i10; -import 'package:remote_configuration/src/remote_configuration.dart' as _i8; import 'package:shared_preferences/shared_preferences.dart' as _i5; import 'package:sharezone/main/application_bloc.dart' as _i7; import 'package:sharezone/util/api.dart' as _i2; @@ -162,70 +158,3 @@ class MockSharezoneContext extends _i1.Mock implements _i7.SharezoneContext { returnValueForMissingStub: null, ); } - -/// A class which mocks [RemoteConfiguration]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockRemoteConfiguration extends _i1.Mock - implements _i8.RemoteConfiguration { - @override - void initialize(Map? defaultValues) => super.noSuchMethod( - Invocation.method( - #initialize, - [defaultValues], - ), - returnValueForMissingStub: null, - ); - - @override - _i9.Future activate() => (super.noSuchMethod( - Invocation.method( - #activate, - [], - ), - returnValue: _i9.Future.value(false), - returnValueForMissingStub: _i9.Future.value(false), - ) as _i9.Future); - - @override - _i9.Future fetch() => (super.noSuchMethod( - Invocation.method( - #fetch, - [], - ), - returnValue: _i9.Future.value(), - returnValueForMissingStub: _i9.Future.value(), - ) as _i9.Future); - - @override - String getString(String? key) => (super.noSuchMethod( - Invocation.method( - #getString, - [key], - ), - returnValue: _i10.dummyValue( - this, - Invocation.method( - #getString, - [key], - ), - ), - returnValueForMissingStub: _i10.dummyValue( - this, - Invocation.method( - #getString, - [key], - ), - ), - ) as String); - - @override - bool getBool(String? key) => (super.noSuchMethod( - Invocation.method( - #getBool, - [key], - ), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); -} diff --git a/app/test_goldens/sharezone_plus/sharezone_plus_page_test.mocks.dart b/app/test_goldens/sharezone_plus/sharezone_plus_page_test.mocks.dart index 7d38a3dd9..014643301 100644 --- a/app/test_goldens/sharezone_plus/sharezone_plus_page_test.mocks.dart +++ b/app/test_goldens/sharezone_plus/sharezone_plus_page_test.mocks.dart @@ -1214,16 +1214,6 @@ class MockUserGateway extends _i2.Mock implements _i13.UserGateway { returnValueForMissingStub: _i24.Future.value(), ) as _i24.Future); - @override - _i24.Future sendVerificationEmail() => (super.noSuchMethod( - Invocation.method( - #sendVerificationEmail, - [], - ), - returnValue: _i24.Future.value(), - returnValueForMissingStub: _i24.Future.value(), - ) as _i24.Future); - @override _i24.Future deleteUser(_i4.SharezoneGateway? gateway) => (super.noSuchMethod(