From 1b17fdcdeed83c5d2a6bb9366369256376988308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A6tur=20Magnussen?= <55387402+pmagnu@users.noreply.github.com> Date: Tue, 7 Nov 2023 15:35:30 +0100 Subject: [PATCH 1/4] Removed the take picture with camera functionality (#963) Co-authored-by: Rasmus Nielsen --- ios/Runner/Info.plist | 2 - lib/blocs/new_citizen_bloc.dart | 11 - lib/blocs/take_image_with_camera_bloc.dart | 106 ---------- lib/blocs/toolbar_bloc.dart | 11 - lib/bootstrap.dart | 5 - lib/models/enums/app_bar_icons_enum.dart | 3 - lib/screens/new_citizen_screen.dart | 19 -- lib/screens/pictogram_search_screen.dart | 10 - .../take_picture_with_camera_screen.dart | 188 ------------------ test/screens/new_citizen_screen_test.dart | 2 +- .../screens/pictogram_search_screen_test.dart | 19 -- .../take_picture_with_camera_screen_test.dart | 69 ------- test/widgets/giraf_app_bar_widget_test.dart | 11 - 13 files changed, 1 insertion(+), 455 deletions(-) delete mode 100644 lib/blocs/take_image_with_camera_bloc.dart delete mode 100644 lib/screens/take_picture_with_camera_screen.dart delete mode 100644 test/screens/take_picture_with_camera_screen_test.dart diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index bb3cfbd94..7f05eb730 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -49,8 +49,6 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - NSCameraUsageDescription - Appen kræver adgang til dit kamera for at oprette nye piktogrammer. UIViewControllerBasedStatusBarAppearance CADisableMinimumFrameDurationOnPhone diff --git a/lib/blocs/new_citizen_bloc.dart b/lib/blocs/new_citizen_bloc.dart index 43a5f594b..66a97969c 100644 --- a/lib/blocs/new_citizen_bloc.dart +++ b/lib/blocs/new_citizen_bloc.dart @@ -98,17 +98,6 @@ class NewCitizenBloc extends BlocBase { }); } - /// pushes an imagePicker screen, then sets the pictogram image, - /// to the selected image from the gallery - void takePictureWithCamera() { - ImagePicker().pickImage(source: ImageSource.camera).then((XFile f) { - if (f != null) { - _publishImage(File(f.path)); - _checkInput(); - } - }); - } - /// pushes an imagePicker screen, then sets the profile picture image, /// to the selected image from the gallery void chooseImageFromGallery() { diff --git a/lib/blocs/take_image_with_camera_bloc.dart b/lib/blocs/take_image_with_camera_bloc.dart deleted file mode 100644 index 184ce5d70..000000000 --- a/lib/blocs/take_image_with_camera_bloc.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:api_client/api/api.dart'; -import 'package:api_client/models/enums/access_level_enum.dart'; -import 'package:api_client/models/pictogram_model.dart'; -import 'package:image/image.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:rxdart/rxdart.dart' as rx_dart; -import 'package:weekplanner/blocs/bloc_base.dart'; - -/// Bloc for retrieving an image from a phones gallery, -/// and send it to the pictogram database -class TakePictureWithCameraBloc extends BlocBase { - ///Constructor for the bloc - TakePictureWithCameraBloc(this._api); - - final Api _api; - String _pictogramName; - - /// Publishes the image file, while it is not null - Stream get file => _file.stream.where((File f) => f != null); - - /// Publishes true while waiting for the pictogram to be uploaded - Stream get isUploading => _isUploading.stream; - - /// Publishes the accessLevel for the pictogram - Stream get accessLevel => _accessString.stream; - - /// Publishes if the input fields are filled - Stream get isInputValid => _isInputValid.stream; - - final rx_dart.BehaviorSubject _isInputValid = - rx_dart.BehaviorSubject.seeded(false); - final rx_dart.BehaviorSubject _file = rx_dart.BehaviorSubject(); - final rx_dart.BehaviorSubject _accessString = - rx_dart.BehaviorSubject.seeded('Institution'); - final rx_dart.BehaviorSubject _isUploading = - rx_dart.BehaviorSubject.seeded(false); - - /// pushes an imagePicker screen, then sets the pictogram image, - /// to the selected image from the gallery - void takePictureWithCamera() { - ImagePicker() - .pickImage(source: ImageSource.camera) - .then((XFile f) { - if (f != null) { - _publishImage(File(f.path)); - _checkInput(); - } - }); - } - - /// Checks if the input fields are filled out - void _checkInput() { - if (_file.value != null && - _pictogramName != null && - _pictogramName.isNotEmpty) { - _isInputValid.add(true); - } else { - _isInputValid.add(false); - } - } - - /// sets the pictogram name - void setPictogramName(String newName) { - _pictogramName = newName; - _checkInput(); - } - - void _publishImage(File file) { - _file.add(file); - } - - Uint8List _encodePng(File file) { - return encodePng(copyResize(decodeImage(file.readAsBytesSync()), - width: 512)); // 512 bytes chosen as a reasonable input size. - } - - /// Creates a [PictogramModel] - /// from the selected [Image], [AccessLevel], and title - Stream createPictogram() { - _isUploading.add(true); - return _api.pictogram - .create(PictogramModel( - accessLevel: AccessLevel.PRIVATE, - title: _pictogramName, - )) - .flatMap((PictogramModel pictogram) { - return _api.pictogram.updateImage(pictogram.id, _encodePng(_file.value)); - }).map((PictogramModel pictogram) { - _isUploading.add(false); - return pictogram; - }).doOnError((Object error, StackTrace trace) { - _isUploading.add(false); - }).take(1); - } - - @override - void dispose() { - _file.close(); - _accessString.close(); - _isInputValid.close(); - _isUploading.close(); - } -} diff --git a/lib/blocs/toolbar_bloc.dart b/lib/blocs/toolbar_bloc.dart index d6202b407..e397ab7b9 100644 --- a/lib/blocs/toolbar_bloc.dart +++ b/lib/blocs/toolbar_bloc.dart @@ -63,9 +63,6 @@ class ToolbarBloc extends BlocBase { case AppBarIcon.burgerMenu: _iconsToAdd.add(_createIconBurgermenu(callback)); break; - case AppBarIcon.camera: - _iconsToAdd.add(_createIconCamera(callback)); - break; case AppBarIcon.cancel: _iconsToAdd.add(_createIconCancel(callback)); break; @@ -163,14 +160,6 @@ class ToolbarBloc extends BlocBase { ); } - IconButton _createIconCamera(VoidCallback callback) { - return IconButton( - icon: Image.asset('assets/icons/camera.png'), - tooltip: 'Åbn kamera', - onPressed: callback, - ); - } - IconButton _createIconCancel(VoidCallback callback) { return IconButton( icon: Image.asset('assets/icons/cancel.png'), diff --git a/lib/bootstrap.dart b/lib/bootstrap.dart index d14303c88..3ffb7bdc0 100644 --- a/lib/bootstrap.dart +++ b/lib/bootstrap.dart @@ -13,7 +13,6 @@ import 'package:weekplanner/blocs/new_weekplan_bloc.dart'; import 'package:weekplanner/blocs/pictogram_bloc.dart'; import 'package:weekplanner/blocs/pictogram_image_bloc.dart'; import 'package:weekplanner/blocs/settings_bloc.dart'; -import 'package:weekplanner/blocs/take_image_with_camera_bloc.dart'; import 'package:weekplanner/blocs/timer_bloc.dart'; import 'package:weekplanner/blocs/toolbar_bloc.dart'; import 'package:weekplanner/blocs/upload_from_gallery_bloc.dart'; @@ -110,9 +109,5 @@ class Bootstrap { di.registerDependency(() { return CopyResolveBloc(di.get()); }); - - di.registerDependency(() { - return TakePictureWithCameraBloc(di.get()); - }); } } diff --git a/lib/models/enums/app_bar_icons_enum.dart b/lib/models/enums/app_bar_icons_enum.dart index 6456846bd..4982857f2 100644 --- a/lib/models/enums/app_bar_icons_enum.dart +++ b/lib/models/enums/app_bar_icons_enum.dart @@ -15,9 +15,6 @@ enum AppBarIcon { /// Icon for opening burger menu burgerMenu, - /// Icon for opening camera - camera, - /// Icon for cancelling action cancel, diff --git a/lib/screens/new_citizen_screen.dart b/lib/screens/new_citizen_screen.dart index 5515145f9..523fec486 100644 --- a/lib/screens/new_citizen_screen.dart +++ b/lib/screens/new_citizen_screen.dart @@ -323,25 +323,6 @@ class _NewCitizenScreenState extends State { : widget._displayIfNoImage()), ), ), - Padding( - padding: - const EdgeInsets.symmetric(vertical: 10, horizontal: 16), - - /// Take picture button - child: GirafButton( - key: const Key('TagBillede'), - icon: const ImageIcon(AssetImage('assets/icons/camera.png')), - text: 'Tag billede', - onPressed: widget._bloc.takePictureWithCamera, - child: StreamBuilder( - stream: widget._bloc.file, - builder: (BuildContext context, - AsyncSnapshot snapshot) => - snapshot.data != null - ? widget._displayImage(snapshot.data) - : widget._displayIfNoImage()), - ), - ), ], ), diff --git a/lib/screens/pictogram_search_screen.dart b/lib/screens/pictogram_search_screen.dart index 1e51326b0..319d5d13b 100644 --- a/lib/screens/pictogram_search_screen.dart +++ b/lib/screens/pictogram_search_screen.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:weekplanner/blocs/pictogram_bloc.dart'; import 'package:weekplanner/di.dart'; import 'package:weekplanner/routes.dart'; -import 'package:weekplanner/screens/take_picture_with_camera_screen.dart'; import 'package:weekplanner/screens/upload_image_from_phone_screen.dart'; import 'package:weekplanner/widgets/bottom_app_bar_button_widget.dart'; import 'package:weekplanner/widgets/giraf_app_bar_widget.dart'; @@ -148,15 +147,6 @@ class _PictogramSearchState extends State { context, UploadImageFromPhone()); } ), - BottomAppBarButton( - buttonText: 'Tag billede', - buttonKey: 'TagBilledeButton', - assetPath: 'assets/icons/camera.png', - dialogFunction: (BuildContext context) { - Routes().push( - context, TakePictureWithCamera()); - } - ) ] ))) ] diff --git a/lib/screens/take_picture_with_camera_screen.dart b/lib/screens/take_picture_with_camera_screen.dart deleted file mode 100644 index b98efdcd3..000000000 --- a/lib/screens/take_picture_with_camera_screen.dart +++ /dev/null @@ -1,188 +0,0 @@ -import 'dart:io'; -import 'package:api_client/models/pictogram_model.dart'; -import 'package:flutter/material.dart'; -import 'package:weekplanner/blocs/take_image_with_camera_bloc.dart'; -import 'package:weekplanner/di.dart'; -import 'package:weekplanner/routes.dart'; -import 'package:weekplanner/style/font_size.dart'; -import 'package:weekplanner/widgets/giraf_app_bar_widget.dart'; -import 'package:weekplanner/widgets/giraf_button_widget.dart'; -import 'package:weekplanner/widgets/giraf_notify_dialog.dart'; -import 'package:weekplanner/widgets/loading_spinner_widget.dart'; -import '../style/custom_color.dart' as theme; - -/// Screen for uploading a [PictogramModel] to the server -/// Generic type I used for mocks in testing -// ignore: must_be_immutable -class TakePictureWithCamera extends StatelessWidget { - /// Default constructor - TakePictureWithCamera({Key key}) : super(key: key); - - final TakePictureWithCameraBloc _takePictureWithCamera = - di.get(); - - final BorderRadius _imageBorder = BorderRadius.circular(25); - ///height of screen - dynamic screenHeight; - ///width of screen - dynamic screenWidth; - - @override - Widget build(BuildContext context) { - screenHeight = MediaQuery - .of(context) - .size - .height; - screenWidth = MediaQuery - .of(context) - .size - .width; - return Scaffold( - appBar: GirafAppBar(title: 'Tilføj fra kamera'), - body: StreamBuilder( - stream: _takePictureWithCamera.isUploading, - builder: (BuildContext context, AsyncSnapshot snapshot) { - return snapshot.hasData && snapshot.data - ? const LoadingSpinnerWidget() - : _buildBody(context); - }), - ); - } - - Widget _buildBody(BuildContext context) { - return ListView( - children: [ - _buildDefaultText(), - _buildImageBox(), - _buildInputField(context), - ], - //), - ); - } - - Widget _buildInputField(BuildContext context) { - return Column( - children: [ - Row( - children: [ - Expanded( - child: TextField( - onChanged: _takePictureWithCamera.setPictogramName, - decoration: InputDecoration( - hintText: 'Piktogram navn', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(50))), - ), - ), - ], - ), - Container( - height: 15, - ), - Container( - width: 250, - height: 50, - child: GirafButton( - key: const Key('SavePictogramButtonKey'), - icon: const ImageIcon(AssetImage('assets/icons/save.png')), - text: 'Gem', - onPressed: () { - _takePictureWithCamera.createPictogram().listen((PictogramModel p) - { - Routes().pop(context, p); - }, onError: (Object error) { - _showUploadError(context); - }); - }, - isEnabledStream: _takePictureWithCamera.isInputValid, - ), - ), - ], - ); - } - - Widget _buildImageBox() { - return Padding( - padding: const EdgeInsets.only(bottom: 15), - child: Container( - child: TextButton( - onPressed: _takePictureWithCamera.takePictureWithCamera, - child: StreamBuilder( - stream: _takePictureWithCamera.file, - builder: (BuildContext context, AsyncSnapshot snapshot) => - snapshot.data != null - ? _displayImage(snapshot.data) - : _displayIfNoImage()), - - ), - ) - ); - } - - void _showUploadError(BuildContext context) { - showDialog
( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return const GirafNotifyDialog( - title: 'Fejl', - description: 'Upload af pictogram fejlede.', - ); - }, - ); - } - - Widget _displayIfNoImage() { - return Container( - height: screenHeight / 3, - width: screenWidth * 0.90, - decoration: BoxDecoration( - border: Border.all( - width: 4, - color: theme.GirafColors.black, - ), - color: theme.GirafColors.white70, - borderRadius: _imageBorder), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Image.asset( - 'assets/icons/gallery.png', - color: theme.GirafColors.black, - scale: .75, - ), - const Text( - 'Tryk for at tage billede med kamera', - style: TextStyle(color: theme.GirafColors.black, - fontSize: GirafFont.medium), - ) - ], - ), - ); - } - - Widget _buildDefaultText() { - return const Padding( - padding: EdgeInsets.only( - bottom: 10, - ), - child: Text( - 'Tag billede med kamera', - style: TextStyle(color: theme.GirafColors.black, - fontSize: GirafFont.medium), - textAlign: TextAlign.center, - )); - } - - Widget _displayImage(File image) { - return Container( - height: screenHeight / 2, - width: screenWidth / 2, - child: Image.file(image), - decoration: BoxDecoration( - borderRadius: _imageBorder, - ), - ); - } -} \ No newline at end of file diff --git a/test/screens/new_citizen_screen_test.dart b/test/screens/new_citizen_screen_test.dart index e8d0e5bc9..3ee97134f 100644 --- a/test/screens/new_citizen_screen_test.dart +++ b/test/screens/new_citizen_screen_test.dart @@ -174,7 +174,7 @@ void main() { await gesture.moveBy(const Offset(0, -300)); await tester.pump(); - expect(find.byType(GirafButton, skipOffstage: false), findsNWidgets(4)); + expect(find.byType(GirafButton, skipOffstage: false), findsNWidgets(3)); }); testWidgets('You can input a display name', (WidgetTester tester) async { diff --git a/test/screens/pictogram_search_screen_test.dart b/test/screens/pictogram_search_screen_test.dart index 909dac502..2bf9dbde2 100644 --- a/test/screens/pictogram_search_screen_test.dart +++ b/test/screens/pictogram_search_screen_test.dart @@ -60,25 +60,6 @@ void main() { di.registerDependency(() => NewCitizenBloc(api)); }); - testWidgets('Camera button shows', (WidgetTester tester) async { - - when(pictogramApi.getAll(page: bloc.latestPage, - pageSize: pageSize, query: '')).thenAnswer( - (_) => rx_dart.BehaviorSubject>.seeded( - [pictogramModel])); - - await tester.pumpWidget(MaterialApp( - home: PictogramSearch(user: user), - )); - await tester.pumpAndSettle(); - - expect(find.text('Tag billede'), findsOneWidget); - - await tester.pump(const Duration(milliseconds: 11000)); - - - }); - testWidgets('renders', (WidgetTester tester) async { final Completer done = Completer(); diff --git a/test/screens/take_picture_with_camera_screen_test.dart b/test/screens/take_picture_with_camera_screen_test.dart deleted file mode 100644 index 206ac9393..000000000 --- a/test/screens/take_picture_with_camera_screen_test.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:api_client/api/pictogram_api.dart'; -import 'package:api_client/api/user_api.dart'; -import 'package:api_client/api_client.dart'; -import 'package:api_client/models/enums/role_enum.dart'; -import 'package:api_client/models/giraf_user_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'package:rxdart/rxdart.dart' as rx_dart; -import 'package:weekplanner/blocs/auth_bloc.dart'; -import 'package:weekplanner/blocs/take_image_with_camera_bloc.dart'; -import 'package:weekplanner/blocs/toolbar_bloc.dart'; -import 'package:weekplanner/di.dart'; -import 'package:weekplanner/screens/take_picture_with_camera_screen.dart'; - -class MockPictogramApi extends Mock implements PictogramApi {} - -class MockUserApi extends Mock implements UserApi { - @override - Stream me() { - return Stream.value(GirafUserModel( - id: '1', - department: 3, - role: Role.Guardian, - roleName: 'Guardian', - displayName: 'Kurt', - username: 'SpaceLord69', - )); - } -} - -class MockTakePictureBloc extends TakePictureWithCameraBloc { - MockTakePictureBloc(Api api) : super(api); - - @override - Stream get isInputValid => _isInputValid.stream; - - final rx_dart.BehaviorSubject _isInputValid = - rx_dart.BehaviorSubject.seeded(false); - - void setInputIsValid(bool b) { - _isInputValid.add(b); - } -} - -void main() { - MockTakePictureBloc bloc; - Api api; - - setUp(() { - api = Api('Any'); - api.pictogram = MockPictogramApi(); - api.user = MockUserApi(); - bloc = MockTakePictureBloc(api); - - di.clearAll(); - di.registerDependency(() => bloc); - di.registerDependency(() => ToolbarBloc()); - di.registerDependency(() => api); - di.registerDependency(() => AuthBloc(api)); - }); - - testWidgets('Screen renders', (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp(home: TakePictureWithCamera())); - await tester.pumpAndSettle(); - - expect(find.text('Tag billede med kamera'), findsOneWidget); - }); -} diff --git a/test/widgets/giraf_app_bar_widget_test.dart b/test/widgets/giraf_app_bar_widget_test.dart index 836ea38af..816a505d1 100644 --- a/test/widgets/giraf_app_bar_widget_test.dart +++ b/test/widgets/giraf_app_bar_widget_test.dart @@ -231,17 +231,6 @@ void main() { expect(find.byTooltip('Åbn menu'), findsOneWidget); }); - testWidgets('Camera button is displayed', (WidgetTester tester) async { - final GirafAppBar girafAppBar = GirafAppBar( - title: 'Ugeplan', appBarIcons: const { - AppBarIcon.camera: null}); - - await tester.pumpWidget(makeTestableWidget(child: girafAppBar)); - await tester.pump(); - - expect(find.byTooltip('Åbn kamera'), findsOneWidget); - }); - testWidgets('Cancel button is displayed', (WidgetTester tester) async { final GirafAppBar girafAppBar = GirafAppBar( title: 'Ugeplan', appBarIcons: const { From 70bb64659d019605894c3f7d92c461efe56b4082 Mon Sep 17 00:00:00 2001 From: Thuyhaile <95319419+Thuyhaile@users.noreply.github.com> Date: Wed, 8 Nov 2023 09:55:09 +0100 Subject: [PATCH 2/4] Update show_activity_screen.dart (#961) --- lib/screens/show_activity_screen.dart | 165 +++++++++++++------------- 1 file changed, 84 insertions(+), 81 deletions(-) diff --git a/lib/screens/show_activity_screen.dart b/lib/screens/show_activity_screen.dart index d14673f16..128b9e4a9 100644 --- a/lib/screens/show_activity_screen.dart +++ b/lib/screens/show_activity_screen.dart @@ -710,89 +710,92 @@ class ShowActivityScreen extends StatelessWidget { /// of the button depends on whether it is in guardian or citizen mode. ButtonBar buildButtonBar() { return ButtonBar( - // Key used for testing widget. - key: const Key('ButtonBarRender'), - alignment: MainAxisAlignment.center, - children: [ - StreamBuilder( - stream: _authBloc.mode, - builder: (BuildContext context, - AsyncSnapshot weekplanModeSnapshot) { - return StreamBuilder( - stream: _activityBloc.activityModelStream, - builder: (BuildContext context, - AsyncSnapshot activitySnapshot) { - if (activitySnapshot.data == null) { - return const CircularProgressIndicator(); - } + // Key used for testing widget. + key: const Key('ButtonBarRender'), + alignment: MainAxisAlignment.center, + children: [ + StreamBuilder( + stream: _authBloc.mode, + builder: (BuildContext context, + AsyncSnapshot weekplanModeSnapshot) { + return StreamBuilder( + stream: _activityBloc.activityModelStream, + builder: (BuildContext context, + AsyncSnapshot activitySnapshot) { + if (activitySnapshot.data == null) { + return const CircularProgressIndicator(); + } - final GirafButton completeButton = GirafButton( - key: const Key('CompleteStateToggleButton'), - onPressed: () { - _activityBloc.completeActivity(); - - - }, - isEnabled: activitySnapshot.data.state != - ActivityState.Canceled, - text: activitySnapshot.data.state != - ActivityState.Completed - ? 'Afslut' - : 'Fortryd', - icon: activitySnapshot.data.state != - ActivityState.Completed - ? const ImageIcon( - AssetImage('assets/icons/accept.png'), - color: theme.GirafColors.green) - : const ImageIcon( - AssetImage('assets/icons/undo.png'), - color: theme.GirafColors.blue)); + ActivityState activityState = activitySnapshot.data.state; + final bool isComplete = activityState != ActivityState.Canceled; + final bool isCanceled = + activityState != ActivityState.Completed; + + final bool showCancelButton = + weekplanModeSnapshot.data == WeekplanMode.guardian && + isCanceled; + final bool showCompleteButton = isComplete; + + final GirafButton completeButton = GirafButton( + key: const Key('CompleteStateToggleButton'), + onPressed: showCompleteButton + ? () { + _activityBloc.completeActivity(); + activityState = _activityBloc.getActivity().state; + } + : null, + text: isCanceled ? 'Afslut' : 'Fortryd', + icon: isCanceled + ? const ImageIcon( + AssetImage('assets/icons/accept.png'), + color: theme.GirafColors.green, + ) + : const ImageIcon( + AssetImage('assets/icons/undo.png'), + color: theme.GirafColors.blue, + ), + ); - if (weekplanModeSnapshot.data == WeekplanMode.guardian) { - final GirafButton cancelButton = GirafButton( - key: const Key('CancelStateToggleButton'), - onPressed: () { - _activityBloc.cancelActivity(); - _activity.state = _activityBloc.getActivity().state; - //This removes current context - // so back button correctly navigates - - }, - isEnabled: activitySnapshot.data.state != - ActivityState.Completed, - text: activitySnapshot.data.state != - ActivityState.Canceled - ? 'Aflys' - : 'Fortryd', - icon: activitySnapshot.data.state != - ActivityState.Canceled - ? const ImageIcon( - AssetImage('assets/icons/cancel.png'), - color: theme.GirafColors.red) - : const ImageIcon( - AssetImage('assets/icons/undo.png'), - color: theme.GirafColors.blue), - ); - - if (_activity.isChoiceBoard) { - return Container( - child: Row(children: [cancelButton])); - } else { - return Container( - child: Row(children: [ - Padding( - padding: const EdgeInsets.only(right: 40.0), - child: completeButton), - cancelButton - ])); - } - } else { - return completeButton; - } - }); - }, - ), - ]); + final GirafButton cancelButton = GirafButton( + key: const Key('CancelStateToggleButton'), + onPressed: showCancelButton + ? () { + _activityBloc.cancelActivity(); + activityState = _activityBloc.getActivity().state; + } + : null, + text: isComplete ? 'Aflys' : 'Fortryd', + icon: isComplete + ? const ImageIcon( + AssetImage('assets/icons/cancel.png'), + color: theme.GirafColors.red, + ) + : const ImageIcon( + AssetImage('assets/icons/undo.png'), + color: theme.GirafColors.blue, + ), + ); + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Visibility( + visible: showCompleteButton, + child: completeButton, + ), + const SizedBox(width: 15), + Visibility( + visible: showCancelButton, + child: cancelButton, + ), + ], + ); + }, + ); + }, + ), + ], + ); } /// Builds the input field and buttons for changing the description of From 76bf9ee2ac3c0f3366196d75d5e58cb73be96cb4 Mon Sep 17 00:00:00 2001 From: Thuyhaile <95319419+Thuyhaile@users.noreply.github.com> Date: Wed, 8 Nov 2023 11:39:34 +0100 Subject: [PATCH 3/4] Issue#689 (#969) * Fix issue#689 * Update * update * Update pubspec.yaml * Update weekplan_screen_test.dart --- lib/screens/show_activity_screen.dart | 35 ++++++++++----------- pubspec.yaml | 5 +-- test/screens/show_activity_screen_test.dart | 4 +-- test/screens/weekplan_screen_test.dart | 6 ++-- 4 files changed, 22 insertions(+), 28 deletions(-) diff --git a/lib/screens/show_activity_screen.dart b/lib/screens/show_activity_screen.dart index 128b9e4a9..6ac4b3a22 100644 --- a/lib/screens/show_activity_screen.dart +++ b/lib/screens/show_activity_screen.dart @@ -6,6 +6,7 @@ import 'package:api_client/models/pictogram_model.dart'; import 'package:api_client/models/settings_model.dart'; import 'package:api_client/models/weekday_model.dart'; import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:weekplanner/blocs/activity_bloc.dart'; import 'package:weekplanner/blocs/auth_bloc.dart'; import 'package:weekplanner/blocs/pictogram_image_bloc.dart'; @@ -624,7 +625,8 @@ class ShowActivityScreen extends StatelessWidget { BuildContext overallContext, AsyncSnapshot timerInitSnapshot, AsyncSnapshot modeSnapshot, - AsyncSnapshot settingsSnapshot) { + AsyncSnapshot settingsSnapshot, + ) { return Visibility( visible: modeSnapshot.data == WeekplanMode.guardian || (settingsSnapshot.hasData && !settingsSnapshot.data.lockTimerControl), @@ -632,30 +634,25 @@ class ShowActivityScreen extends StatelessWidget { child: GirafButton( key: const Key('TimerStopButtonKey'), onPressed: () { - showDialog
( - context: overallContext, - barrierDismissible: false, - builder: (BuildContext context) { - //Confirmation dialog for stopping the timer. - return GirafConfirmDialog( - key: const Key('TimerStopConfirmDialogKey'), - title: 'Stop Timer', - description: 'Vil du stoppe timeren?', - confirmButtonText: 'Stop', - confirmButtonIcon: - const ImageIcon(AssetImage('assets/icons/stop.png')), - confirmOnPressed: () { - _timerBloc.stopTimer(); - Routes().pop(context); - }, - ); - }); + // Directly perform actions without showing the confirmation dialog + _timerBloc.stopTimer(); + _showToast('Timeren er blevet stoppet.'); }, icon: const ImageIcon(AssetImage('assets/icons/stop.png')), ), ), ); } + // Give message after stopping timer + void _showToast(String message) { + Fluttertoast.showToast( + msg: message, + gravity: ToastGravity.CENTER, + timeInSecForIosWeb: 1, + backgroundColor: Colors.black, + textColor: Colors.white, + ); + } Widget _deleteButton( BuildContext overallContext, diff --git a/pubspec.yaml b/pubspec.yaml index 5414b72e1..5df776291 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,16 +14,14 @@ dependencies: git: url: https://github.com/aau-giraf/api_client.git ref: develop - - audioplayers: ^1.1.1 auto_size_text: ^3.0.0 csv: ^5.0.1 cupertino_icons: ^1.0.5 data_connection_checker: ^0.3.4 - flutter: sdk: flutter + fluttertoast: ^8.2.2 http: ^0.13.5 image: ^3.2.2 image_picker: ^0.8.6 @@ -43,7 +41,6 @@ dev_dependencies: sdk: flutter mockito: ^5.3.2 - flutter: assets: - assets/ diff --git a/test/screens/show_activity_screen_test.dart b/test/screens/show_activity_screen_test.dart index 3718aef60..29d17f766 100644 --- a/test/screens/show_activity_screen_test.dart +++ b/test/screens/show_activity_screen_test.dart @@ -766,7 +766,7 @@ void main() { await _openTimePickerAndConfirm(tester, 3, 2, 1); await tester.tap(find.byKey(const Key('TimerStopButtonKey'))); await tester.pumpAndSettle(); - expect(find.byKey(const Key('TimerStopConfirmDialogKey')), findsOneWidget); + expect(find.byKey(const Key('TimerStopConfirmDialogKey')), findsNothing); }); testWidgets('Test that timer delete button probs a confirm dialog', @@ -894,7 +894,7 @@ void main() { await _openTimePickerAndConfirm(tester, 1, 1, 1); await tester.tap(find.byKey(const Key('TimerStopButtonKey'))); await tester.pumpAndSettle(); - expect(find.byKey(const Key('TimerStopConfirmDialogKey')), findsOneWidget); + expect(find.byKey(const Key('TimerStopConfirmDialogKey')), findsNothing); }); testWidgets('Only have a play button for timer when lockTimerControl is true', diff --git a/test/screens/weekplan_screen_test.dart b/test/screens/weekplan_screen_test.dart index 3758f783e..5c729fde0 100644 --- a/test/screens/weekplan_screen_test.dart +++ b/test/screens/weekplan_screen_test.dart @@ -1184,7 +1184,7 @@ void main() { mockActivities[2].id.toString()))); await tester.pumpAndSettle(); - expect(find.byKey(const Key('TimerInitKey')), findsOneWidget); + expect(find.byKey(const Key('TimerInitKey')), findsNothing); // ignore: always_specify_types Future.delayed(const Duration(seconds: 2), () async { checkCompleted.complete(); @@ -1232,11 +1232,11 @@ void main() { + mockActivities[2].id.toString()))); await tester.pumpAndSettle(); - expect(find.byKey(const Key('TimerInitKey')), findsOneWidget); + expect(find.byKey(const Key('TimerInitKey')), findsNothing); await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() + mockActivities[2].id.toString()))); - expect(find.byKey(const Key('TimerInitKey')), findsOneWidget); + expect(find.byKey(const Key('TimerInitKey')), findsNothing); // ignore: always_specify_types Future.delayed(const Duration(seconds: 2), () async { checkCompleted.complete(); From b4ae4e6b345b54c758ab180abf936bd8b7cf56a9 Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen <58025878+BicaniWolfie@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:20:39 +0100 Subject: [PATCH 4/4] Issue #931 (#962) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed issue with choice boards Fixed issue with choice boards becoming regular activity cards when a pictogram is selected in the choice board by a citizen * Fixed weekplan_screen_test.dart * Update weekplanner_choiceboard_selector.dart --------- Co-authored-by: Jacob Søndergaard --- .../activity_card.dart | 200 +-- .../weekplan_day_column.dart | 145 +- .../weekplanner_choiceboard_selector.dart | 152 ++- test/screens/weekplan_screen_test.dart | 1162 +++++++++-------- 4 files changed, 850 insertions(+), 809 deletions(-) diff --git a/lib/widgets/weekplan_screen_widgets/activity_card.dart b/lib/widgets/weekplan_screen_widgets/activity_card.dart index fa6f4ec2f..ff9815f2a 100644 --- a/lib/widgets/weekplan_screen_widgets/activity_card.dart +++ b/lib/widgets/weekplan_screen_widgets/activity_card.dart @@ -21,7 +21,7 @@ import '../../style/custom_color.dart' as theme; /// Widget used for activities in the weekplan screen. class ActivityCard extends StatelessWidget { /// Constructor - ActivityCard(this._activity,this._timerBloc, this._user) { + ActivityCard(this._activity, this._timerBloc, this._user) { _settingsBloc.loadSettings(_user); } @@ -129,52 +129,98 @@ class ActivityCard extends StatelessWidget { ), ); } - return Container( - decoration: BoxDecoration( + + if (_activity.chosenActivity != -1 && + weekModeSnapShot.data != WeekplanMode.guardian) { + return Opacity( + opacity: _shouldActivityBeVisible(weekModeSnapShot, settingsSnapShot) + ? 1.0 + : 0, + child: Container( color: theme.GirafColors.white, - border: Border.all( - color: Colors.black, - width: MediaQuery.of(context).size.width * 0.01)), - margin: EdgeInsets.all(MediaQuery.of(context).size.width * 0.02), - child: FittedBox( - child: Column( - children: [ - Stack( + margin: EdgeInsets.all(MediaQuery.of(context).size.width * 0.02), + child: FittedBox( + child: Column( children: [ Stack( - alignment: AlignmentDirectional.topEnd, children: [ - SizedBox( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.width, - child: FittedBox( - child: Stack( - alignment: AlignmentDirectional.center, - children: [ - SizedBox( - key: const Key('WeekPlanScreenChoiceBoard'), - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.width, - child: returnGridView(pictograms)), - ], - )), + Stack( + alignment: AlignmentDirectional.topEnd, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.width, + child: FittedBox( + child: _getPictogram(_activity + .pictograms[_activity.chosenActivity]), + ), + ), + _buildActivityStateIcon(context, _activityState, + weekModeSnapShot, settingsSnapShot), + _buildTimerIcon(context, _activity), + ], + ), + Stack( + alignment: AlignmentDirectional.topStart, + children: [ + _buildAvatarIcon(context), + ], ), - _buildActivityStateIcon(context, _activityState, - weekModeSnapShot, settingsSnapShot), - _buildTimerIcon(context, _activity), ], ), - Stack( - alignment: AlignmentDirectional.topStart, - children: [ - _buildAvatarIcon(context), - ]) + PictogramText(_activity, _user), ], ), - PictogramText(_activity, _user), - ], - ), - )); + )), + ); + } else { + return Container( + decoration: BoxDecoration( + color: theme.GirafColors.white, + border: Border.all( + color: Colors.black, + width: MediaQuery.of(context).size.width * 0.01)), + margin: EdgeInsets.all(MediaQuery.of(context).size.width * 0.02), + child: FittedBox( + child: Column( + children: [ + Stack( + children: [ + Stack( + alignment: AlignmentDirectional.topEnd, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.width, + child: FittedBox( + child: Stack( + alignment: AlignmentDirectional.center, + children: [ + SizedBox( + key: const Key('WeekPlanScreenChoiceBoard'), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.width, + child: returnGridView(pictograms)), + ], + )), + ), + _buildActivityStateIcon(context, _activityState, + weekModeSnapShot, settingsSnapShot), + _buildTimerIcon(context, _activity), + ], + ), + Stack( + alignment: AlignmentDirectional.topStart, + children: [ + _buildAvatarIcon(context), + ]) + ], + ), + PictogramText(_activity, _user), + ], + ), + )); + } } ///Returns the correct gridview @@ -225,8 +271,8 @@ class ActivityCard extends StatelessWidget { AsyncSnapshot settingsSnapShot) { return StreamBuilder( stream: _timerBloc.timerRunningMode, - builder: (BuildContext context, - AsyncSnapshot snapshot1) { + builder: + (BuildContext context, AsyncSnapshot snapshot1) { if (weekModeSnapShot.hasData && settingsSnapShot.hasData) { final WeekplanMode role = weekModeSnapShot.data; final SettingsModel settings = settingsSnapShot.data; @@ -237,25 +283,17 @@ class ActivityCard extends StatelessWidget { snapshot1.data != TimerRunningMode.running) { break; } - return Container(child: TimerPiechart(_timerBloc), - width: MediaQuery - .of(context) - .size - .width, - height: MediaQuery - .of(context) - .size - .height); + return Container( + child: TimerPiechart(_timerBloc), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height); case ActivityState.Completed: if (role == WeekplanMode.guardian) { return Icon( Icons.check, key: const Key('IconComplete'), color: theme.GirafColors.green, - size: MediaQuery - .of(context) - .size - .width, + size: MediaQuery.of(context).size.width, ); } else if (role == WeekplanMode.citizen) { if (settings.completeMark == null) { @@ -267,23 +305,14 @@ class ActivityCard extends StatelessWidget { Icons.check, key: const Key('IconComplete'), color: theme.GirafColors.green, - size: MediaQuery - .of(context) - .size - .width, + size: MediaQuery.of(context).size.width, ); } else if (settings.completeMark == CompleteMark.MovedRight) { return Container( key: const Key('GreyOutBox'), color: theme.GirafColors.transparentGrey, - height: MediaQuery - .of(context) - .size - .width, - width: MediaQuery - .of(context) - .size - .width); + height: MediaQuery.of(context).size.width, + width: MediaQuery.of(context).size.width); } else if (settings.completeMark == CompleteMark.Removed) { //This case should be handled by _shouldActivityBeVisiblei return Container( @@ -293,17 +322,13 @@ class ActivityCard extends StatelessWidget { } } - return const Center(child: CircularProgressIndicator()); case ActivityState.Canceled: return Icon( Icons.clear, key: const Key('IconCanceled'), color: theme.GirafColors.red, - size: MediaQuery - .of(context) - .size - .width, + size: MediaQuery.of(context).size.width, ); break; case ActivityState.Active: @@ -313,10 +338,7 @@ class ActivityCard extends StatelessWidget { Icons.brightness_1_outlined, key: const Key('IconActive'), color: theme.GirafColors.amber, - size: MediaQuery - .of(context) - .size - .width, + size: MediaQuery.of(context).size.width, ); } if (role == WeekplanMode.citizen && @@ -325,10 +347,7 @@ class ActivityCard extends StatelessWidget { Icons.brightness_1_outlined, key: const Key('IconActive'), color: theme.GirafColors.amber, - size: MediaQuery - .of(context) - .size - .width, + size: MediaQuery.of(context).size.width, ); } else { return Container( @@ -337,21 +356,20 @@ class ActivityCard extends StatelessWidget { ); } - break; - default: + break; + default: + return Container( + width: 0, + height: 0, + ); + } + } + //If no settings/role have been loaded then we just make an empty overlay return Container( - width: 0, - height: 0 - , + width: 0, + height: 0, ); - } - } - //If no settings/role have been loaded then we just make an empty overlay - return Container( - width: 0, - height: 0, - ); - }); + }); } Widget _buildTimerIcon(BuildContext context, ActivityModel activity) { diff --git a/lib/widgets/weekplan_screen_widgets/weekplan_day_column.dart b/lib/widgets/weekplan_screen_widgets/weekplan_day_column.dart index 2fafcb5d4..b01b8e47e 100644 --- a/lib/widgets/weekplan_screen_widgets/weekplan_day_column.dart +++ b/lib/widgets/weekplan_screen_widgets/weekplan_day_column.dart @@ -29,12 +29,11 @@ import 'activity_card.dart'; /// Widget used to create a single column in the weekplan screen. class WeekplanDayColumn extends StatelessWidget { /// Constructor - WeekplanDayColumn({ - @required this.color, - @required this.user, - @required this.weekplanBloc, - @required this.streamIndex - }) { + WeekplanDayColumn( + {@required this.color, + @required this.user, + @required this.weekplanBloc, + @required this.streamIndex}) { _settingsBloc.loadSettings(user); } @@ -51,21 +50,18 @@ class WeekplanDayColumn extends StatelessWidget { /// Index of the weekday in the weekdayStreams list final int streamIndex; - final AuthBloc _authBloc = di.get(); final SettingsBloc _settingsBloc = di.get(); final ActivityBloc _activityBloc = di.get(); final List _timerBloc = []; + /// Method used to create TimerBlocs. void createTimerBlocs(int numOfTimeBlocs) { - for (int i = 0; i <= numOfTimeBlocs- _timerBloc.length; i++) { + for (int i = 0; i <= numOfTimeBlocs - _timerBloc.length; i++) { _timerBloc.add(di.get()); } } - - - @override Widget build(BuildContext context) { return StreamBuilder( @@ -137,9 +133,8 @@ class WeekplanDayColumn extends StatelessWidget { fontWeight: FontWeight.bold, fontSize: isToday(day) ? 40 : 30, foreground: Paint() - ..style = isToday(day) - ? PaintingStyle.stroke - : PaintingStyle.fill + ..style = + isToday(day) ? PaintingStyle.stroke : PaintingStyle.fill ..strokeWidth = 5 ..color = Colors.black, ), @@ -228,8 +223,8 @@ class WeekplanDayColumn extends StatelessWidget { /// Returns true if the field dayOfTheWeek matches with today's date /// This function is mainly used for highlighting today's date on the weekplan - bool isToday(Weekday weekday){ - return DateTime.now().weekday.toInt()-1 == weekday.index; + bool isToday(Weekday weekday) { + return DateTime.now().weekday.toInt() - 1 == weekday.index; } /// Unmarks all activities for a given day @@ -242,10 +237,10 @@ class WeekplanDayColumn extends StatelessWidget { } /// Marks the first Normal activity to Active - void markCurrent(WeekdayModel weekdayModel){ - if(isToday(weekdayModel.day)){ - for (ActivityModel activity in weekdayModel.activities){ - if(activity.state == ActivityState.Normal){ + void markCurrent(WeekdayModel weekdayModel) { + if (isToday(weekdayModel.day)) { + for (ActivityModel activity in weekdayModel.activities) { + if (activity.state == ActivityState.Normal) { activity.state = ActivityState.Active; break; } @@ -254,17 +249,16 @@ class WeekplanDayColumn extends StatelessWidget { } /// Sets all activites to Normal state - void resetActiveMarks(WeekdayModel weekdayModel){ - for (ActivityModel activity in weekdayModel.activities){ - if(activity.state == ActivityState.Active){ + void resetActiveMarks(WeekdayModel weekdayModel) { + for (ActivityModel activity in weekdayModel.activities) { + if (activity.state == ActivityState.Active) { activity.state = ActivityState.Normal; } } } /// Builds a day's activities - StreamBuilder> _buildDayActivities( WeekdayModel weekday){ - + StreamBuilder> _buildDayActivities(WeekdayModel weekday) { return StreamBuilder>( stream: weekplanBloc.markedActivities, builder: (BuildContext context, @@ -274,11 +268,10 @@ class WeekplanDayColumn extends StatelessWidget { stream: weekplanBloc.editMode, builder: (BuildContext context, AsyncSnapshot editModeSnapshot) { - return StreamBuilder( - stream: _settingsBloc.settings, - builder: (BuildContext context, - AsyncSnapshot settingsSnapshot) - { + return StreamBuilder( + stream: _settingsBloc.settings, + builder: (BuildContext context, + AsyncSnapshot settingsSnapshot) { return Expanded( child: ListView.builder( itemBuilder: (BuildContext context, int index) { @@ -286,8 +279,8 @@ class WeekplanDayColumn extends StatelessWidget { markCurrent(weekday); if (index >= weekday.activities.length) { return StreamBuilder( - stream: weekplanBloc - .activityPlaceholderVisible, + stream: + weekplanBloc.activityPlaceholderVisible, initialData: false, builder: (BuildContext context, AsyncSnapshot snapshot) { @@ -298,8 +291,7 @@ class WeekplanDayColumn extends StatelessWidget { index, weekday), ); }); - } - else { + } else { return StreamBuilder( stream: _authBloc.mode, initialData: WeekplanMode.guardian, @@ -308,13 +300,14 @@ class WeekplanDayColumn extends StatelessWidget { if (snapshot.data == WeekplanMode.guardian) { return _dragTargetPictogram( - index, weekday, - editModeSnapshot.data, context); + index, + weekday, + editModeSnapshot.data, + context); } return _pictogramIconStack(context, index, weekday, editModeSnapshot.data); - } - ); + }); } }, itemCount: weekday.activities.length + 1, @@ -354,7 +347,6 @@ class WeekplanDayColumn extends StatelessWidget { // Returns the draggable pictograms, which also function as drop targets. DragTarget> _dragTargetPictogram( int index, WeekdayModel weekday, bool inEditMode, BuildContext context) { - return DragTarget>( key: const Key('DragTarget'), builder: (BuildContext context, @@ -388,9 +380,9 @@ class WeekplanDayColumn extends StatelessWidget { return true; }, onAccept: (Tuple2 data) { - weekplanBloc.reorderActivities( - data.item1, data.item2, weekday.day, index) - .catchError((Object error){ + weekplanBloc + .reorderActivities(data.item1, data.item2, weekday.day, index) + .catchError((Object error) { creatingNotifyDialog(error, context); }); }, @@ -402,7 +394,6 @@ class WeekplanDayColumn extends StatelessWidget { BuildContext context, int index, WeekdayModel weekday, bool inEditMode) { final ActivityModel currActivity = weekday.activities[index]; - final bool isMarked = weekplanBloc.isActivityMarked(currActivity); return FittedBox( @@ -427,10 +418,10 @@ class WeekplanDayColumn extends StatelessWidget { key: Key(weekday.day.index.toString() + currActivity.id.toString()), onTap: () { - if (modeSnapshot.data == WeekplanMode.guardian - || - modeSnapshot.data == WeekplanMode.trustee) - { + if (modeSnapshot.data == + WeekplanMode.guardian || + modeSnapshot.data == + WeekplanMode.trustee) { _handleOnTapActivity( inEditMode, isMarked, @@ -469,25 +460,23 @@ class WeekplanDayColumn extends StatelessWidget { ), ); } + void _handleActivity( - List activities, - int index, - WeekdayModel weekday) { + List activities, int index, WeekdayModel weekday) { final ActivityModel activistModel = activities[index]; - if(activistModel.state == ActivityState.Completed || - (activistModel.timer != null && - activistModel.timer.paused == false)) { - return; + if (activistModel.state == ActivityState.Completed || + (activistModel.timer != null && activistModel.timer.paused == false)) { + return; } _activityBloc.load(activistModel, user); _activityBloc.accesWeekPlanBloc(weekplanBloc, weekday); - _timerBloc[index].load(activistModel,user: user); + _timerBloc[index].load(activistModel, user: user); _timerBloc[index].setActivityBloc(_activityBloc); _activityBloc.addHandlerToActivityStateOnce(); _timerBloc[index].addHandlerToRunningModeOnce(); _timerBloc[index].initTimer(); - if (activistModel.timer == null) { + if (activistModel.timer == null || activistModel.chosenActivity != null) { _activityBloc.completeActivity(); } else { _timerBloc[index].playTimer(); @@ -521,17 +510,16 @@ class WeekplanDayColumn extends StatelessWidget { activities[index], _activityBloc, user); }); } else if (isCitizen) { - _handleActivity(activities,index,weekday); - } - else if(!inEditMode){ - - Routes().push(context, ShowActivityScreen(activities[index], - user, weekplanBloc,_timerBloc[index], weekday)) - - - .whenComplete(() {weekplanBloc.getWeekday(weekday.day) - .catchError((Object error) { - creatingNotifyDialog(error, context); + _handleActivity(activities, index, weekday); + } else if (!inEditMode) { + Routes() + .push( + context, + ShowActivityScreen(activities[index], user, weekplanBloc, + _timerBloc[index], weekday)) + .whenComplete(() { + weekplanBloc.getWeekday(weekday.day).catchError((Object error) { + creatingNotifyDialog(error, context); }); }); } @@ -540,10 +528,8 @@ class WeekplanDayColumn extends StatelessWidget { /// Builds activity card with a status icon if it is marked StatelessWidget _buildIsMarked(bool isMarked, BuildContext context, WeekdayModel weekday, List activities, int index) { - if(index >= activities.length){ - return Container( - child: const CircularProgressIndicator() - ); + if (index >= activities.length) { + return Container(child: const CircularProgressIndicator()); } if (isMarked) { return Container( @@ -564,7 +550,8 @@ class WeekplanDayColumn extends StatelessWidget { backgroundColor: theme.GirafColors.buttonColor, ); - Container _buildAddActivityButton(WeekdayModel weekday, BuildContext context){ + Container _buildAddActivityButton( + WeekdayModel weekday, BuildContext context) { return Container( padding: EdgeInsets.symmetric( horizontal: @@ -581,11 +568,16 @@ class WeekplanDayColumn extends StatelessWidget { return Visibility( visible: snapshot.data == WeekplanMode.guardian, child: ElevatedButton( - style: addActivityStyle, + style: addActivityStyle, key: const Key('AddActivityButton'), child: Image.asset('assets/icons/add.png'), onPressed: () async { - Routes().push(context, PictogramSearch(user: user,)) + Routes() + .push( + context, + PictogramSearch( + user: user, + )) .then((Object object) { if (object is PictogramModel) { final PictogramModel newPictogram = object; @@ -615,12 +607,11 @@ class WeekplanDayColumn extends StatelessWidget { /// Show the new NotifyDialog String message = ''; Key key; - if(error is ApiException){ + if (error is ApiException) { message = error.errorMessage; // ignore: avoid_as key = error.errorKey as Key; - } - else{ + } else { message = error.toString(); key = const Key('UnknownError'); } diff --git a/lib/widgets/weekplanner_choiceboard_selector.dart b/lib/widgets/weekplanner_choiceboard_selector.dart index 165bb4b2c..18927d576 100644 --- a/lib/widgets/weekplanner_choiceboard_selector.dart +++ b/lib/widgets/weekplanner_choiceboard_selector.dart @@ -17,8 +17,8 @@ import 'giraf_confirm_dialog.dart'; ///This is a class class WeekplannerChoiceboardSelector extends StatelessWidget { ///Constructor - WeekplannerChoiceboardSelector(this._activity, this._activityBloc, - this._user) { + WeekplannerChoiceboardSelector( + this._activity, this._activityBloc, this._user) { _activityBloc.load(_activity, _user); _settingsBloc.loadSettings(_user); } @@ -117,79 +117,89 @@ class WeekplannerChoiceboardSelector extends StatelessWidget { Widget _displayPictogram( BuildContext context, List pictograms, int index) { - return StreamBuilder( - stream: _settingsBloc.settings, - builder: (BuildContext context, - AsyncSnapshot settingSnapshot) { - return SizedBox( - height: MediaQuery.of(context).size.height * 0.2, - width: MediaQuery.of(context).size.height * 0.2, - child: FittedBox( - child: GestureDetector( - onTap: () { - if(settingSnapshot.data.showPopup) { - _selectPictogramFromChoiceBoardPopup(context, - pictograms, index) - .then((_) { - Routes().pop(context); - }); - } - else{ - _selectPictogramFromChoiceboard(context, index); - } - }, - child: Container( - constraints: const BoxConstraints( - maxWidth: double.infinity, - maxHeight: double.infinity, - ), - decoration: BoxDecoration( - border: Border.all( - color: theme.GirafColors.blueBorderColor, width: 1)), - child: pictograms[index], - )), - ), - ); - } - ); + return StreamBuilder( + stream: _settingsBloc.settings, + builder: (BuildContext context, + AsyncSnapshot settingSnapshot) { + return SizedBox( + height: MediaQuery.of(context).size.height * 0.2, + width: MediaQuery.of(context).size.height * 0.2, + child: FittedBox( + child: GestureDetector( + onTap: () { + if (settingSnapshot.data.showPopup) { + _selectPictogramFromChoiceBoardPopup( + context, pictograms, index) + .then((_) { + Routes().pop(context); + }); + } else { + _selectPictogramFromChoiceboard(context, index); + } + }, + child: Container( + constraints: const BoxConstraints( + maxWidth: double.infinity, + maxHeight: double.infinity, + ), + decoration: BoxDecoration( + border: Border.all( + color: theme.GirafColors.blueBorderColor, + width: 1)), + child: pictograms[index], + )), + ), + ); + }); } //Shows a popup when selecting a pictogram on a choiceboard Future
_selectPictogramFromChoiceBoardPopup( BuildContext context, List pictograms, int index) { - return showDialog
( - barrierDismissible: false, - context: context, - builder: (BuildContext context) { - return GirafConfirmDialog( - key: const Key('PictogramSelectorConfirmDialog'), - title: 'Vælg aktivitet', - description: 'Vil du vælge aktiviteten ' + - _activity.pictograms[index].title, - confirmButtonText: 'Ja', - confirmButtonIcon: - const ImageIcon(AssetImage('assets/icons/accept.png')), - confirmOnPressed: () { - _selectPictogramFromChoiceboard(context, index); - }, - cancelOnPressed: () {}); - }); - } + return showDialog
( + barrierDismissible: false, + context: context, + builder: (BuildContext context) { + return GirafConfirmDialog( + key: const Key('PictogramSelectorConfirmDialog'), + title: 'Vælg aktivitet', + description: 'Vil du vælge aktiviteten ' + + _activity.pictograms[index].title, + confirmButtonText: 'Ja', + confirmButtonIcon: + const ImageIcon(AssetImage('assets/icons/accept.png')), + confirmOnPressed: () { + _selectPictogramFromChoiceboard(context, index); + }, + cancelOnPressed: () {}); + }); + } - //Changes activity type so it is not a choiceboard, and only keeps the - //selected pictogram in the activity - void _selectPictogramFromChoiceboard(BuildContext context, int index){ - _activity.isChoiceBoard = false; - final List _pictogramModels = < - PictogramModel>[ - _activity.pictograms[index] - ]; - _activity.pictograms = _pictogramModels; - - _activityBloc.update(); - _activityBloc.activityModelStream.skip(1).take(1).listen((_) { - Routes().pop(context); - }); - //Closes the dialog box - } + //Changes activity type so it is not a choiceboard, and only keeps the + //selected pictogram in the activity + void _selectPictogramFromChoiceboard(BuildContext context, int index) { + // if (!_activity.pictograms + // .any((PictogramModel element) => element.isCompleted == false)) { + // _activity.state = ActivityState.Completed; + // } + // if (_activity.pictograms.length == 1) { + // _activity.isChoiceBoard = false; + // } else { + // _activity.pictograms.removeAt(index); + // } + + // final List _pictogramModels = [ + // _activity.pictograms[index] + // ]; + // _activity.pictograms = _pictogramModels; + _activity.chosenActivity = index; + _activityBloc.load(_activity, _user); + _activityBloc.completeActivity(); + + _activityBloc.update(); + _activityBloc.activityModelStream.skip(1).take(1).listen((_) { + Routes().pop(context); + }); + //Closes the dialog box + } } diff --git a/test/screens/weekplan_screen_test.dart b/test/screens/weekplan_screen_test.dart index 5c729fde0..0b52d85a2 100644 --- a/test/screens/weekplan_screen_test.dart +++ b/test/screens/weekplan_screen_test.dart @@ -73,7 +73,7 @@ void main() { mockPictograms = mockData.mockPictograms; user = mockData.mockUser; api = mockData.mockApi; - api.pictogram=MockPictogramApi(); + api.pictogram = MockPictogramApi(); authBloc = AuthBloc(api); authBloc.setMode(WeekplanMode.guardian); weekplanBloc = WeekplanBloc(api); @@ -111,23 +111,21 @@ void main() { }); testWidgets('Activity selector pops up when choiceBoard activity is tapped', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.citizen); - mockActivities[0].state = ActivityState.Normal; - mockActivities[0].isChoiceBoard = true; - mockActivities[0].pictograms = mockPictograms; - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - await tester.tap(find.byKey(const Key('WeekPlanScreenChoiceBoard'))); - await tester.pumpAndSettle(); - - expect( - find.byKey(const Key('ChoiceBoardActivitySelector')), - findsOneWidget); - }); + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + mockActivities[0].state = ActivityState.Normal; + mockActivities[0].isChoiceBoard = true; + mockActivities[0].pictograms = mockPictograms; + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + await tester.tap(find.byKey(const Key('WeekPlanScreenChoiceBoard'))); + await tester.pumpAndSettle(); + + expect( + find.byKey(const Key('ChoiceBoardActivitySelector')), findsOneWidget); + }); testWidgets('Has Giraf App Bar', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); @@ -142,328 +140,315 @@ void main() { }); testWidgets('Click on edit icon toggles edit mode', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - bool currentEditMode = false; - weekplanBloc.editMode.listen((bool editMode) { - currentEditMode = editMode; - }); - // Initial edit mode should be false - expect(currentEditMode, false); - - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); - - weekplanBloc.editMode.listen((bool editMode) { - currentEditMode = editMode; - }); - // After tapping the button edit mode should be true - expect(currentEditMode, true); - - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); - weekplanBloc.editMode.listen((bool editMode) { - currentEditMode = editMode; - }); - // After tapping the button agian it should be false - expect(currentEditMode, false); - }); + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + bool currentEditMode = false; + weekplanBloc.editMode.listen((bool editMode) { + currentEditMode = editMode; + }); + // Initial edit mode should be false + expect(currentEditMode, false); + + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); + + weekplanBloc.editMode.listen((bool editMode) { + currentEditMode = editMode; + }); + // After tapping the button edit mode should be true + expect(currentEditMode, true); + + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); + weekplanBloc.editMode.listen((bool editMode) { + currentEditMode = editMode; + }); + // After tapping the button agian it should be false + expect(currentEditMode, false); + }); testWidgets('No activity cards when no activities are added', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - // After tapping the button edit mode should be true - expect(find.byType(ActivityCard), findsNothing); - }); + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + // After tapping the button edit mode should be true + expect(find.byType(ActivityCard), findsNothing); + }); testWidgets('Each added activity gets an activity card', - (WidgetTester tester) async { - // We add an activity to monday and one to tuesday - mockWeek.days[0].activities.add(mockActivities[0]); - mockWeek.days[1].activities.add(mockActivities[1]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // After tapping the button edit mode should be true - expect(find.byType(ActivityCard), findsNWidgets(2)); - }); + (WidgetTester tester) async { + // We add an activity to monday and one to tuesday + mockWeek.days[0].activities.add(mockActivities[0]); + mockWeek.days[1].activities.add(mockActivities[1]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // After tapping the button edit mode should be true + expect(find.byType(ActivityCard), findsNWidgets(2)); + }); testWidgets('Tapping activity when not in edit mode pushes activity screen', - (WidgetTester tester) async { - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - await tester.tap(find.byType(ActivityCard)); - await tester.pumpAndSettle(); - expect(find.byType(ShowActivityScreen), findsOneWidget); - }); + (WidgetTester tester) async { + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + await tester.tap(find.byType(ActivityCard)); + await tester.pumpAndSettle(); + expect(find.byType(ShowActivityScreen), findsOneWidget); + }); testWidgets('Tapping activity in edit mode selects/deselects it', - (WidgetTester tester) async { - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + (WidgetTester tester) async { + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - //We enter edit mode. - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); + //We enter edit mode. + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); - expect(weekplanBloc.getNumberOfMarkedActivities(), 0); + expect(weekplanBloc.getNumberOfMarkedActivities(), 0); - await tester.tap(find.byType(ActivityCard)); - await tester.pumpAndSettle(); - expect(weekplanBloc.getNumberOfMarkedActivities(), 1); + await tester.tap(find.byType(ActivityCard)); + await tester.pumpAndSettle(); + expect(weekplanBloc.getNumberOfMarkedActivities(), 1); - await tester.tap(find.byType(ActivityCard)); - await tester.pumpAndSettle(); - expect(weekplanBloc.getNumberOfMarkedActivities(), 0); - }); + await tester.tap(find.byType(ActivityCard)); + await tester.pumpAndSettle(); + expect(weekplanBloc.getNumberOfMarkedActivities(), 0); + }); testWidgets('Marking activity in edit mode renders a black box around it', - (WidgetTester tester) async { - mockWeek.days[0].activities.add(mockActivities[0]); + (WidgetTester tester) async { + mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - await tester.tap(find.byTooltip('Rediger')); - await tester.pumpAndSettle(); + await tester.tap(find.byTooltip('Rediger')); + await tester.pumpAndSettle(); - await tester.tap(find.byType(ActivityCard)); - await tester.pumpAndSettle(); + await tester.tap(find.byType(ActivityCard)); + await tester.pumpAndSettle(); - expect(find.byKey(const Key('isSelectedKey')), findsOneWidget); - }); + expect(find.byKey(const Key('isSelectedKey')), findsOneWidget); + }); testWidgets( 'Cancel/Copy/Delete/Undo buttons not built when edit mode is false', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Aflys' && - widget.buttonKey == 'CancelActivtiesButton'), - findsNothing); + widget.buttonText == 'Aflys' && + widget.buttonKey == 'CancelActivtiesButton'), + findsNothing); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Kopier' && - widget.buttonKey == 'CopyActivtiesButton'), - findsNothing); + widget.buttonText == 'Kopier' && + widget.buttonKey == 'CopyActivtiesButton'), + findsNothing); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Slet' && - widget.buttonKey == 'DeleteActivtiesButton'), - findsNothing); + widget.buttonText == 'Slet' && + widget.buttonKey == 'DeleteActivtiesButton'), + findsNothing); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Genoptag' && - widget.buttonKey == 'GenoptagActivtiesButton'), - findsNothing); - }); + widget.buttonText == 'Genoptag' && + widget.buttonKey == 'GenoptagActivtiesButton'), + findsNothing); + }); testWidgets( 'Cancel/Copy/Delete/Undo buttons are built when edit mode is true', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - // Toggle edit mode by pressing the edit mode button - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); + // Toggle edit mode by pressing the edit mode button + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Aflys' && - widget.buttonKey == 'CancelActivtiesButton'), - findsOneWidget); + widget.buttonText == 'Aflys' && + widget.buttonKey == 'CancelActivtiesButton'), + findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Kopier' && - widget.buttonKey == 'CopyActivtiesButton'), - findsOneWidget); + widget.buttonText == 'Kopier' && + widget.buttonKey == 'CopyActivtiesButton'), + findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Slet' && - widget.buttonKey == 'DeleteActivtiesButton'), - findsOneWidget); + widget.buttonText == 'Slet' && + widget.buttonKey == 'DeleteActivtiesButton'), + findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Genoptag' && - widget.buttonKey == 'GenoptagActivtiesButton'), - findsOneWidget); - }); + widget.buttonText == 'Genoptag' && + widget.buttonKey == 'GenoptagActivtiesButton'), + findsOneWidget); + }); testWidgets( 'Cancel/Copy/Delete/Undo buttons do not open dialog when no activites are selected', - (WidgetTester tester) async { - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); - await tester.tap(find.byWidgetPredicate((Widget widget) => + await tester.tap(find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Aflys' && - widget.buttonKey == 'CancelActivtiesButton')); - await tester.pumpAndSettle(); + widget.buttonText == 'Aflys' && + widget.buttonKey == 'CancelActivtiesButton')); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is GirafConfirmDialog && - widget.title == 'Aflys aktiviteter'), - findsNothing); + widget.title == 'Aflys aktiviteter'), + findsNothing); - await tester.tap(find.byWidgetPredicate((Widget widget) => + await tester.tap(find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Kopier' && - widget.buttonKey == 'CopyActivtiesButton')); - await tester.pumpAndSettle(); + widget.buttonText == 'Kopier' && + widget.buttonKey == 'CopyActivtiesButton')); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is GirafCopyActivitiesDialog && - widget.title == 'Kopier aktiviteter'), - findsNothing); + widget.title == 'Kopier aktiviteter'), + findsNothing); - await tester.tap(find.byWidgetPredicate((Widget widget) => + await tester.tap(find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Slet' && - widget.buttonKey == 'DeleteActivtiesButton')); - await tester.pumpAndSettle(); + widget.buttonText == 'Slet' && + widget.buttonKey == 'DeleteActivtiesButton')); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is GirafConfirmDialog && widget.title == 'Slet aktiviteter'), - findsNothing); + findsNothing); - await tester.tap(find.byWidgetPredicate((Widget widget) => + await tester.tap(find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Genoptag' && - widget.buttonKey == 'GenoptagActivtiesButton')); - await tester.pumpAndSettle(); + widget.buttonText == 'Genoptag' && + widget.buttonKey == 'GenoptagActivtiesButton')); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is GirafConfirmDialog && widget.title == 'Genoptag'), - findsNothing - ); - }); + findsNothing); + }); testWidgets('Cancel activity button opens dialog when activity is selected', - (WidgetTester tester) async { - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Toggle edit mode by pressing the edit mode button - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); - - // Selecting an activity - await tester.tap(find.byType(ActivityCard)); - await tester.pumpAndSettle(); - - // Tapping cancel activities button - await tester.tap(find.byWidgetPredicate((Widget widget) => + (WidgetTester tester) async { + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Toggle edit mode by pressing the edit mode button + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); + + // Selecting an activity + await tester.tap(find.byType(ActivityCard)); + await tester.pumpAndSettle(); + + // Tapping cancel activities button + await tester.tap(find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Aflys' && - widget.buttonKey == 'CancelActivtiesButton')); - await tester.pumpAndSettle(); + widget.buttonText == 'Aflys' && + widget.buttonKey == 'CancelActivtiesButton')); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is GirafConfirmDialog && - widget.title == 'Aflys aktiviteter'), - findsOneWidget); - }); + widget.title == 'Aflys aktiviteter'), + findsOneWidget); + }); testWidgets('Copy activity button opens dialog when activity is selected', - (WidgetTester tester) async { - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Toggle edit mode by pressing the edit mode button - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); - - // Selecting an activity - await tester.tap(find.byType(ActivityCard)); - await tester.pumpAndSettle(); - - // Tapping copy activities button - await tester.tap(find.byWidgetPredicate((Widget widget) => + (WidgetTester tester) async { + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Toggle edit mode by pressing the edit mode button + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); + + // Selecting an activity + await tester.tap(find.byType(ActivityCard)); + await tester.pumpAndSettle(); + + // Tapping copy activities button + await tester.tap(find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Kopier' && - widget.buttonKey == 'CopyActivtiesButton')); - await tester.pumpAndSettle(); + widget.buttonText == 'Kopier' && + widget.buttonKey == 'CopyActivtiesButton')); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is GirafCopyActivitiesDialog && - widget.title == 'Kopier aktiviteter'), - findsOneWidget); - }); + widget.title == 'Kopier aktiviteter'), + findsOneWidget); + }); testWidgets('Delete activity button opens dialog when activity is selected', - (WidgetTester tester) async { - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Toggle edit mode by pressing the edit mode button - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); - - // Selecting an activity - await tester.tap(find.byType(ActivityCard)); - await tester.pumpAndSettle(); - - // Tapping copy activities button - await tester.tap(find.byWidgetPredicate((Widget widget) => + (WidgetTester tester) async { + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Toggle edit mode by pressing the edit mode button + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); + + // Selecting an activity + await tester.tap(find.byType(ActivityCard)); + await tester.pumpAndSettle(); + + // Tapping copy activities button + await tester.tap(find.byWidgetPredicate((Widget widget) => widget is BottomAppBarButton && - widget.buttonText == 'Slet' && - widget.buttonKey == 'DeleteActivtiesButton')); - await tester.pumpAndSettle(); + widget.buttonText == 'Slet' && + widget.buttonKey == 'DeleteActivtiesButton')); + await tester.pumpAndSettle(); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is GirafConfirmDialog && widget.title == 'Slet aktiviteter'), - findsOneWidget); - }); + findsOneWidget); + }); testWidgets('Canceling an activity works', (WidgetTester tester) async { mockWeek.days[0].activities.add(mockActivities[0]); @@ -477,7 +462,7 @@ void main() { await tester.pumpAndSettle(); await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is BottomAppBarButton && + widget is BottomAppBarButton && widget is BottomAppBarButton && widget.buttonText == 'Aflys' && widget.buttonKey == 'CancelActivtiesButton')); @@ -492,9 +477,9 @@ void main() { }); testWidgets('Marking an activity as current and updating work', - (WidgetTester tester) async { + (WidgetTester tester) async { mockSettings.nrOfDaysToDisplayLandscape = 1; - final int weekDay = DateTime.now().weekday.toInt()-1; + final int weekDay = DateTime.now().weekday.toInt() - 1; mockWeek.days[weekDay].activities.add(mockActivities[0]); mockWeek.days[weekDay].activities.add(mockActivities[1]); await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); @@ -509,7 +494,7 @@ void main() { await tester.pumpAndSettle(); await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is BottomAppBarButton && + widget is BottomAppBarButton && widget is BottomAppBarButton && widget.buttonText == 'Aflys' && widget.buttonKey == 'CancelActivtiesButton')); @@ -531,7 +516,7 @@ void main() { await tester.pumpAndSettle(); await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is BottomAppBarButton && + widget is BottomAppBarButton && widget is BottomAppBarButton && widget.buttonText == 'Genoptag' && widget.buttonKey == 'GenoptagActivtiesButton')); @@ -562,7 +547,7 @@ void main() { await tester.pumpAndSettle(); await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is BottomAppBarButton && + widget is BottomAppBarButton && widget is BottomAppBarButton && widget.buttonText == 'Genoptag' && widget.buttonKey == 'GenoptagActivtiesButton')); @@ -576,7 +561,6 @@ void main() { }); testWidgets('Copying an activity works', (WidgetTester tester) async { - mockWeek.days[0].activities.add(mockActivities[0]); await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); await tester.pumpAndSettle(); @@ -594,7 +578,7 @@ void main() { // Tapping copy activities button await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is BottomAppBarButton && + widget is BottomAppBarButton && widget.buttonText == 'Kopier' && widget.buttonKey == 'CopyActivtiesButton')); await tester.pumpAndSettle(); @@ -626,7 +610,7 @@ void main() { // Tapping copy activities button await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is BottomAppBarButton && + widget is BottomAppBarButton && widget.buttonText == 'Slet' && widget.buttonKey == 'DeleteActivtiesButton')); await tester.pumpAndSettle(); @@ -660,60 +644,59 @@ void main() { }); testWidgets('Marks all and unmarks all activities for a given day', - (WidgetTester tester) async { - // Adding two activities too monday - mockWeek.days[0].activities.add(mockActivities[0]); - mockWeek.days[0].activities.add(mockActivities[1]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - await tester.tap(find.byTooltip('Rediger')); - await tester.pump(); - expect(weekplanBloc.getNumberOfMarkedActivities(), 0); - - // Checking that the select all activities button works - await tester.tap(find.byKey(const Key('SelectAllButton')).first); - await tester.pump(); - expect(weekplanBloc.getNumberOfMarkedActivities(), 2); - - // Checking that the Deselect all activities button works - await tester.tap(find.byKey(const Key('DeselectAllButton')).first); - await tester.pump(); - expect(weekplanBloc.getNumberOfMarkedActivities(), 0); - }); + (WidgetTester tester) async { + // Adding two activities too monday + mockWeek.days[0].activities.add(mockActivities[0]); + mockWeek.days[0].activities.add(mockActivities[1]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + await tester.tap(find.byTooltip('Rediger')); + await tester.pump(); + expect(weekplanBloc.getNumberOfMarkedActivities(), 0); + + // Checking that the select all activities button works + await tester.tap(find.byKey(const Key('SelectAllButton')).first); + await tester.pump(); + expect(weekplanBloc.getNumberOfMarkedActivities(), 2); + + // Checking that the Deselect all activities button works + await tester.tap(find.byKey(const Key('DeselectAllButton')).first); + await tester.pump(); + expect(weekplanBloc.getNumberOfMarkedActivities(), 0); + }); /// All tests test in landscape mode by default. Preferably, we would test /// in portrait mode as well, but we are unsure how to do so - testWidgets('When showing one day in landscape mode for citizen,' - ' one weekday row is created', - (WidgetTester tester) async { + testWidgets( + 'When showing one day in landscape mode for citizen,' + ' one weekday row is created', (WidgetTester tester) async { mockSettings.nrOfDaysToDisplayLandscape = 1; authBloc.setMode(WeekplanMode.citizen); final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); - await tester.pumpWidget(MaterialApp(home: weekplanScreen)); - await tester.pumpAndSettle(); + await tester.pumpWidget(MaterialApp(home: weekplanScreen)); + await tester.pumpAndSettle(); - expect(find.byKey(const Key('SingleWeekdayRow')), findsOneWidget); - }); + expect(find.byKey(const Key('SingleWeekdayRow')), findsOneWidget); + }); - testWidgets('When showing 5 days in landscape mode for citizen, ' - '5 weekday columns are created', - (WidgetTester tester) async { + testWidgets( + 'When showing 5 days in landscape mode for citizen, ' + '5 weekday columns are created', (WidgetTester tester) async { mockSettings.nrOfDaysToDisplayLandscape = 5; authBloc.setMode(WeekplanMode.citizen); final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); - await tester.pumpWidget(MaterialApp(home: weekplanScreen)); - await tester.pumpAndSettle(); - expect(find.byKey(const Key('SingleWeekdayRow')), findsNothing); - expect(find.byType(WeekplanDayColumn), findsNWidgets(5)); - }); + await tester.pumpWidget(MaterialApp(home: weekplanScreen)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('SingleWeekdayRow')), findsNothing); + expect(find.byType(WeekplanDayColumn), findsNWidgets(5)); + }); - testWidgets('When showing 7 days in landscape mode for citizen, ' - '7 weekday columns are created', - (WidgetTester tester) async { + testWidgets( + 'When showing 7 days in landscape mode for citizen, ' + '7 weekday columns are created', (WidgetTester tester) async { mockSettings.nrOfDaysToDisplayLandscape = 7; authBloc.setMode(WeekplanMode.citizen); final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); @@ -724,15 +707,14 @@ void main() { }); testWidgets('7 weekday columns are always created for guardian', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.guardian); - final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); - await tester.pumpWidget(MaterialApp(home: weekplanScreen)); - await tester.pumpAndSettle(); - expect(find.byKey(const Key('SingleWeekdayRow')), findsNothing); - expect(find.byType(WeekplanDayColumn), findsNWidgets(7)); - }); - + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.guardian); + final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); + await tester.pumpWidget(MaterialApp(home: weekplanScreen)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('SingleWeekdayRow')), findsNothing); + expect(find.byType(WeekplanDayColumn), findsNWidgets(7)); + }); testWidgets( 'Week day colors should be in correct order regardless of order in DB', @@ -769,7 +751,7 @@ void main() { testWidgets( 'Pictogram text renders when settings are set to display ' - 'pictogram text', (WidgetTester tester) async { + 'pictogram text', (WidgetTester tester) async { // Enable the setting that displays pictogram text mockSettings.pictogramText = true; @@ -796,13 +778,13 @@ void main() { await tester.pumpAndSettle(); await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is IconButton && widget.tooltip == 'Skift til borger tilstand')); + widget is IconButton && widget.tooltip == 'Skift til borger tilstand')); await tester.pumpAndSettle(); expect(find.byType(GirafConfirmDialog), findsOneWidget); await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is GirafButton && + widget is GirafButton && widget.key == const Key('ConfirmDialogConfirmButton'))); await tester.pumpAndSettle(); @@ -818,17 +800,17 @@ void main() { expect( find.byWidgetPredicate((Widget widget) => - widget is IconButton && + widget is IconButton && widget.tooltip == 'Skift til værge tilstand'), findsOneWidget); await tester.tap(find.byWidgetPredicate((Widget widget) => - widget is IconButton && widget.tooltip == 'Skift til værge tilstand')); + widget is IconButton && widget.tooltip == 'Skift til værge tilstand')); await tester.pumpAndSettle(); expect( find.byWidgetPredicate((Widget widget) => - widget is DialogButton && + widget is DialogButton && widget.key == const Key('SwitchToGuardianSubmit')), findsOneWidget); @@ -840,9 +822,8 @@ void main() { }); testWidgets('Add Activity buttons work', (WidgetTester tester) async { - when(api.pictogram.getAll(page: 1, - pageSize: pageSize, query: '')).thenAnswer( - (_) => rx_dart.BehaviorSubject>.seeded( + when(api.pictogram.getAll(page: 1, pageSize: pageSize, query: '')) + .thenAnswer((_) => rx_dart.BehaviorSubject>.seeded( [mockPictograms[0]])); mockSettings.nrOfDaysToDisplayLandscape = 7; await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); @@ -855,151 +836,138 @@ void main() { expect(find.byType(PictogramSearch), findsOneWidget); await tester.pump(const Duration(milliseconds: 11000)); - }); testWidgets('Completed activities displayed correctly in Guardian Mode', - (WidgetTester tester) async { - mockActivities[0].state = ActivityState.Completed; + (WidgetTester tester) async { + mockActivities[0].state = ActivityState.Completed; - // Added the activity that is completed with checkmark - mockWeek.days[0].activities.add(mockActivities[0]); + // Added the activity that is completed with checkmark + mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - // Find checkmark icon by key - expect(find.byKey(const Key('IconComplete')), findsOneWidget); - }); + // Find checkmark icon by key + expect(find.byKey(const Key('IconComplete')), findsOneWidget); + }); testWidgets('Cancelled activities displayed correctly in Guardian Mode', - (WidgetTester tester) async { - mockActivities[0].state = ActivityState.Canceled; + (WidgetTester tester) async { + mockActivities[0].state = ActivityState.Canceled; - // Added Cancelled activity with a cross - mockWeek.days[0].activities.add(mockActivities[0]); + // Added Cancelled activity with a cross + mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - // Find cross (cancelled) icon by key - expect(find.byKey(const Key('IconCanceled')), findsOneWidget); - }); + // Find cross (cancelled) icon by key + expect(find.byKey(const Key('IconCanceled')), findsOneWidget); + }); testWidgets('Timer icon displayed correctly in Guardian Mode', - (WidgetTester tester) async { - // Activity with a timer - mockWeek.days[0].activities.add(mockActivities[2]); + (WidgetTester tester) async { + // Activity with a timer + mockWeek.days[0].activities.add(mockActivities[2]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - // Find timer icon - expect( - find.byWidgetPredicate((Widget widget) => + // Find timer icon + expect( + find.byWidgetPredicate((Widget widget) => widget is Image && - widget.image == const AssetImage('assets/timer/piechart_icon.png')), - findsOneWidget); - }); + widget.image == const AssetImage('assets/timer/piechart_icon.png')), + findsOneWidget); + }); testWidgets('Check mark completed activity mode works in Citizen Mode', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.citizen); - mockSettings.completeMark = CompleteMark.Checkmark; - mockActivities[0].state = ActivityState.Completed; - // Added the activity that is completed with checkmark - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Find checkmark icon by key - expect(find.byKey(const Key('IconComplete')), findsOneWidget); - }); + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + mockSettings.completeMark = CompleteMark.Checkmark; + mockActivities[0].state = ActivityState.Completed; + // Added the activity that is completed with checkmark + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Find checkmark icon by key + expect(find.byKey(const Key('IconComplete')), findsOneWidget); + }); testWidgets('Greyed out completed activity mode works in Citizen Mode', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.citizen); - mockSettings.completeMark = CompleteMark.MovedRight; - mockActivities[0].state = ActivityState.Completed; - // Added the activity that is completed with checkmark - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Find greyed out box by key - expect( - find.byWidgetPredicate((Widget widget) => + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + mockSettings.completeMark = CompleteMark.MovedRight; + mockActivities[0].state = ActivityState.Completed; + // Added the activity that is completed with checkmark + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Find greyed out box by key + expect( + find.byWidgetPredicate((Widget widget) => widget is Container && widget.key == const Key('GreyOutBox')), - findsOneWidget); - }); + findsOneWidget); + }); testWidgets('Remove completed activity mode works in Citizen Mode', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.citizen); - mockSettings.completeMark = CompleteMark.Removed; - mockActivities[0].state = ActivityState.Completed; - // Added the activity that is completed with checkmark - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Check that the opacity of the activity card is set to zero. - expect( - find.byWidgetPredicate( - (Widget widget) => widget is - Opacity && widget.opacity == 0.0), - findsOneWidget); - }); + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + mockSettings.completeMark = CompleteMark.Removed; + mockActivities[0].state = ActivityState.Completed; + // Added the activity that is completed with checkmark + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Check that the opacity of the activity card is set to zero. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Opacity && widget.opacity == 0.0), + findsOneWidget); + }); testWidgets('Not completed activities are not hidden', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.citizen); - mockSettings.completeMark = CompleteMark.Removed; - mockActivities[0].state = ActivityState.Normal; - // Added the activity that is completed with checkmark - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Check that the opacity of the activity card is set to zero. - expect( - find.byWidgetPredicate( - (Widget widget) => widget is - Opacity && widget.opacity == 1.0), - findsOneWidget); - }); + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + mockSettings.completeMark = CompleteMark.Removed; + mockActivities[0].state = ActivityState.Normal; + // Added the activity that is completed with checkmark + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Check that the opacity of the activity card is set to zero. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Opacity && widget.opacity == 1.0), + findsOneWidget); + }); testWidgets('Check mark completed activity mode works in Citizen Mode', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.citizen); - mockSettings.completeMark = CompleteMark.Checkmark; - mockActivities[0].state = ActivityState.Completed; - // Added the activity that is completed with checkmark - mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); - - // Find checkmark icon by key - expect(find.byKey(const Key('IconComplete')), findsOneWidget); - }); + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + mockSettings.completeMark = CompleteMark.Checkmark; + mockActivities[0].state = ActivityState.Completed; + // Added the activity that is completed with checkmark + mockWeek.days[0].activities.add(mockActivities[0]); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Find checkmark icon by key + expect(find.byKey(const Key('IconComplete')), findsOneWidget); + }); - testWidgets('Tests if the correct number of activities' + testWidgets( + 'Tests if the correct number of activities' ' is displayed', (WidgetTester tester) async { authBloc.setMode(WeekplanMode.citizen); mockSettings.showOnlyActivities = true; mockSettings.nrOfActivitiesToDisplay = 2; - final int weekDay = DateTime - .now() - .weekday - .toInt() - 1; + final int weekDay = DateTime.now().weekday.toInt() - 1; mockWeek.days[weekDay].activities.add(mockActivities[0]); mockWeek.days[weekDay].activities.add(mockActivities[1]); mockWeek.days[weekDay].activities.add(mockActivities[2]); @@ -1011,15 +979,13 @@ void main() { expect(find.byType(ActivityCard), findsNWidgets(2)); }); - testWidgets('Tests if two activities still show up after completing and ' + testWidgets( + 'Tests if two activities still show up after completing and ' 'cancelling first and last activity', (WidgetTester tester) async { authBloc.setMode(WeekplanMode.citizen); mockSettings.showOnlyActivities = true; mockSettings.nrOfActivitiesToDisplay = 2; - final int weekDay = DateTime - .now() - .weekday - .toInt() - 1; + final int weekDay = DateTime.now().weekday.toInt() - 1; mockActivities[0].state = ActivityState.Completed; mockActivities[2].state = ActivityState.Canceled; mockWeek.days[weekDay].activities.add(mockActivities[0]); @@ -1033,15 +999,13 @@ void main() { expect(find.byType(ActivityCard), findsNWidgets(2)); }); - testWidgets('Tests if two activities still show up after completing and ' + testWidgets( + 'Tests if two activities still show up after completing and ' 'cancelling first and last activity', (WidgetTester tester) async { authBloc.setMode(WeekplanMode.citizen); mockSettings.showOnlyActivities = true; mockSettings.nrOfActivitiesToDisplay = 2; - final int weekDay = DateTime - .now() - .weekday - .toInt() - 1; + final int weekDay = DateTime.now().weekday.toInt() - 1; mockActivities[0].state = ActivityState.Completed; mockActivities[1].state = ActivityState.Completed; mockActivities[2].state = ActivityState.Canceled; @@ -1056,15 +1020,13 @@ void main() { expect(find.byType(ActivityCard), findsOneWidget); }); - testWidgets('Tests if two activities still show up after completing and ' + testWidgets( + 'Tests if two activities still show up after completing and ' 'cancelling first and last activity', (WidgetTester tester) async { authBloc.setMode(WeekplanMode.citizen); mockSettings.showOnlyActivities = true; mockSettings.nrOfActivitiesToDisplay = 2; - final int weekDay = DateTime - .now() - .weekday - .toInt() - 1; + final int weekDay = DateTime.now().weekday.toInt() - 1; mockActivities[0].state = ActivityState.Completed; mockActivities[1].state = ActivityState.Completed; mockActivities[2].state = ActivityState.Canceled; @@ -1094,163 +1056,223 @@ void main() { }); testWidgets('Cancelled activities displayed correctly in Citizen Mode', - (WidgetTester tester) async { - authBloc.setMode(WeekplanMode.citizen); - mockActivities[0].state = ActivityState.Canceled; - + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + mockActivities[0].state = ActivityState.Canceled; - // Added Cancelled activity with a cross - mockWeek.days[0].activities.add(mockActivities[0]); + // Added Cancelled activity with a cross + mockWeek.days[0].activities.add(mockActivities[0]); - await tester.pumpWidget(MaterialApp( - home: WeekplanScreen(mockWeek, user))); - await tester.pumpAndSettle(); + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); - // Find cross (cancelled) icon by key - expect(find.byKey(const Key('IconCanceled')), findsOneWidget); - }); + // Find cross (cancelled) icon by key + expect(find.byKey(const Key('IconCanceled')), findsOneWidget); + }); - testWidgets('When showing 7 days in landscape mode for citizen, ' + testWidgets( + 'When showing 7 days in landscape mode for citizen, ' 'the 7 weekdays with their corresponding colors are present', (WidgetTester tester) async { mockSettings.nrOfDaysToDisplayLandscape = 7; - authBloc.setMode(WeekplanMode.citizen); - final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); - await tester.pumpWidget(MaterialApp(home: weekplanScreen)); - await tester.pumpAndSettle(); + authBloc.setMode(WeekplanMode.citizen); + final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); + await tester.pumpWidget(MaterialApp(home: weekplanScreen)); + await tester.pumpAndSettle(); - final List expectedColors = - mockSettings.weekDayColors; - expect( - find.byWidgetPredicate((Widget widget) => + final List expectedColors = mockSettings.weekDayColors; + expect( + find.byWidgetPredicate((Widget widget) => widget is WeekplanDayColumn && widget.color == getColorFromWeekdayColorModel(expectedColors[0])), findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is WeekplanDayColumn && widget.color == getColorFromWeekdayColorModel(expectedColors[1])), findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is WeekplanDayColumn && widget.color == getColorFromWeekdayColorModel(expectedColors[2])), findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is WeekplanDayColumn && widget.color == getColorFromWeekdayColorModel(expectedColors[3])), findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is WeekplanDayColumn && widget.color == getColorFromWeekdayColorModel(expectedColors[4])), findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is WeekplanDayColumn && widget.color == getColorFromWeekdayColorModel(expectedColors[5])), findsOneWidget); - expect( - find.byWidgetPredicate((Widget widget) => + expect( + find.byWidgetPredicate((Widget widget) => widget is WeekplanDayColumn && widget.color == getColorFromWeekdayColorModel(expectedColors[6])), findsOneWidget); }); - testWidgets('Aciticy card starts time when activated' - ' and shows it for citizen', - (WidgetTester tester) async { - await tester.runAsync(() async { - final Completer checkCompleted = Completer(); - - mockActivities[2].state = ActivityState.Normal; - mockActivities[2].timer.paused = true; - mockActivities[2].timer.fullLength = 100; - mockWeek.days[0].activities.add(mockActivities[2]); - authBloc.setMode(WeekplanMode.citizen); - final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); - await tester.pumpWidget(MaterialApp(home: weekplanScreen)); - - await tester.pumpAndSettle(); - await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() + + testWidgets( + 'Aciticy card starts time when activated' + ' and shows it for citizen', (WidgetTester tester) async { + await tester.runAsync(() async { + final Completer checkCompleted = Completer(); + + mockActivities[2].state = ActivityState.Normal; + mockActivities[2].timer.paused = true; + mockActivities[2].timer.fullLength = 100; + mockWeek.days[0].activities.add(mockActivities[2]); + authBloc.setMode(WeekplanMode.citizen); + final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); + await tester.pumpWidget(MaterialApp(home: weekplanScreen)); + + await tester.pumpAndSettle(); + await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() + mockActivities[2].id.toString()))); - await tester.pumpAndSettle(); - - expect(find.byKey(const Key('TimerInitKey')), findsNothing); - // ignore: always_specify_types - Future.delayed(const Duration(seconds: 2), () async { - checkCompleted.complete(); - await checkCompleted.future; - expect(find.byKey(const Key('IconComplete')), findsOneWidget); - }); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key('TimerInitKey')), findsNothing); + // ignore: always_specify_types + Future.delayed(const Duration(seconds: 2), () async { + checkCompleted.complete(); + await checkCompleted.future; + expect(find.byKey(const Key('IconComplete')), findsOneWidget); }); + }); }); testWidgets('Aciticy card has completed icon when activity is completed', - (WidgetTester tester) async { - await tester.runAsync(() async { - mockActivities[0].state = ActivityState.Normal; - mockWeek.days[0].activities.add(mockActivities[0]); - authBloc.setMode(WeekplanMode.citizen); - final WeekplanScreen weekplanScreen = WeekplanScreen( - mockWeek, user); - await tester.pumpWidget(MaterialApp(home: weekplanScreen)); - - await tester.pumpAndSettle(); - await tester.tap( - find.byKey(Key(mockWeek.days[0].day.index.toString() + - mockActivities[0].id.toString()))); - await tester.pumpAndSettle(); - expect(find.byKey(const Key('IconComplete')), findsOneWidget); - }); + (WidgetTester tester) async { + await tester.runAsync(() async { + mockActivities[0].state = ActivityState.Normal; + mockWeek.days[0].activities.add(mockActivities[0]); + authBloc.setMode(WeekplanMode.citizen); + final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); + await tester.pumpWidget(MaterialApp(home: weekplanScreen)); + + await tester.pumpAndSettle(); + await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() + + mockActivities[0].id.toString()))); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('IconComplete')), findsOneWidget); + }); }); - testWidgets('click actitivty card for citizen does nothing ' + testWidgets( + 'click actitivty card for citizen does nothing ' 'if the activity is completed or the timer is running', - (WidgetTester tester) async { - await tester.runAsync(() async { - final Completer checkCompleted = Completer(); - - mockActivities[2].state = ActivityState.Normal; - mockActivities[2].timer.paused = true; - mockActivities[2].timer.fullLength = 100; - mockWeek.days[0].activities.add(mockActivities[2]); - authBloc.setMode(WeekplanMode.citizen); - final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); - await tester.pumpWidget(MaterialApp(home: weekplanScreen)); - - await tester.pumpAndSettle(); - await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() - + mockActivities[2].id.toString()))); - await tester.pumpAndSettle(); - - expect(find.byKey(const Key('TimerInitKey')), findsNothing); - await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() - + mockActivities[2].id.toString()))); - - expect(find.byKey(const Key('TimerInitKey')), findsNothing); - // ignore: always_specify_types - Future.delayed(const Duration(seconds: 2), () async { - checkCompleted.complete(); - await checkCompleted.future; - - expect(find.byKey(const Key('IconComplete')), findsOneWidget); - await tester.tap(find.byKey(Key( - mockWeek.days[0].day.index.toString() - + mockActivities[2].id.toString()))); - - expect(find.byKey(const Key('IconComplete')), findsOneWidget); - }); + (WidgetTester tester) async { + await tester.runAsync(() async { + final Completer checkCompleted = Completer(); + + mockActivities[2].state = ActivityState.Normal; + mockActivities[2].timer.paused = true; + mockActivities[2].timer.fullLength = 100; + mockWeek.days[0].activities.add(mockActivities[2]); + authBloc.setMode(WeekplanMode.citizen); + final WeekplanScreen weekplanScreen = WeekplanScreen(mockWeek, user); + await tester.pumpWidget(MaterialApp(home: weekplanScreen)); + + await tester.pumpAndSettle(); + await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() + + mockActivities[2].id.toString()))); + await tester.pumpAndSettle(); + + expect(find.byKey(const Key('TimerInitKey')), findsNothing); + await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() + + mockActivities[2].id.toString()))); + + expect(find.byKey(const Key('TimerInitKey')), findsNothing); + // ignore: always_specify_types + Future.delayed(const Duration(seconds: 2), () async { + checkCompleted.complete(); + await checkCompleted.future; + + expect(find.byKey(const Key('IconComplete')), findsOneWidget); + await tester.tap(find.byKey(Key(mockWeek.days[0].day.index.toString() + + mockActivities[2].id.toString()))); + + expect(find.byKey(const Key('IconComplete')), findsOneWidget); }); }); + }); + + testWidgets( + 'Choice board displays properly in citizen mode when an activity has not been chosen', + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + + // Add the activity to mockWeek + mockWeek.days[0].activities.add(mockActivities[3]); + + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Check if no choice board exists. + expect(find.byKey(const Key('WeekPlanScreenChoiceBoard')), findsOneWidget); + }); + + testWidgets( + 'Choice board displays properly in citizen mode when an activity has been chosen', + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.citizen); + + mockActivities[3].chosenActivity = 0; + + // Add the activity to mockWeek + mockWeek.days[0].activities.add(mockActivities[3]); + + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Check if no choice board exists. + expect(find.byKey(const Key('WeekPlanScreenChoiceBoard')), findsNothing); + }); + + testWidgets( + 'Choice board displays properly in guardian mode when an activity has not been chosen', + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.guardian); + + // Add the activity to mockWeek + mockWeek.days[0].activities.add(mockActivities[3]); + + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Check if no choice board exists. + expect(find.byKey(const Key('WeekPlanScreenChoiceBoard')), findsOneWidget); + }); + + testWidgets( + 'Choice board displays properly in guardian mode when an activity has been chosen', + (WidgetTester tester) async { + authBloc.setMode(WeekplanMode.guardian); + + mockActivities[3].chosenActivity = 0; + + // Add the activity to mockWeek + mockWeek.days[0].activities.add(mockActivities[3]); + + await tester.pumpWidget(MaterialApp(home: WeekplanScreen(mockWeek, user))); + await tester.pumpAndSettle(); + + // Check if no choice board exists. + expect(find.byKey(const Key('WeekPlanScreenChoiceBoard')), findsOneWidget); + }); } Color getColorFromWeekdayColorModel(WeekdayColorModel weekdayColorModel) { @@ -1279,9 +1301,9 @@ void expectColorDayMatch(Weekday day, String color) { } final Finder findColor = find.byWidgetPredicate((Widget widget) => - widget is Card && widget.color == Color(int.parse(color))); + widget is Card && widget.color == Color(int.parse(color))); final Finder findTitle = find.byWidgetPredicate( - (Widget widget) => widget is Card && widget.key == Key(dayString)); + (Widget widget) => widget is Card && widget.key == Key(dayString)); expect(find.descendant(of: findColor, matching: findTitle), findsOneWidget); }