From f7ffba7d317447934d2bdc4a91f10c9ac477267a Mon Sep 17 00:00:00 2001 From: Xavier Paquet-Rapold <80051842+XavierPaquet-Rapold@users.noreply.github.com> Date: Sun, 21 Jul 2024 13:56:26 -0400 Subject: [PATCH] Hotfix/#882 fix dashboard reorganisation (#1023) * Remove broadcast card from reorderable list * Fix some tests * Create migration * Fix migration with removed item * Remove broadcastCard from shared prefs * Remove broadcastChange from shared prefs * Fix tests * Last changes before review * [BOT] Applying version. * Fix TODO version * [BOT] Applying format. * Fix analyze * [BOT] Update golden files --------- Co-authored-by: XavierPaquet-Rapold Co-authored-by: clubapplets-server --- lib/constants/preferences_flags.dart | 2 - lib/features/dashboard/dashboard_view.dart | 75 +++++++++--------- .../dashboard/dashboard_viewmodel.dart | 47 +++++------ .../more/settings/settings_manager.dart | 13 +-- pubspec.lock | 8 ++ pubspec.yaml | 2 +- test/managers/settings_manager_test.dart | 34 +++----- test/ui/views/dashboard_view_test.dart | 63 ++++++--------- .../dashboardView_appletsCard_1.png | Bin 3340 -> 4611 bytes .../dashboardView_progressBarCard_1.png | Bin 4170 -> 5550 bytes .../dashboardView_scheduleCard_1.png | Bin 3523 -> 4926 bytes test/ui/views/schedule_default_view_test.dart | 3 +- test/viewmodels/dashboard_viewmodel_test.dart | 61 +++++--------- 13 files changed, 132 insertions(+), 176 deletions(-) diff --git a/lib/constants/preferences_flags.dart b/lib/constants/preferences_flags.dart index 67ef95b64..5d5cb0110 100644 --- a/lib/constants/preferences_flags.dart +++ b/lib/constants/preferences_flags.dart @@ -35,13 +35,11 @@ enum PreferencesFlag { discoveryMore, // Dashboard flags - broadcastCard, aboutUsCard, scheduleCard, progressBarCard, gradesCard, progressBarText, - broadcastChange, // Rating flag ratingTimer, diff --git a/lib/features/dashboard/dashboard_view.dart b/lib/features/dashboard/dashboard_view.dart index 71617d41c..addedaeb8 100644 --- a/lib/features/dashboard/dashboard_view.dart +++ b/lib/features/dashboard/dashboard_view.dart @@ -80,6 +80,10 @@ class _DashboardViewState extends State data: Theme.of(context) .copyWith(canvasColor: Colors.transparent), child: ReorderableListView( + header: + model.remoteConfigService.dashboardMessageActive + ? _buildMessageBroadcastCard(model) + : null, onReorder: (oldIndex, newIndex) => onReorder(model, oldIndex, newIndex), padding: const EdgeInsets.fromLTRB(0, 4, 0, 24), @@ -96,16 +100,11 @@ class _DashboardViewState extends State List _buildCards(DashboardViewModel model) { final List cards = List.empty(growable: true); - // always try to build broadcast cart so the user doesn't miss out on // important info if they dismissed it previously for (final PreferencesFlag element in model.cardsToDisplay ?? []) { switch (element) { - case PreferencesFlag.broadcastCard: - if (model.remoteConfigService.dashboardMessageActive) { - cards.add(_buildMessageBroadcastCard(model, element)); - } case PreferencesFlag.aboutUsCard: cards.add(_buildAboutUsCard(model, element)); case PreferencesFlag.scheduleCard: @@ -114,7 +113,6 @@ class _DashboardViewState extends State cards.add(_buildProgressBarCard(model, element)); case PreferencesFlag.gradesCard: cards.add(_buildGradesCards(model, element)); - default: } @@ -459,43 +457,48 @@ class _DashboardViewState extends State ); } - Widget _buildMessageBroadcastCard( - DashboardViewModel model, PreferencesFlag flag) { + Widget _buildMessageBroadcastCard(DashboardViewModel model) { + if (model.broadcastMessage == "" || + model.broadcastColor == "" || + model.broadcastTitle == "") { + return const SizedBox.shrink(); + } final broadcastMsgColor = Color(int.parse(model.broadcastColor)); final broadcastMsgType = model.broadcastType; final broadcastMsgUrl = model.broadcastUrl; - return DismissibleCard( + return Card( key: UniqueKey(), - onDismissed: (DismissDirection direction) { - dismissCard(model, flag); - }, - isBusy: model.busy(model.broadcastMessage), - cardColor: broadcastMsgColor, + color: broadcastMsgColor, child: Padding( padding: const EdgeInsets.fromLTRB(17, 10, 15, 20), - child: Column(mainAxisSize: MainAxisSize.min, children: [ - // title row - Row( - children: [ - Expanded( - child: Align( - alignment: Alignment.centerLeft, - child: Text(model.broadcastTitle, - style: Theme.of(context).primaryTextTheme.titleLarge), - ), - ), - Align( - alignment: Alignment.centerRight, - child: InkWell( - child: getBroadcastIcon(broadcastMsgType, broadcastMsgUrl), + child: model.busy(model.broadcastMessage) + ? const Center(child: CircularProgressIndicator()) + : Column(mainAxisSize: MainAxisSize.min, children: [ + // title row + Row( + children: [ + Expanded( + child: Align( + alignment: Alignment.centerLeft, + child: Text(model.broadcastTitle, + style: Theme.of(context) + .primaryTextTheme + .titleLarge), + ), + ), + Align( + alignment: Alignment.centerRight, + child: InkWell( + child: getBroadcastIcon( + broadcastMsgType, broadcastMsgUrl), + ), + ), + ], ), - ), - ], - ), - // main text - AutoSizeText(model.broadcastMessage, - style: Theme.of(context).primaryTextTheme.bodyMedium) - ]), + // main text + AutoSizeText(model.broadcastMessage, + style: Theme.of(context).primaryTextTheme.bodyMedium) + ]), )); } diff --git a/lib/features/dashboard/dashboard_viewmodel.dart b/lib/features/dashboard/dashboard_viewmodel.dart index 92c00020b..804c31fac 100644 --- a/lib/features/dashboard/dashboard_viewmodel.dart +++ b/lib/features/dashboard/dashboard_viewmodel.dart @@ -8,6 +8,7 @@ import 'package:flutter/material.dart'; import 'package:feature_discovery/feature_discovery.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:stacked/stacked.dart'; // Project imports: @@ -36,7 +37,6 @@ class DashboardViewModel extends FutureViewModel> { static const String tag = "DashboardViewModel"; final SettingsManager _settingsManager = locator(); - final PreferencesService _preferencesService = locator(); final CourseRepository _courseRepository = locator(); final AnalyticsService _analyticsService = locator(); final RemoteConfigService remoteConfigService = @@ -197,9 +197,27 @@ class DashboardViewModel extends FutureViewModel> { Future> futureToRun() async { final dashboard = await _settingsManager.getDashboard(); - _cards = dashboard; + //TODO: remove when all users are on 4.50.1 or more + final sharedPreferences = await SharedPreferences.getInstance(); + if (sharedPreferences.containsKey("PreferencesFlag.broadcastChange")) { + sharedPreferences.remove("PreferencesFlag.broadcastChange"); + } + if (sharedPreferences.containsKey("PreferencesFlag.broadcastCard")) { + sharedPreferences.remove("PreferencesFlag.broadcastCard"); + } + final sortedList = dashboard.entries.toList() + ..sort((a, b) => a.value.compareTo(b.value)); + final sortedDashboard = LinkedHashMap.fromEntries(sortedList); + int index = 0; + for (final element in sortedDashboard.entries) { + if (element.value >= 0) { + sortedDashboard.update(element.key, (value) => index); + index++; + } + } + //TODO: end remove when all users are on 4.50.1 or more - await checkForBroadcastChange(); + _cards = sortedDashboard; getCardsToDisplay(); @@ -207,7 +225,7 @@ class DashboardViewModel extends FutureViewModel> { // (moved from getCardsToDisplay()) await loadDataAndUpdateWidget(); - return dashboard; + return sortedDashboard; } Future loadDataAndUpdateWidget() async { @@ -254,13 +272,13 @@ class DashboardViewModel extends FutureViewModel> { void setAllCardsVisible() { _cards?.updateAll((key, value) { _settingsManager - .setInt(key, key.index - PreferencesFlag.broadcastCard.index) + .setInt(key, key.index - PreferencesFlag.aboutUsCard.index) .then((value) { if (!value) { Fluttertoast.showToast(msg: _appIntl.error); } }); - return key.index - PreferencesFlag.broadcastCard.index; + return key.index - PreferencesFlag.aboutUsCard.index; }); getCardsToDisplay(); @@ -288,23 +306,6 @@ class DashboardViewModel extends FutureViewModel> { _analyticsService.logEvent(tag, "Restoring cards"); } - Future checkForBroadcastChange() async { - final broadcastChange = - await _preferencesService.getString(PreferencesFlag.broadcastChange) ?? - ""; - if (broadcastChange != remoteConfigService.dashboardMessageEn) { - // Update pref - _preferencesService.setString(PreferencesFlag.broadcastChange, - remoteConfigService.dashboardMessageEn); - if (_cards != null && _cards![PreferencesFlag.broadcastCard]! < 0) { - _cards?.updateAll((key, value) { - return value >= 0 ? value + 1 : value; - }); - _cards![PreferencesFlag.broadcastCard] = 0; - } - } - } - Future> futureToRunSessionProgressBar() async { try { final progressBarText = diff --git a/lib/features/more/settings/settings_manager.dart b/lib/features/more/settings/settings_manager.dart index 9cd1fb68c..0acb0830a 100644 --- a/lib/features/more/settings/settings_manager.dart +++ b/lib/features/more/settings/settings_manager.dart @@ -94,14 +94,6 @@ class SettingsManager with ChangeNotifier { /// Get Dashboard Future> getDashboard() async { final Map dashboard = {}; - - final broadcastCardIndex = - await _preferencesService.getInt(PreferencesFlag.broadcastCard) ?? - getDefaultCardIndex(PreferencesFlag.broadcastCard); - - dashboard.putIfAbsent( - PreferencesFlag.broadcastCard, () => broadcastCardIndex); - final aboutUsIndex = await _preferencesService.getInt(PreferencesFlag.aboutUsCard) ?? getDefaultCardIndex(PreferencesFlag.aboutUsCard); @@ -277,9 +269,8 @@ class SettingsManager with ChangeNotifier { } /// Get the default index of each card - int getDefaultCardIndex(PreferencesFlag flag) { - return flag.index - PreferencesFlag.broadcastCard.index; - } + int getDefaultCardIndex(PreferencesFlag flag) => + flag.index - PreferencesFlag.aboutUsCard.index; bool get calendarViewSetting => _remoteConfigService.scheduleListViewDefault; } diff --git a/pubspec.lock b/pubspec.lock index 0b1690541..57df3fffc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1261,6 +1261,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1" + skeletonizer: + dependency: "direct main" + description: + name: skeletonizer + sha256: "9dcaec747d200a299bc457ffe51f135b9856b7f9097e851e277c4c95f563893b" + url: "https://pub.dev" + source: hosted + version: "1.4.1+1" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index b1aa760dd..b1573bf0d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: The 4th generation of ÉTSMobile, the main gateway between the Éco # pub.dev using `pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 4.50.0+1 +version: 4.50.1+1 environment: sdk: '>=3.3.0 <4.0.0' diff --git a/test/managers/settings_manager_test.dart b/test/managers/settings_manager_test.dart index 1dce2fd4f..de37ee17f 100644 --- a/test/managers/settings_manager_test.dart +++ b/test/managers/settings_manager_test.dart @@ -418,11 +418,10 @@ void main() { // Cards final Map expected = { - PreferencesFlag.broadcastCard: 0, - PreferencesFlag.aboutUsCard: 1, - PreferencesFlag.scheduleCard: 2, - PreferencesFlag.progressBarCard: 3, - PreferencesFlag.gradesCard: 4 + PreferencesFlag.aboutUsCard: 0, + PreferencesFlag.scheduleCard: 1, + PreferencesFlag.progressBarCard: 2, + PreferencesFlag.gradesCard: 3 }; expect( @@ -430,8 +429,6 @@ void main() { expected, ); - verify(preferencesServiceMock.getInt(PreferencesFlag.broadcastCard)) - .called(1); verify(preferencesServiceMock.getInt(PreferencesFlag.aboutUsCard)) .called(1); verify(preferencesServiceMock.getInt(PreferencesFlag.scheduleCard)) @@ -447,29 +444,24 @@ void main() { test("validate the loading of the cards", () async { PreferencesServiceMock.stubGetInt( - preferencesServiceMock, PreferencesFlag.broadcastCard, - toReturn: 0); - PreferencesServiceMock.stubGetInt( - preferencesServiceMock, PreferencesFlag.aboutUsCard, - toReturn: 2); + preferencesServiceMock, PreferencesFlag.aboutUsCard); PreferencesServiceMock.stubGetInt( preferencesServiceMock, PreferencesFlag.scheduleCard, - toReturn: 3); + toReturn: 2); PreferencesServiceMock.stubGetInt( preferencesServiceMock, PreferencesFlag.progressBarCard, // ignore: avoid_redundant_argument_values - toReturn: 1); + toReturn: 0); PreferencesServiceMock.stubGetInt( preferencesServiceMock, PreferencesFlag.gradesCard, - toReturn: 4); + toReturn: 3); // Cards final Map expected = { - PreferencesFlag.broadcastCard: 0, - PreferencesFlag.aboutUsCard: 2, - PreferencesFlag.scheduleCard: 3, - PreferencesFlag.progressBarCard: 1, - PreferencesFlag.gradesCard: 4 + PreferencesFlag.aboutUsCard: 1, + PreferencesFlag.scheduleCard: 2, + PreferencesFlag.progressBarCard: 0, + PreferencesFlag.gradesCard: 3 }; expect( @@ -477,8 +469,6 @@ void main() { expected, ); - verify(preferencesServiceMock.getInt(PreferencesFlag.broadcastCard)) - .called(1); verify(preferencesServiceMock.getInt(PreferencesFlag.aboutUsCard)) .called(1); verify(preferencesServiceMock.getInt(PreferencesFlag.scheduleCard)) diff --git a/test/ui/views/dashboard_view_test.dart b/test/ui/views/dashboard_view_test.dart index 22d168135..0e30abd63 100644 --- a/test/ui/views/dashboard_view_test.dart +++ b/test/ui/views/dashboard_view_test.dart @@ -19,6 +19,7 @@ import 'package:notredame/features/app/widgets/dismissible_card.dart'; import 'package:notredame/features/dashboard/dashboard_view.dart'; import 'package:notredame/features/dashboard/widgets/course_activity_tile.dart'; import 'package:notredame/features/student/grades/widgets/grade_button.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../helpers.dart'; import '../../mock/managers/course_repository_mock.dart'; import '../../mock/managers/settings_manager_mock.dart'; @@ -71,11 +72,10 @@ void main() { // Cards Map dashboard = { - PreferencesFlag.broadcastCard: 0, - PreferencesFlag.aboutUsCard: 1, - PreferencesFlag.scheduleCard: 2, - PreferencesFlag.progressBarCard: 3, - PreferencesFlag.gradesCard: 4 + PreferencesFlag.aboutUsCard: 0, + PreferencesFlag.scheduleCard: 1, + PreferencesFlag.progressBarCard: 2, + PreferencesFlag.gradesCard: 3 }; final numberOfCards = dashboard.entries.length; @@ -164,7 +164,7 @@ void main() { // Find schedule card in second position by its title return tester.firstWidget(find.descendant( - of: find.byType(Dismissible, skipOffstage: false).at(2), + of: find.byType(Dismissible, skipOffstage: false).at(1), matching: find.byType(Text), )); } @@ -180,6 +180,9 @@ void main() { setupNetworkingServiceMock(); setupAnalyticsServiceMock(); setupPreferencesServiceMock(); + // TODO: Remove when 4.50.1 is released + SharedPreferences.setMockInitialValues({}); + // End TODO: Remove when 4.50.1 is released inAppReviewServiceMock = setupInAppReviewServiceMock() as InAppReviewServiceMock; @@ -199,24 +202,14 @@ void main() { CourseRepositoryMock.stubCoursesActivities(courseRepositoryMock); CourseRepositoryMock.stubGetCoursesActivities(courseRepositoryMock, fromCacheOnly: true); - CourseRepositoryMock.stubGetCoursesActivities(courseRepositoryMock); - RemoteConfigServiceMock.stubGetBroadcastEnabled(remoteConfigServiceMock); - RemoteConfigServiceMock.stubGetBroadcastColor(remoteConfigServiceMock); - RemoteConfigServiceMock.stubGetBroadcastEn(remoteConfigServiceMock); - RemoteConfigServiceMock.stubGetBroadcastFr(remoteConfigServiceMock); - RemoteConfigServiceMock.stubGetBroadcastTitleEn(remoteConfigServiceMock); - RemoteConfigServiceMock.stubGetBroadcastTitleFr(remoteConfigServiceMock); - RemoteConfigServiceMock.stubGetBroadcastType(remoteConfigServiceMock); - RemoteConfigServiceMock.stubGetBroadcastUrl(remoteConfigServiceMock); + RemoteConfigServiceMock.stubGetBroadcastEnabled(remoteConfigServiceMock, + toReturn: false); SettingsManagerMock.stubGetBool( settingsManagerMock, PreferencesFlag.discoveryDashboard, toReturn: true); - SettingsManagerMock.stubSetInt( - settingsManagerMock, PreferencesFlag.broadcastCard); - SettingsManagerMock.stubSetInt( settingsManagerMock, PreferencesFlag.aboutUsCard); @@ -353,7 +346,7 @@ void main() { of: find.byType(SizedBox, skipOffstage: false), matching: find.byType(Text), ), - findsNWidgets(1)); + findsNWidgets(2)); }); }); @@ -369,9 +362,6 @@ void main() { SettingsManagerMock.stubGetDashboard(settingsManagerMock, toReturn: dashboard); - SettingsManagerMock.stubSetInt( - settingsManagerMock, PreferencesFlag.broadcastCard); - SettingsManagerMock.stubSetInt( settingsManagerMock, PreferencesFlag.aboutUsCard); @@ -395,7 +385,7 @@ void main() { expect(find.text(intl.card_applets_title), findsOneWidget); // Swipe Dismissible aboutUs Card horizontally - await tester.drag(find.byType(Dismissible, skipOffstage: false).at(1), + await tester.drag(find.byType(Dismissible, skipOffstage: false).at(0), const Offset(1000.0, 0.0)); // Check that the card is now absent from the view @@ -425,9 +415,6 @@ void main() { fromCacheOnly: true); CourseRepositoryMock.stubGetCoursesActivities(courseRepositoryMock); - SettingsManagerMock.stubSetInt( - settingsManagerMock, PreferencesFlag.broadcastCard); - SettingsManagerMock.stubSetInt( settingsManagerMock, PreferencesFlag.aboutUsCard); @@ -454,7 +441,7 @@ void main() { // Check that the aboutUs card is in the first position var text = tester.firstWidget(find.descendant( - of: find.byType(Dismissible, skipOffstage: false).at(1), + of: find.byType(Dismissible, skipOffstage: false).at(0), matching: find.byType(Text), )); @@ -485,7 +472,7 @@ void main() { await tester.pumpAndSettle(); text = tester.firstWidget(find.descendant( - of: find.byType(Dismissible, skipOffstage: false).at(1), + of: find.byType(Dismissible, skipOffstage: false).at(0), matching: find.byType(Text), )); @@ -513,7 +500,7 @@ void main() { findsOneWidget); // Swipe Dismissible schedule Card horizontally - await tester.drag(find.byType(Dismissible, skipOffstage: false).at(2), + await tester.drag(find.byType(Dismissible, skipOffstage: false).at(1), const Offset(1000.0, 0.0)); // Check that the card is now absent from the view @@ -596,9 +583,6 @@ void main() { testWidgets('gradesCard is dismissible and can be restored', (WidgetTester tester) async { - SettingsManagerMock.stubSetInt( - settingsManagerMock, PreferencesFlag.broadcastCard); - SettingsManagerMock.stubSetInt( settingsManagerMock, PreferencesFlag.aboutUsCard); @@ -625,10 +609,11 @@ void main() { findsOneWidget); // Swipe Dismissible grades Card horizontally - await tester.drag( - find.widgetWithText(Dismissible, intl.grades_title, - skipOffstage: false), - const Offset(1000.0, 0.0)); + final finder = find.widgetWithText(Dismissible, intl.grades_title, + skipOffstage: false); + await tester.scrollUntilVisible(finder, 100); + await tester.pumpAndSettle(); + await tester.drag(finder, const Offset(1000.0, 0.0)); // Check that the card is now absent from the view await tester.pumpAndSettle(); @@ -792,7 +777,7 @@ void main() { tester.view.physicalSize = const Size(800, 1410); final Map dashboard = { - PreferencesFlag.broadcastCard: 0, + PreferencesFlag.gradesCard: 0, PreferencesFlag.aboutUsCard: 1, }; @@ -819,7 +804,7 @@ void main() { CourseRepositoryMock.stubGetCoursesActivities(courseRepositoryMock); dashboard = { - PreferencesFlag.broadcastCard: 0, + PreferencesFlag.gradesCard: 0, PreferencesFlag.scheduleCard: 1, }; @@ -840,7 +825,7 @@ void main() { tester.view.physicalSize = const Size(800, 1410); dashboard = { - PreferencesFlag.broadcastCard: 0, + PreferencesFlag.gradesCard: 0, PreferencesFlag.progressBarCard: 1, }; diff --git a/test/ui/views/goldenFiles/dashboardView_appletsCard_1.png b/test/ui/views/goldenFiles/dashboardView_appletsCard_1.png index 19a16be9ddb3c1c35d5f44d78b38fe67db36e440..8afc927e34449dd32b610d9d398598300d8e6b27 100644 GIT binary patch literal 4611 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 diff --git a/test/ui/views/goldenFiles/dashboardView_progressBarCard_1.png b/test/ui/views/goldenFiles/dashboardView_progressBarCard_1.png index 7d9c7822bce29dded7db633d347a863c9a6ee06a..0efddafbff26f85111fd2160247d0ea83266918e 100644 GIT binary patch literal 5550 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 diff --git a/test/ui/views/goldenFiles/dashboardView_scheduleCard_1.png b/test/ui/views/goldenFiles/dashboardView_scheduleCard_1.png index dfea879e14b0794a253cd68b78da7e0c2e0ec258..4163d4bea454d6c8dc2b6fd312a5132dfd3a40cf 100644 GIT binary patch literal 4926 zcmb`L2UL^Uw#RX}HtIx#&@rHlko83QUvPn3Xw(n9D-KxZsKC>Dy+g#kna zj8q970!kS`st||}I)o5`1PCGT!|}a$XO^z(tb4Q8x6az<n#y`-f&RXpQe%O635j;Ex zX3s)@vIt6KgT1=DXsH--tctAG9#|mecN1)26of@w(x`dhYuCb?;>Y z#kQ~y6+)ETcl{Qz`@X!Gag;5O(!Vn< zj`WCNJwDhRAqYK-s<5fKKvVGSZA&O7-2ubN<15l(>*1sX8~E@N)yeKtZ~p79`?^Eg za7q{Qla7LlRBrxA;JMiR-5C)752h+N4}QU55anL-ZmeWv#E4jIU9+yOQ2zAS_)qgT zgMEP6Exrl7t?wED;`+M&@7&Mbqm=L%f~(zjO@8}g{s#)48_9K(Er$QY$~4u|BPqy>y`>$Z2(9Q2lhQxI}BTgos(J;VX`!N~yP6 z{Bf;nE~{~4CJphduuv6x`>MEp_bjC@d^}yBuC}1dbRG+LW^_hmO?*(Z_mx8`pI_w%!sbnVc*Hu5R{yiOsZs zePFrwXq9bm>EU#C`@_d;A9xw9irnQV;q;LTpNb=4x>N|Yi>GS8$D+~(xzXCQ^2mLN+;=O4X6xv*` zE*w20rW$F$B9|1J49AjMA>q;p>Gd4jx-c9Rni@DihiZ?h@QMrIwSF1eIWLYTKOg{Q zM8xA0sEg#V8!26kL@lHE0FK}w*hC|=?*WP`sBIHkXe=r?YxIL`C97e=fiGxlJ~o)P zHaMJ0xu#OY-dH2i&|$vbeFNp}6$fK*K>eUlL{Ii>7OGaYQ%IMP`512H>_0P_sVd4z-_yQ0B8J?|9#yvzt9p7drhn$>Ndr8 zC494n{K@V9Go#P@Mq_C~F3E{Swq{1=IqE1}bJWgWq)O&V6?S^Xd&dc{3XnIT0 zJ{djvafF)IvY<2&2-t$2BI<_>$3H~sTO>pC&Oqm#aP|ba{KRC_nv{OPPsTGTobDHo zg9n~~KpNxm`xz-uSe%7;F`K_g>A580UN_Api;a-Vy>6H|Trjgq!=3UIZ8Lq*@o!9E zsbPQRUPVjYKgrbJHO{@YU7hX8uB`Fs&4oD#SjwnEDh^g)))uY(U_evhf&)2>RTHFK zt&&*~vQVgvA6Z*lQ<#a5Hg$4xLb0cE)UAW1|irhfda!p-CA+QN&rV(YA;YVV^DK_?K>F2H7`FvHNWXW&B`I-iUp*_IqbDK zS%c7W>Q$bE^1#ty_v_cA5{hdN;KhujcE+k03oBTsV`ybIC-s8h(tgWwPkPIsPXo|$ z`qwB%1xK&c-#i5szf0haLn+28S8r@SUq#n-SA_sW^4Iw{p`y7{3(7wOehyYoiW6al~yGhOIeCa$*1VzG|9 zt>OQsTgSQYnK-6nC^oey$ArLRsBKT)+H)q~i+=0tl=Wm^xk4Plu|~7K=~c6X#fWHW zjbpJA#}CI!<6PJlwo6hnQe#}q_}0qr>U{$PmpPr1O-I|LIBb?W89g&f3;nfZ5t7E7 z>&=@N9y%Hw8*|~1ndq3^8k4!<@n*FkuXV}>&Uhm1y0$c`F9{QeD8?A+GNnops|9qh z!ANB|r2F+ip#%6v@<1~>-0nb$EcS=(^+|}~3LVF0#%!#};^p=Vy-ihP_1;H!rATX! zVUeghV5*hwZ3-G56D;RJZ(<@_{N|BhYE0c}YII8_efvqz@USEZG)fGLqZq9EM(c)l zlnYS;RRG;O6ozG(k~q{jeL3&Cjo8`#f*`X&A*%+wdX2aUjC+}(4a0nytE+ESnb)sh zpLk`S+mZve@LGZC)yF;sNc?;1YFcn$&v8JYmfLx$uT9OJy9`*K3-`;B3`Q%Y6}&f0 zX`mPZ0fF+;LPN=ZRId@_sIlk^c!^$%bdbwVDKCHceCojp%J4M0nkMY(6yCH(vW%7u za3Kdbbtb@-Elqhhg(LPZ;a;vMHp868MF%FdT}V3Q3hJE2C|1iFKRG zESK>*uRiM`aZ5nd4LGx(l&#lmP_=6%H}{w`0Yz<5RRr-5%>_`(Fevt~bvR4E*c8gY1j*;}uy-*4 zU(y&}SBSQZcTv~XpPK)FQ2H$a^;h`k-!@t^DkBky{ck|}Z&N-e&_N{ENmF&HYNqIw z#mT8grJcyn6*8z(qtOy4g-$AJTwdQ2|t_)2Yf+PjIi zzoZUxeyk7V2TK-n8s&wDSQm3{`2Al_@Nc&t!089sRO6{{!T+~|7GNcy$WbFHT3+*| zB%c1Bk0^5#(WVRj38R#%S`saYf~jb1|E?;zVl1?z(g}e;?9jKbzhATh0pGlMCuz68 zrZU3Gj$Bksci3r?KDqc|g83*sG;8Ozho_!?zXCSAOy;hxaC^_SIAcvrP?!cP|B>nw znaXxmo*teuCIqM;!QM#Hn-UzBJb28D$^48TaBpuY?`8o zR~=0NpNZe`6yoA5^Pdgf{7_uQOX|!^prQQ+8+{@uR);>G4c=Pb(wZsX(8Vj~!eudw z1T!esF90=e3byi%G%nNB)F#!XnxiQyW?p3&1sJ_rJ_mr8sbF`dzcvL*c%zOwqvp>=wO(Tr#qu~Z$;=BJEV zEFLsb*_cvXe9nlq!_P!fe0c1L z_v^Bw03V+lUD;umAXSnNpJ8XkMAz;>c+>Ta61|26?+9^$sn~sVRB@cBt!~B6Hsq+jPl=vNETOB$0{HCj5aR-8CG$9lwJ`KIz2|w%47_?BF3AjlaF9U^-)K%3piZ#A9`@{L6Tg?j?`MBKA0e;`kd3av4FSDI}@9VmlUo+=s(F}B}#I8rSaNSh4 zM!EjOC?}eQRO3v{=X;PSZd9mE=`y1gx&6z=+y=5WHfA@!*l#ls{XowSb!3>rwmmCZ z^TtF~1|lP!lCGJ^E*Kl37L$wsR%)z_VR~1H6I8O@Huv?buieDNcaiSB8bS%`yW0u? zPiWW*vC|c29C;E*ZO(a_g*{q{r^}M_TX*$S>34Y~w!Qb=KlGQR=d<{3K`u+~j@>?W T{Wfq1#&gyb1}!>u<(K~f2nZ8F literal 3523 zcmeHKX;hPE7A7K#Qi@xVowlBl<0#?=76QZyf{Yak8rcaYS|DIE7(!S~aKV+$r2`Zs zp`{uPn3OdnED;1^g@6#kmV^LNwrqqXBoGJ_v8U}=JMEnLH)p~qvJKt~5)q?LX{eeIV>MR}?A20#ROAJ!puSxswS)*=r3oHW#4 z=M7I^*MiRacz${^`JRZ2z7>u{)1{K602>c|!-;jpULR$B{+VHrOUBv_hJW=bNqW*_ zdgkGN`}IdY0{~w6t@pGz#0In*Joty*m9MhVkmU^>YBTL0&SileH4Mrb+ zYB{>x@e6Yy%dImr;%Q<&1Vc$pO9MKCA}=KI&`JwsQ-Wi{cxz#b zs?%k@06Ozt&c3GYQeLX)1C zeYP!1YM*HVrRP}B8^l)x>61GPoy(*x!;|crN0zcr=Z7Wvphe%20!u5-s0#K%VPd;U z);gJQ`SJr{;AXqe%6m#t$KE%HhmsoR{`OcB0Wnz?5JD2!j}_g@WhQ)iMJ46OP2Z`H zoAG|I{hA;TT)JX3V?gGd zM5EDQaE+`BIN*m#OtVJF_lC03f{LKzS1pTWi0;_0(#QF@a!GhvxTuz0(A;HhrcXS*Vo!$UXJCxUeosc1BT+RJ95scz-CWCA`;2E$Dec}2NFYu z&V_XZm4}jv6nDiori-g%i6sjWylVE39MYO{Snw zmKB3_3H-dv*Yz3%q6TIcLjhT#lR|S6WR|}a`0bBUOq7}vO52;Zy6o1wx$e%K6J{Il zy(!jTm%*QI32*Al{7!vZJ#b(A%71U_Kdj-b;o%FJ4vlq0nsl+&#C1iuP&51d%2^3{ z^p2h*ysM#BSwT{uhG7}aoXS4h@00X=KOJsejE9Fh@%}rLaKnsP#iCEG9Eg8 zVXQ~(1xKLCJ@qwK%zdVOdN!O$Q}t%9=9sIJQ^ioM+q}JcRo9*!M+D8QN>_E|DX`-R zbW4VGH8-1?CSMVGN(W_9a>$dTy)g%1({uGjYw-@cU+qm zrKzHt0RjOg9ISBU|6p!UugPlbu?13-hR);@2qCgQhqwjMZk`u&?Nv4}Tt;RnD2Rzu zfq{V?3HH#6r|$#%%ptC&lx3Dtw<2(3@>Z%ulP0)Y)WqXx<{(&>WDvuPmMV;Br_zKK z-rz=LQo_75L_E6X;#fbI84gj&n1yUSM$=b_c_GKpm6n-%q3wN)gPcB2lcqiW;W5)N z&bP5^o=zX6r8H`$zE5FkQDCrITm=tLSZG0UCarnRDI6hx2HupAf>4tj>g(JQ&+!7q z07UR4@#5I*AU~HS_rS9@`?>pr;l*YgB)yoi^M)o~AsUf&V^=~+5Dw*Kj*EOYx8F|^ zvG3UqU5{AigX72_FJ%g#bZdV%hxr35%eA3f2fjw*@tEM9r`&^3yD6pE zG!129MN%^mp=BclXUmrsZr0*t*-Z>fe#fm-5vkMnseB?3#v)vU zDK?kIy_Tm}jdk6uUVN%PAA@rly`T#l?u$jXmIphk2Zt^@he=AJ01eS{>VomRxW}JO z>_0(c{%`7+iSS31?|=8KZdm^|w%h*2pFA7JAMCromE)!*w24z{fgF)L^(4!M-yow6 z-{$YClUL?g;WuN>t8)b!0~<4W!bJM3osM5DWxU@RGn*PAd~_u+Y_AsU4)rQdZnzZRlI)}2yFEsT++#OSXa!vaHuAJs4{sep(=Wy*Qp&f&ZZ8KAdoHzMjOxk(d4nu7@7C diff --git a/test/ui/views/schedule_default_view_test.dart b/test/ui/views/schedule_default_view_test.dart index f077f61b0..d706f3f75 100644 --- a/test/ui/views/schedule_default_view_test.dart +++ b/test/ui/views/schedule_default_view_test.dart @@ -82,8 +82,7 @@ void main() { matchesGoldenFile(goldenFilePath("scheduleDefaultView_1"))); }); - /// TODO: add when https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/pull/343 - /// is merged + /// TODO: add when flutter_calendar_view is at version 1.2.0 // testWidgets("calendar view", (WidgetTester tester) async { // tester.view.physicalSize = const Size(800, 1410); // diff --git a/test/viewmodels/dashboard_viewmodel_test.dart b/test/viewmodels/dashboard_viewmodel_test.dart index fd5886c8f..a5f69dc76 100644 --- a/test/viewmodels/dashboard_viewmodel_test.dart +++ b/test/viewmodels/dashboard_viewmodel_test.dart @@ -11,6 +11,7 @@ import 'package:notredame/features/dashboard/dashboard_viewmodel.dart'; import 'package:notredame/features/dashboard/progress_bar_text_options.dart'; import 'package:notredame/features/more/settings/settings_manager.dart'; import 'package:notredame/utils/activity_code.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../helpers.dart'; import '../mock/managers/course_repository_mock.dart'; import '../mock/managers/settings_manager_mock.dart'; @@ -155,26 +156,23 @@ void main() { // Cards final Map dashboard = { - PreferencesFlag.broadcastCard: 0, - PreferencesFlag.aboutUsCard: 1, - PreferencesFlag.scheduleCard: 2, - PreferencesFlag.progressBarCard: 3, + PreferencesFlag.aboutUsCard: 0, + PreferencesFlag.scheduleCard: 1, + PreferencesFlag.progressBarCard: 2, }; // Reorderered Cards final Map reorderedDashboard = { - PreferencesFlag.broadcastCard: 1, - PreferencesFlag.aboutUsCard: 2, - PreferencesFlag.scheduleCard: 3, + PreferencesFlag.aboutUsCard: 1, + PreferencesFlag.scheduleCard: 2, PreferencesFlag.progressBarCard: 0, }; // Reorderered Cards with hidden scheduleCard final Map hiddenCardDashboard = { - PreferencesFlag.broadcastCard: 0, - PreferencesFlag.aboutUsCard: 1, + PreferencesFlag.aboutUsCard: 0, PreferencesFlag.scheduleCard: -1, - PreferencesFlag.progressBarCard: 2, + PreferencesFlag.progressBarCard: 1, }; // Session @@ -202,6 +200,9 @@ void main() { preferenceServiceMock = setupPreferencesServiceMock(); analyticsServiceMock = setupAnalyticsServiceMock(); preferencesServiceMock = setupPreferencesServiceMock(); + // TODO: Remove when 4.50.1 is released + SharedPreferences.setMockInitialValues({}); + // TODO: End remove when 4.50.1 is released viewModel = DashboardViewModel(intl: await setupAppIntl()); CourseRepositoryMock.stubGetSessions(courseRepositoryMock, @@ -342,7 +343,6 @@ void main() { await viewModel.futureToRun(); expect(viewModel.cards, dashboard); expect(viewModel.cardsToDisplay, [ - PreferencesFlag.broadcastCard, PreferencesFlag.aboutUsCard, PreferencesFlag.scheduleCard, PreferencesFlag.progressBarCard @@ -549,8 +549,6 @@ void main() { CourseRepositoryMock.stubCoursesActivities(courseRepositoryMock); CourseRepositoryMock.stubGetCourses(courseRepositoryMock); - PreferencesServiceMock.stubException( - preferenceServiceMock, PreferencesFlag.broadcastCard); PreferencesServiceMock.stubException( preferenceServiceMock, PreferencesFlag.aboutUsCard); PreferencesServiceMock.stubException( @@ -650,8 +648,6 @@ void main() { group("interact with cards - ", () { test("can hide a card and reset cards to default layout", () async { - SettingsManagerMock.stubSetInt( - settingsManagerMock, PreferencesFlag.broadcastCard); SettingsManagerMock.stubSetInt( settingsManagerMock, PreferencesFlag.aboutUsCard); SettingsManagerMock.stubSetInt( @@ -672,32 +668,26 @@ void main() { settingsManagerMock.setInt(PreferencesFlag.scheduleCard, -1)); expect(viewModel.cards, hiddenCardDashboard); - expect(viewModel.cardsToDisplay, [ - PreferencesFlag.broadcastCard, - PreferencesFlag.aboutUsCard, - PreferencesFlag.progressBarCard - ]); + expect(viewModel.cardsToDisplay, + [PreferencesFlag.aboutUsCard, PreferencesFlag.progressBarCard]); verify(analyticsServiceMock.logEvent( "DashboardViewModel", "Deleting scheduleCard")); verify(settingsManagerMock.setInt(PreferencesFlag.scheduleCard, -1)) .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.broadcastCard, 0)) + verify(settingsManagerMock.setInt(PreferencesFlag.aboutUsCard, 0)) .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.aboutUsCard, 1)) - .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.progressBarCard, 2)) + verify(settingsManagerMock.setInt(PreferencesFlag.progressBarCard, 1)) .called(1); // Call the setter. viewModel.setAllCardsVisible(); await untilCalled( - settingsManagerMock.setInt(PreferencesFlag.progressBarCard, 3)); + settingsManagerMock.setInt(PreferencesFlag.progressBarCard, 2)); expect(viewModel.cards, dashboard); expect(viewModel.cardsToDisplay, [ - PreferencesFlag.broadcastCard, PreferencesFlag.aboutUsCard, PreferencesFlag.scheduleCard, PreferencesFlag.progressBarCard @@ -706,13 +696,11 @@ void main() { verify(analyticsServiceMock.logEvent( "DashboardViewModel", "Restoring cards")); verify(settingsManagerMock.getDashboard()).called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.broadcastCard, 0)) + verify(settingsManagerMock.setInt(PreferencesFlag.aboutUsCard, 0)) .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.aboutUsCard, 1)) - .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.scheduleCard, 2)) + verify(settingsManagerMock.setInt(PreferencesFlag.scheduleCard, 1)) .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.progressBarCard, 3)) + verify(settingsManagerMock.setInt(PreferencesFlag.progressBarCard, 2)) .called(1); verify(settingsManagerMock.getString(PreferencesFlag.progressBarText)) .called(2); @@ -727,9 +715,6 @@ void main() { SettingsManagerMock.stubGetDashboard(settingsManagerMock, toReturn: dashboard); - - SettingsManagerMock.stubSetInt( - settingsManagerMock, PreferencesFlag.broadcastCard); SettingsManagerMock.stubSetInt( settingsManagerMock, PreferencesFlag.aboutUsCard); SettingsManagerMock.stubSetInt( @@ -741,7 +726,6 @@ void main() { expect(viewModel.cards, dashboard); expect(viewModel.cardsToDisplay, [ - PreferencesFlag.broadcastCard, PreferencesFlag.aboutUsCard, PreferencesFlag.scheduleCard, PreferencesFlag.progressBarCard, @@ -756,7 +740,6 @@ void main() { expect(viewModel.cards, reorderedDashboard); expect(viewModel.cardsToDisplay, [ PreferencesFlag.progressBarCard, - PreferencesFlag.broadcastCard, PreferencesFlag.aboutUsCard, PreferencesFlag.scheduleCard ]); @@ -766,11 +749,9 @@ void main() { verify(settingsManagerMock.getDashboard()).called(1); verify(settingsManagerMock.setInt(PreferencesFlag.progressBarCard, 0)) .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.broadcastCard, 1)) - .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.aboutUsCard, 2)) + verify(settingsManagerMock.setInt(PreferencesFlag.aboutUsCard, 1)) .called(1); - verify(settingsManagerMock.setInt(PreferencesFlag.scheduleCard, 3)) + verify(settingsManagerMock.setInt(PreferencesFlag.scheduleCard, 2)) .called(1); verify(settingsManagerMock.getString(PreferencesFlag.progressBarText)) .called(1);