From 6b8347082b25ad5c12fc30dbd1a4ddf591f0a505 Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 20:04:19 -0300 Subject: [PATCH 01/10] Refactor CheckAllActionChipWidget to handle null status and simplify ProgressWidget padding --- .../widgets/check_all_action_chip_widget.dart | 34 +++++++++++------- .../components/widgets/progress_widget.dart | 35 +++++++++++-------- .../task/taskslist/tasks_list_widget.dart | 3 +- lib/ui/screens/tasks/tasks_screen.dart | 25 +++++-------- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/lib/ui/components/widgets/check_all_action_chip_widget.dart b/lib/ui/components/widgets/check_all_action_chip_widget.dart index 58b2cf9..74cbd3e 100644 --- a/lib/ui/components/widgets/check_all_action_chip_widget.dart +++ b/lib/ui/components/widgets/check_all_action_chip_widget.dart @@ -3,7 +3,7 @@ import 'package:todoapp/data/model/tasks_complete_status.dart'; import 'package:todoapp/ui/l10n/app_localizations.dart'; class CheckAllActionChipWidget extends StatelessWidget { - final TasksCompleteStatus status; + final TasksCompleteStatus? status; final VoidCallback onClick; const CheckAllActionChipWidget({ @@ -17,17 +17,27 @@ class CheckAllActionChipWidget extends StatelessWidget { final localizations = AppLocalizations.of(context)!; String text; - switch (status) { - case TasksCompleteStatus.checkAll: - text = localizations.check_all; - case TasksCompleteStatus.uncheckAll: - text = localizations.uncheck_all; + if (status == null) { + return const SizedBox.shrink(); + } else { + switch (status!) { + case TasksCompleteStatus.checkAll: + text = localizations.check_all; + case TasksCompleteStatus.uncheckAll: + text = localizations.uncheck_all; + } + return Padding( + padding: const EdgeInsets.only( + left: 12, + right: 12, + ), + child: ActionChip( + label: Text(text), + onPressed: () { + onClick(); + }, + ), + ); } - return ActionChip( - label: Text(text), - onPressed: () { - onClick(); - }, - ); } } diff --git a/lib/ui/components/widgets/progress_widget.dart b/lib/ui/components/widgets/progress_widget.dart index f2f4660..a96e964 100644 --- a/lib/ui/components/widgets/progress_widget.dart +++ b/lib/ui/components/widgets/progress_widget.dart @@ -19,23 +19,28 @@ class ProgressWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Stack( - children: [ - Container( - width: double.infinity, - height: containerHeight, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.onTertiary, + return Padding( + padding: const EdgeInsets.only( + bottom: 8, + ), + child: Stack( + children: [ + Container( + width: double.infinity, + height: containerHeight, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.onTertiary, + ), ), - ), - LayoutBuilder( - builder: (context, constraints) => _buildProgressBar( - progress: _progress, - maxWidth: constraints.maxWidth, - color: _color, + LayoutBuilder( + builder: (context, constraints) => _buildProgressBar( + progress: _progress, + maxWidth: constraints.maxWidth, + color: _color, + ), ), - ), - ], + ], + ), ); } diff --git a/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart b/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart index 9701d65..0df2282 100644 --- a/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart +++ b/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart @@ -41,8 +41,7 @@ class TasksListWidget extends StatelessWidget { child = ReorderableListView.builder( onReorder: onReorder, padding: const EdgeInsets.only( - top: 12, - bottom: 120, + bottom: 120.0, ), itemBuilder: (context, index) => _buildTaskCellWidget( tasks[index], diff --git a/lib/ui/screens/tasks/tasks_screen.dart b/lib/ui/screens/tasks/tasks_screen.dart index c3ec05d..7e27db0 100644 --- a/lib/ui/screens/tasks/tasks_screen.dart +++ b/lib/ui/screens/tasks/tasks_screen.dart @@ -115,24 +115,15 @@ class TasksScaffold extends StatelessWidget { body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.only( - bottom: 8, - ), - child: ProgressWidget( - progress: uiState.progress, - ), + ProgressWidget( + progress: uiState.progress, + ), + CheckAllActionChipWidget( + status: uiState.tasksCompleteStatus, + onClick: () { + callbacks.onCompleteButtonAction(); + }, ), - Padding( - padding: const EdgeInsets.only(left: 12, right: 12, bottom: 8), - child: uiState.tasksCompleteStatus != null - ? CheckAllActionChipWidget( - status: uiState.tasksCompleteStatus!, - onClick: () { - callbacks.onCompleteButtonAction(); - }, - ) - : const SizedBox.shrink()), TasksListWidget( tasks: uiState.tasks, emptyTasksMessage: localizations.empty_tasks, From 4edddaac9c3fabfb7af2c660c5bea5f19e0ab0f4 Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 20:08:53 -0300 Subject: [PATCH 02/10] Remove unused emptyTasksMessage parameter from TasksListWidget and update usage in TasksScaffold --- .../widgets/checklist/checklist_full_widget.dart | 1 - .../widgets/task/taskslist/tasks_list_widget.dart | 8 +++++--- lib/ui/screens/tasks/tasks_screen.dart | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ui/components/widgets/checklist/checklist_full_widget.dart b/lib/ui/components/widgets/checklist/checklist_full_widget.dart index d36b2c0..a6cfaa3 100644 --- a/lib/ui/components/widgets/checklist/checklist_full_widget.dart +++ b/lib/ui/components/widgets/checklist/checklist_full_widget.dart @@ -103,7 +103,6 @@ class ChecklistsListFullWidgetState extends State { TasksListWidget( flex: 6, tasks: tasks == null ? [] : tasks!, - emptyTasksMessage: localizations.empty_tasks, onCompleteTask: _tasksViewModel.onCompleteTask, onRemoveTask: (task) => _showConfirmationDialogToRemoveTask( context, diff --git a/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart b/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart index 0df2282..9f9389a 100644 --- a/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart +++ b/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:todoapp/data/model/task.dart'; import 'package:todoapp/ui/components/widgets/task/task_cell_widget.dart'; +import 'package:todoapp/ui/l10n/app_localizations.dart'; class TasksListWidget extends StatelessWidget { final List tasks; final int? flex; - final String emptyTasksMessage; final Function(Task) onRemoveTask; final Function(Task p1, bool p2) onCompleteTask; final Function(int oldIndex, int newIndex) onReorder; @@ -15,7 +15,6 @@ class TasksListWidget extends StatelessWidget { super.key, required this.tasks, this.flex, - required this.emptyTasksMessage, required this.onRemoveTask, required this.onCompleteTask, required this.onReorder, @@ -28,11 +27,14 @@ class TasksListWidget extends StatelessWidget { } Widget _buildTaskList(BuildContext context) { + final localizations = AppLocalizations.of(context)!; + final emptyTaskMessage = localizations.empty_tasks; + Widget child; if (tasks.isEmpty) { child = Center( child: Text( - emptyTasksMessage, + emptyTaskMessage, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyLarge, ), diff --git a/lib/ui/screens/tasks/tasks_screen.dart b/lib/ui/screens/tasks/tasks_screen.dart index 7e27db0..a836495 100644 --- a/lib/ui/screens/tasks/tasks_screen.dart +++ b/lib/ui/screens/tasks/tasks_screen.dart @@ -126,7 +126,6 @@ class TasksScaffold extends StatelessWidget { ), TasksListWidget( tasks: uiState.tasks, - emptyTasksMessage: localizations.empty_tasks, onReorder: callbacks.onReorder, onRemoveTask: (task) => _showConfirmationDialogToRemoveTask(context, task), From a7a4966c4aadb43c3e376432900fe364c3626efd Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 20:12:08 -0300 Subject: [PATCH 03/10] Remove unused localizations variable from _buildTaskList method --- lib/ui/components/widgets/checklist/checklist_full_widget.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ui/components/widgets/checklist/checklist_full_widget.dart b/lib/ui/components/widgets/checklist/checklist_full_widget.dart index a6cfaa3..a8cf567 100644 --- a/lib/ui/components/widgets/checklist/checklist_full_widget.dart +++ b/lib/ui/components/widgets/checklist/checklist_full_widget.dart @@ -84,7 +84,6 @@ class ChecklistsListFullWidgetState extends State { } Widget _buildTaskList(BuildContext context) { - final localizations = AppLocalizations.of(context)!; return Row( children: [ Expanded( From 98e2f5c06f59d0c50232b02018412dd55e516f45 Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 20:34:12 -0300 Subject: [PATCH 04/10] Add progress and status parameters to TasksListWidget and update usage in TasksScaffold --- .../checklist/checklist_full_widget.dart | 3 ++ .../task/taskslist/tasks_list_widget.dart | 43 +++++++++++++---- lib/ui/screens/tasks/tasks_screen.dart | 47 +++++++------------ 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/lib/ui/components/widgets/checklist/checklist_full_widget.dart b/lib/ui/components/widgets/checklist/checklist_full_widget.dart index a8cf567..29d2bfd 100644 --- a/lib/ui/components/widgets/checklist/checklist_full_widget.dart +++ b/lib/ui/components/widgets/checklist/checklist_full_widget.dart @@ -101,6 +101,8 @@ class ChecklistsListFullWidgetState extends State { ), TasksListWidget( flex: 6, + progress: 0.0, + status: null, tasks: tasks == null ? [] : tasks!, onCompleteTask: _tasksViewModel.onCompleteTask, onRemoveTask: (task) => _showConfirmationDialogToRemoveTask( @@ -113,6 +115,7 @@ class ChecklistsListFullWidgetState extends State { checklistId: selected?.id, task: task, ), + onCompleteButtonAction: () {}, ), ], ); diff --git a/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart b/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart index 9f9389a..4c755cf 100644 --- a/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart +++ b/lib/ui/components/widgets/task/taskslist/tasks_list_widget.dart @@ -1,24 +1,33 @@ import 'package:flutter/material.dart'; import 'package:todoapp/data/model/task.dart'; +import 'package:todoapp/data/model/tasks_complete_status.dart'; +import 'package:todoapp/ui/components/widgets/check_all_action_chip_widget.dart'; +import 'package:todoapp/ui/components/widgets/progress_widget.dart'; import 'package:todoapp/ui/components/widgets/task/task_cell_widget.dart'; import 'package:todoapp/ui/l10n/app_localizations.dart'; class TasksListWidget extends StatelessWidget { final List tasks; + final double progress; + final TasksCompleteStatus? status; final int? flex; final Function(Task) onRemoveTask; final Function(Task p1, bool p2) onCompleteTask; final Function(int oldIndex, int newIndex) onReorder; final Function(Task) onTap; + final Function() onCompleteButtonAction; const TasksListWidget({ super.key, required this.tasks, + required this.progress, + this.status, this.flex, required this.onRemoveTask, required this.onCompleteTask, required this.onReorder, required this.onTap, + required this.onCompleteButtonAction, }); @override @@ -40,15 +49,31 @@ class TasksListWidget extends StatelessWidget { ), ); } else { - child = ReorderableListView.builder( - onReorder: onReorder, - padding: const EdgeInsets.only( - bottom: 120.0, - ), - itemBuilder: (context, index) => _buildTaskCellWidget( - tasks[index], - ), - itemCount: tasks.length, + child = Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ProgressWidget( + progress: progress, + ), + CheckAllActionChipWidget( + status: status, + onClick: () { + onCompleteButtonAction(); + }, + ), + Expanded( + child: ReorderableListView.builder( + onReorder: onReorder, + padding: const EdgeInsets.only( + bottom: 120.0, + ), + itemBuilder: (context, index) => _buildTaskCellWidget( + tasks[index], + ), + itemCount: tasks.length, + ), + ), + ], ); } diff --git a/lib/ui/screens/tasks/tasks_screen.dart b/lib/ui/screens/tasks/tasks_screen.dart index a836495..8e71fe3 100644 --- a/lib/ui/screens/tasks/tasks_screen.dart +++ b/lib/ui/screens/tasks/tasks_screen.dart @@ -4,9 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:todoapp/data/model/checklist.dart'; import 'package:todoapp/data/model/task.dart'; import 'package:todoapp/ui/components/remove_task_dialog_builder.dart'; -import 'package:todoapp/ui/components/widgets/check_all_action_chip_widget.dart'; import 'package:todoapp/ui/components/widgets/custom_app_bar_widget.dart'; -import 'package:todoapp/ui/components/widgets/progress_widget.dart'; import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_list_widget.dart'; import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_screen_state.dart'; import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_viewmodel.dart'; @@ -112,33 +110,24 @@ class TasksScaffold extends StatelessWidget { ); }, ), - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ProgressWidget( - progress: uiState.progress, - ), - CheckAllActionChipWidget( - status: uiState.tasksCompleteStatus, - onClick: () { - callbacks.onCompleteButtonAction(); - }, - ), - TasksListWidget( - tasks: uiState.tasks, - onReorder: callbacks.onReorder, - onRemoveTask: (task) => - _showConfirmationDialogToRemoveTask(context, task), - onCompleteTask: callbacks.onCompleteTask, - onTap: (task) => { - _navigateToTaskScreen( - context, - checklistId: checklistId, - task: task, - ) - }, - ), - ], + body: TasksListWidget( + tasks: uiState.tasks, + status: uiState.tasksCompleteStatus, + progress: uiState.progress, + onReorder: callbacks.onReorder, + onRemoveTask: (task) => + _showConfirmationDialogToRemoveTask(context, task), + onCompleteTask: callbacks.onCompleteTask, + onTap: (task) => { + _navigateToTaskScreen( + context, + checklistId: checklistId, + task: task, + ) + }, + onCompleteButtonAction: () { + callbacks.onCompleteButtonAction(); + }, ), ); } From 4a430c2f26a42c9abeda1490da834efb07523fcd Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 20:42:52 -0300 Subject: [PATCH 05/10] Update ChecklistsListFullWidget to track task progress and status from TasksViewModel --- .../widgets/checklist/checklist_full_widget.dart | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/ui/components/widgets/checklist/checklist_full_widget.dart b/lib/ui/components/widgets/checklist/checklist_full_widget.dart index 29d2bfd..fb66bb1 100644 --- a/lib/ui/components/widgets/checklist/checklist_full_widget.dart +++ b/lib/ui/components/widgets/checklist/checklist_full_widget.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:todoapp/data/model/checklist.dart'; import 'package:todoapp/data/model/task.dart'; +import 'package:todoapp/data/model/tasks_complete_status.dart'; import 'package:todoapp/ui/components/remove_task_dialog_builder.dart'; import 'package:todoapp/ui/components/widgets/checklist/checklist_item_widget.dart'; import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_list_widget.dart'; @@ -30,6 +31,8 @@ class ChecklistsListFullWidget extends StatefulWidget { class ChecklistsListFullWidgetState extends State { Checklist? selected; List? tasks; + double progress = 0.0; + TasksCompleteStatus? status; late TasksViewModel _tasksViewModel; @override @@ -58,6 +61,8 @@ class ChecklistsListFullWidgetState extends State { _tasksViewModel.stream.listen((state) { setState(() { tasks = state.tasks; + progress = state.progress; + status = state.tasksCompleteStatus; }); }); }); @@ -101,8 +106,8 @@ class ChecklistsListFullWidgetState extends State { ), TasksListWidget( flex: 6, - progress: 0.0, - status: null, + progress: progress, + status: status, tasks: tasks == null ? [] : tasks!, onCompleteTask: _tasksViewModel.onCompleteTask, onRemoveTask: (task) => _showConfirmationDialogToRemoveTask( @@ -115,7 +120,9 @@ class ChecklistsListFullWidgetState extends State { checklistId: selected?.id, task: task, ), - onCompleteButtonAction: () {}, + onCompleteButtonAction: () { + _tasksViewModel.onCompleteButtonAction(selected?.id); + }, ), ], ); From bdc1c219ae63f7c5999a66b8e03d61a76af973ad Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 20:56:20 -0300 Subject: [PATCH 06/10] Implement ShareMessageHandler and integrate sharing functionality in TodoRepository --- lib/{util => data}/share_message_handler.dart | 0 lib/data/todo_repository.dart | 13 +++++++++++++ .../widgets/checklist/checklist_full_widget.dart | 1 - .../widgets/task/taskslist/tasks_viewmodel.dart | 6 +----- lib/ui/screens/tasks/tasks_screen.dart | 1 - test/test_utils/fakes/fake_repository.dart | 5 +++++ .../fakes/fake_share_message_handler.dart | 8 -------- .../task/taskslist/tasks_viewmodel_test.dart | 2 -- 8 files changed, 19 insertions(+), 17 deletions(-) rename lib/{util => data}/share_message_handler.dart (100%) delete mode 100644 test/test_utils/fakes/fake_share_message_handler.dart diff --git a/lib/util/share_message_handler.dart b/lib/data/share_message_handler.dart similarity index 100% rename from lib/util/share_message_handler.dart rename to lib/data/share_message_handler.dart diff --git a/lib/data/todo_repository.dart b/lib/data/todo_repository.dart index d9b65bc..e05ceb2 100644 --- a/lib/data/todo_repository.dart +++ b/lib/data/todo_repository.dart @@ -3,6 +3,7 @@ import 'package:todoapp/data/database/checklist_dao.dart'; import 'package:todoapp/data/database/task_dao.dart'; import 'package:todoapp/data/model/checklist.dart'; import 'package:todoapp/data/model/task.dart'; +import 'package:todoapp/data/share_message_handler.dart'; abstract class TodoRepository { Future> getTasks(int? checklistId); @@ -28,16 +29,23 @@ abstract class TodoRepository { required int taskId, required String taskTitle, }); + + Future share({ + required String text, + required String title, + }); } @Injectable(as: TodoRepository) class TodoRepositoryImpl implements TodoRepository { final TaskDAO _todoDAO; final ChecklistDAO _checklistDAO; + final ShareMessageHandler _shareMessageHandler; TodoRepositoryImpl( this._todoDAO, this._checklistDAO, + this._shareMessageHandler, ); @override @@ -97,4 +105,9 @@ class TodoRepositoryImpl implements TodoRepository { Future updateTasks(List tasks, bool isCompletedNewValue) async { return await _todoDAO.updateTasks(tasks, isCompletedNewValue); } + + @override + Future share({required String text, required String title}) { + return _shareMessageHandler.share(text: text, title: title); + } } diff --git a/lib/ui/components/widgets/checklist/checklist_full_widget.dart b/lib/ui/components/widgets/checklist/checklist_full_widget.dart index fb66bb1..2c6a177 100644 --- a/lib/ui/components/widgets/checklist/checklist_full_widget.dart +++ b/lib/ui/components/widgets/checklist/checklist_full_widget.dart @@ -42,7 +42,6 @@ class ChecklistsListFullWidgetState extends State { _tasksViewModel = TasksViewModel( repository: getIt.get(), taskListSummaryHelper: getIt.get(), - shareMessageHandler: getIt.get(), taskListSortHelper: getIt.get(), ); } diff --git a/lib/ui/components/widgets/task/taskslist/tasks_viewmodel.dart b/lib/ui/components/widgets/task/taskslist/tasks_viewmodel.dart index d99d5b1..a7281a9 100644 --- a/lib/ui/components/widgets/task/taskslist/tasks_viewmodel.dart +++ b/lib/ui/components/widgets/task/taskslist/tasks_viewmodel.dart @@ -6,17 +6,14 @@ import 'package:todoapp/data/todo_repository.dart'; import 'package:todoapp/domain/task_list_sort_helper.dart'; import 'package:todoapp/domain/task_list_summary_helper.dart'; import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_screen_state.dart'; -import 'package:todoapp/util/share_message_handler.dart'; class TasksViewModel extends Cubit { late TodoRepository _repository; - late ShareMessageHandler _shareMessageHandler; late TaskListSummaryHelper _taskListSummaryHelper; late TaskListSortHelper _taskListSortHelper; TasksViewModel({ required TodoRepository repository, - required ShareMessageHandler shareMessageHandler, required TaskListSummaryHelper taskListSummaryHelper, required TaskListSortHelper taskListSortHelper, }) : super( @@ -28,7 +25,6 @@ class TasksViewModel extends Cubit { ), ) { _repository = repository; - _shareMessageHandler = shareMessageHandler; _taskListSummaryHelper = taskListSummaryHelper; _taskListSortHelper = taskListSortHelper; } @@ -79,7 +75,7 @@ class TasksViewModel extends Cubit { tasks: state.tasks, ); - await _shareMessageHandler.share( + await _repository.share( text: checklist, title: checklistName, ); diff --git a/lib/ui/screens/tasks/tasks_screen.dart b/lib/ui/screens/tasks/tasks_screen.dart index 8e71fe3..19bbbf4 100644 --- a/lib/ui/screens/tasks/tasks_screen.dart +++ b/lib/ui/screens/tasks/tasks_screen.dart @@ -30,7 +30,6 @@ class TasksScreen extends StatelessWidget { final getIt = GetItStartupHandlerWrapper.getIt; final viewModel = TasksViewModel( repository: getIt.get(), - shareMessageHandler: getIt.get(), taskListSummaryHelper: getIt.get(), taskListSortHelper: getIt.get(), ); diff --git a/test/test_utils/fakes/fake_repository.dart b/test/test_utils/fakes/fake_repository.dart index d8d3cea..0e6051e 100644 --- a/test/test_utils/fakes/fake_repository.dart +++ b/test/test_utils/fakes/fake_repository.dart @@ -89,4 +89,9 @@ class FakeRepository implements TodoRepository { } return Future.value(true); } + + @override + Future share({required String text, required String title}) { + return Future.value(true); + } } diff --git a/test/test_utils/fakes/fake_share_message_handler.dart b/test/test_utils/fakes/fake_share_message_handler.dart deleted file mode 100644 index f6978bc..0000000 --- a/test/test_utils/fakes/fake_share_message_handler.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:todoapp/util/share_message_handler.dart'; - -class FakeShareMessageHandler extends ShareMessageHandler { - @override - Future share({required String text, required String title}) { - return Future.value(true); - } -} diff --git a/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart b/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart index cf525ec..4f68a3b 100644 --- a/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart +++ b/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart @@ -7,7 +7,6 @@ import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_screen_state. import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_viewmodel.dart'; import '../../../../../test_utils/fakes/fake_repository.dart'; -import '../../../../../test_utils/fakes/fake_share_message_handler.dart'; void main() { late TasksViewModel viewModel; @@ -18,7 +17,6 @@ void main() { viewModel = TasksViewModel( repository: fakeRepository, taskListSummaryHelper: TaskListSummaryHelperImpl(), - shareMessageHandler: FakeShareMessageHandler(), taskListSortHelper: TaskListSortHelperImpl(), ); }); From 939a4773c3884f165dee08b643cf514f87cd9ad8 Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 22:47:33 -0300 Subject: [PATCH 07/10] Refactor ChecklistViewModel and ChecklistsViewModel to use GetIt for dependency injection --- lib/ui/screens/checklist/checklist_screen.dart | 4 +--- lib/ui/screens/checklist/checklist_viewmodel.dart | 2 ++ lib/ui/screens/checklists/checklists_screen.dart | 9 +++------ lib/ui/screens/checklists/checklists_viewmodel.dart | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/ui/screens/checklist/checklist_screen.dart b/lib/ui/screens/checklist/checklist_screen.dart index f459d9b..02d7a2a 100644 --- a/lib/ui/screens/checklist/checklist_screen.dart +++ b/lib/ui/screens/checklist/checklist_screen.dart @@ -16,9 +16,7 @@ class ChecklistScreen extends StatelessWidget { @override Widget build(BuildContext context) { - final viewModel = ChecklistViewModel( - GetItStartupHandlerWrapper.getIt.get(), - ); + final viewModel = GetItStartupHandlerWrapper.getIt(); return ChecklistScreenScaffold( formScreenValidator: GetItStartupHandlerWrapper.getIt.get(), diff --git a/lib/ui/screens/checklist/checklist_viewmodel.dart b/lib/ui/screens/checklist/checklist_viewmodel.dart index edc3479..d61c365 100644 --- a/lib/ui/screens/checklist/checklist_viewmodel.dart +++ b/lib/ui/screens/checklist/checklist_viewmodel.dart @@ -1,7 +1,9 @@ +import 'package:injectable/injectable.dart'; import 'package:todoapp/data/model/checklist.dart'; import 'package:todoapp/data/todo_repository.dart'; +@Injectable() class ChecklistViewModel { late TodoRepository _repository; diff --git a/lib/ui/screens/checklists/checklists_screen.dart b/lib/ui/screens/checklists/checklists_screen.dart index a128080..5c13593 100644 --- a/lib/ui/screens/checklists/checklists_screen.dart +++ b/lib/ui/screens/checklists/checklists_screen.dart @@ -21,9 +21,8 @@ class ChecklistsScreen extends StatelessWidget { @override Widget build(BuildContext context) { - final viewModel = ChecklistsViewModel( - GetItStartupHandlerWrapper.getIt.get(), - ); + final viewModel = + GetItStartupHandlerWrapper.getIt.get(); viewModel.updateChecklists(); return BlocProvider( @@ -71,9 +70,7 @@ class ChecklistsScaffold extends StatelessWidget { onSharePressed: () async { await _checklistFullKey.currentState?.onShareTasks(); }, - onSortPressed: () => { - _checklistFullKey.currentState?.onSortTasks() - }, + onSortPressed: () => {_checklistFullKey.currentState?.onSortTasks()}, onNewTaskPressed: () async { /// Use key to access a specific internal behavior of /// TaskViewModel to update the task list through diff --git a/lib/ui/screens/checklists/checklists_viewmodel.dart b/lib/ui/screens/checklists/checklists_viewmodel.dart index 262e2f5..c5b1250 100644 --- a/lib/ui/screens/checklists/checklists_viewmodel.dart +++ b/lib/ui/screens/checklists/checklists_viewmodel.dart @@ -5,7 +5,7 @@ import 'package:todoapp/data/todo_repository.dart'; import 'package:todoapp/ui/screens/checklists/checklists_screen_state.dart'; -@injectable +@Injectable() class ChecklistsViewModel extends Cubit { late TodoRepository _repository; From 7f3d242b5b09409a53f7efc6b9519454fcf60cc8 Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 22:54:36 -0300 Subject: [PATCH 08/10] Add TasksScreenState and TasksViewModel for task management functionality --- .../tasks_screen_state.dart | 0 .../tasks_viewmodel.dart | 4 +++- .../widgets/checklist/checklist_full_widget.dart | 8 ++------ lib/ui/screens/tasks/tasks_screen.dart | 10 +++------- test/test_utils/fakes/fake_states.dart | 2 +- .../widgets/task/taskslist/tasks_viewmodel_test.dart | 4 ++-- 6 files changed, 11 insertions(+), 17 deletions(-) rename lib/ui/components/{widgets/task/taskslist => tasks_view_model}/tasks_screen_state.dart (100%) rename lib/ui/components/{widgets/task/taskslist => tasks_view_model}/tasks_viewmodel.dart (97%) diff --git a/lib/ui/components/widgets/task/taskslist/tasks_screen_state.dart b/lib/ui/components/tasks_view_model/tasks_screen_state.dart similarity index 100% rename from lib/ui/components/widgets/task/taskslist/tasks_screen_state.dart rename to lib/ui/components/tasks_view_model/tasks_screen_state.dart diff --git a/lib/ui/components/widgets/task/taskslist/tasks_viewmodel.dart b/lib/ui/components/tasks_view_model/tasks_viewmodel.dart similarity index 97% rename from lib/ui/components/widgets/task/taskslist/tasks_viewmodel.dart rename to lib/ui/components/tasks_view_model/tasks_viewmodel.dart index a7281a9..a1db0d7 100644 --- a/lib/ui/components/widgets/task/taskslist/tasks_viewmodel.dart +++ b/lib/ui/components/tasks_view_model/tasks_viewmodel.dart @@ -1,12 +1,14 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:injectable/injectable.dart'; import 'package:todoapp/data/model/task.dart'; import 'package:todoapp/data/model/tasks_complete_status.dart'; import 'package:todoapp/data/todo_repository.dart'; import 'package:todoapp/domain/task_list_sort_helper.dart'; import 'package:todoapp/domain/task_list_summary_helper.dart'; -import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_screen_state.dart'; +import 'package:todoapp/ui/components/tasks_view_model/tasks_screen_state.dart'; +@Injectable() class TasksViewModel extends Cubit { late TodoRepository _repository; late TaskListSummaryHelper _taskListSummaryHelper; diff --git a/lib/ui/components/widgets/checklist/checklist_full_widget.dart b/lib/ui/components/widgets/checklist/checklist_full_widget.dart index 2c6a177..157dd31 100644 --- a/lib/ui/components/widgets/checklist/checklist_full_widget.dart +++ b/lib/ui/components/widgets/checklist/checklist_full_widget.dart @@ -3,9 +3,9 @@ import 'package:todoapp/data/model/checklist.dart'; import 'package:todoapp/data/model/task.dart'; import 'package:todoapp/data/model/tasks_complete_status.dart'; import 'package:todoapp/ui/components/remove_task_dialog_builder.dart'; +import 'package:todoapp/ui/components/tasks_view_model/tasks_viewmodel.dart'; import 'package:todoapp/ui/components/widgets/checklist/checklist_item_widget.dart'; import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_list_widget.dart'; -import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_viewmodel.dart'; import 'package:todoapp/ui/l10n/app_localizations.dart'; import 'package:todoapp/ui/todo_app_router_config.gr.dart'; import 'package:todoapp/util/di/dependency_startup_launcher.dart'; @@ -39,11 +39,7 @@ class ChecklistsListFullWidgetState extends State { void initState() { super.initState(); final getIt = GetItStartupHandlerWrapper.getIt; - _tasksViewModel = TasksViewModel( - repository: getIt.get(), - taskListSummaryHelper: getIt.get(), - taskListSortHelper: getIt.get(), - ); + _tasksViewModel = getIt(); } @override diff --git a/lib/ui/screens/tasks/tasks_screen.dart b/lib/ui/screens/tasks/tasks_screen.dart index 19bbbf4..eb96ed9 100644 --- a/lib/ui/screens/tasks/tasks_screen.dart +++ b/lib/ui/screens/tasks/tasks_screen.dart @@ -4,10 +4,10 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:todoapp/data/model/checklist.dart'; import 'package:todoapp/data/model/task.dart'; import 'package:todoapp/ui/components/remove_task_dialog_builder.dart'; +import 'package:todoapp/ui/components/tasks_view_model/tasks_screen_state.dart'; +import 'package:todoapp/ui/components/tasks_view_model/tasks_viewmodel.dart'; import 'package:todoapp/ui/components/widgets/custom_app_bar_widget.dart'; import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_list_widget.dart'; -import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_screen_state.dart'; -import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_viewmodel.dart'; import 'package:todoapp/ui/l10n/app_localizations.dart'; import 'package:todoapp/ui/screens/tasks/tasks_screen_callbacks.dart'; import 'package:todoapp/ui/todo_app_router_config.gr.dart'; @@ -28,11 +28,7 @@ class TasksScreen extends StatelessWidget { @override Widget build(BuildContext context) { final getIt = GetItStartupHandlerWrapper.getIt; - final viewModel = TasksViewModel( - repository: getIt.get(), - taskListSummaryHelper: getIt.get(), - taskListSortHelper: getIt.get(), - ); + final viewModel = getIt(); viewModel.updateTasks(checklist.id); return BlocProvider( diff --git a/test/test_utils/fakes/fake_states.dart b/test/test_utils/fakes/fake_states.dart index 1808cd1..0b7ba0e 100644 --- a/test/test_utils/fakes/fake_states.dart +++ b/test/test_utils/fakes/fake_states.dart @@ -1,5 +1,5 @@ import 'package:todoapp/data/model/task.dart'; -import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_screen_state.dart'; +import 'package:todoapp/ui/components/tasks_view_model/tasks_screen_state.dart'; class FakeStates { static const fakeTasksEmptyState = TasksScreenState( diff --git a/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart b/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart index 4f68a3b..ec0d9cd 100644 --- a/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart +++ b/test/ui/components/widgets/task/taskslist/tasks_viewmodel_test.dart @@ -3,8 +3,8 @@ import 'package:todoapp/data/model/task.dart'; import 'package:todoapp/data/model/tasks_complete_status.dart'; import 'package:todoapp/domain/task_list_sort_helper.dart'; import 'package:todoapp/domain/task_list_summary_helper.dart'; -import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_screen_state.dart'; -import 'package:todoapp/ui/components/widgets/task/taskslist/tasks_viewmodel.dart'; +import 'package:todoapp/ui/components/tasks_view_model/tasks_screen_state.dart'; +import 'package:todoapp/ui/components/tasks_view_model/tasks_viewmodel.dart'; import '../../../../../test_utils/fakes/fake_repository.dart'; From 09ae7d2fec373f6f4e7a130d6f35764176f14835 Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 23:31:31 -0300 Subject: [PATCH 09/10] Bump version to 1.2.1 and remove equatable dependency from pubspec.yaml --- pubspec.lock | 8 -------- pubspec.yaml | 3 +-- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index ab64c03..fafdef5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -233,14 +233,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" - equatable: - dependency: "direct main" - description: - name: equatable - sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b" - url: "https://pub.dev" - source: hosted - version: "2.0.8" fake_async: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f860e81..fc36ccf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.2.0 +version: 1.2.1 environment: sdk: ^3.5.0 @@ -39,7 +39,6 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 get_it: ^9.2.1 - equatable: ^2.0.7 flutter_bloc: ^9.1.1 sqflite: ^2.4.2 injectable: ^2.5.0 From 61a8b9fe1e0ef1eb046a5423f219edea7fac401b Mon Sep 17 00:00:00 2001 From: Gabriel Moro Date: Fri, 3 Apr 2026 23:35:22 -0300 Subject: [PATCH 10/10] Remove obsolete test files for checklist, checklists, startup, task, and tasks screens --- test/ui/screens/checklist_screen_test.dart | 28 ----- test/ui/screens/checklists_screen_test.dart | 68 ----------- test/ui/screens/startup_screen_test.dart | 26 ---- test/ui/screens/task_screen_test.dart | 60 ---------- test/ui/screens/tasks_screen_test.dart | 125 -------------------- 5 files changed, 307 deletions(-) delete mode 100644 test/ui/screens/checklist_screen_test.dart delete mode 100644 test/ui/screens/checklists_screen_test.dart delete mode 100644 test/ui/screens/startup_screen_test.dart delete mode 100644 test/ui/screens/task_screen_test.dart delete mode 100644 test/ui/screens/tasks_screen_test.dart diff --git a/test/ui/screens/checklist_screen_test.dart b/test/ui/screens/checklist_screen_test.dart deleted file mode 100644 index 9ec327f..0000000 --- a/test/ui/screens/checklist_screen_test.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:todoapp/ui/components/form_validator.dart'; -import 'package:todoapp/ui/screens/checklist/checklist_screen.dart'; - -import '../../test_utils/fakes/fake_navigator_provider.dart'; -import '../../test_utils/widgets_util.dart'; - -void main() { - testWidgets( - 'ChecklistScreen - Insert a new checklist', - (tester) async { - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: ChecklistScreenScaffold( - onAddNewChecklist: (_) => {}, - formScreenValidator: FormScreenValidator(), - navigatorProvider: FakeNavigatorProvider(), - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - final floatActionButtonFinder = find.byType(FloatingActionButton); - expect(floatActionButtonFinder, findsOneWidget); - }, - ); -} diff --git a/test/ui/screens/checklists_screen_test.dart b/test/ui/screens/checklists_screen_test.dart deleted file mode 100644 index b919ffa..0000000 --- a/test/ui/screens/checklists_screen_test.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:todoapp/data/model/checklist.dart'; -import 'package:todoapp/ui/components/widgets/checklist/checklists_list_widget.dart'; -import 'package:todoapp/ui/screens/checklists/checklists_screen.dart'; -import 'package:todoapp/ui/screens/checklists/checklists_screen_state.dart'; - -import '../../test_utils/fakes/fake_navigator_provider.dart'; -import '../../test_utils/widgets_util.dart'; - -void main() { - testWidgets( - 'ChecklistsScreen - Empty message should appear if we have no checklists', - (tester) async { - tester.view.physicalSize = const Size(500, 800); - - const emptyChecklistMessage = 'No checklists available'; - - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: ChecklistsScaffold( - uiState: const ChecklistsScreenState( - checklists: [], - isLoading: false, - ), - onRemoveChecklist: (_) => {}, - navigatorProvider: FakeNavigatorProvider(), - updateChecklists: () => {}, - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - find.text(emptyChecklistMessage); - - expect(find.text(emptyChecklistMessage), findsOneWidget); - }, - ); - - testWidgets( - 'ChecklistsScreen - Checklist widget should appear if we have checklists', - (tester) async { - tester.view.physicalSize = const Size(500, 800); - - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: ChecklistsScaffold( - uiState: const ChecklistsScreenState( - checklists: [ - Checklist(id: null, title: 'pets'), - Checklist(id: null, title: 'supermarket'), - Checklist(id: null, title: 'drugstore'), - Checklist(id: null, title: 'street market'), - ], - isLoading: false, - ), - onRemoveChecklist: (_) => {}, - navigatorProvider: FakeNavigatorProvider(), - updateChecklists: () => {}, - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - expect(find.byType(ChecklistsListWidget), findsOneWidget); - }, - ); -} diff --git a/test/ui/screens/startup_screen_test.dart b/test/ui/screens/startup_screen_test.dart deleted file mode 100644 index 594a77a..0000000 --- a/test/ui/screens/startup_screen_test.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:todoapp/ui/screens/startup/startup_screen.dart'; - -import '../../test_utils/widgets_util.dart'; - -void main() { - testWidgets( - 'StartupScreen - Loading state', - (tester) async { - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: const StartupContainer( - isLoading: true, - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - expect( - find.byType(CircularProgressIndicator), - findsOneWidget, - ); - }, - ); -} diff --git a/test/ui/screens/task_screen_test.dart b/test/ui/screens/task_screen_test.dart deleted file mode 100644 index 6319c79..0000000 --- a/test/ui/screens/task_screen_test.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:todoapp/ui/components/form_validator.dart'; -import 'package:todoapp/ui/screens/task/task_screen.dart'; - -import '../../test_utils/fakes/fake_navigator_provider.dart'; -import '../../test_utils/widgets_util.dart'; - -void main() { - testWidgets( - 'TaskScreen - Insert a new task', - (tester) async { - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: TaskScreenScaffold( - navigatorProvider: FakeNavigatorProvider(), - addTaskOrUpdate: (p0) { - return Future.value(false); - }, - floatingActionIcon: Icons.plus_one, - formScreenValidator: FormScreenValidator(), - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - expect( - find.byType(FloatingActionButton), - findsOneWidget, - ); - }, - ); - - testWidgets( - 'TaskScreen - Show taskTitle if the user is updating an existing task', - (tester) async { - const existingTaskTitle = 'Buy dog food'; - - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: TaskScreenScaffold( - taskTitle: existingTaskTitle, - navigatorProvider: FakeNavigatorProvider(), - addTaskOrUpdate: (p0) { - return Future.value(false); - }, - floatingActionIcon: Icons.save, - formScreenValidator: FormScreenValidator(), - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - expect( - find.textContaining(existingTaskTitle), - findsOneWidget, - ); - }, - ); -} diff --git a/test/ui/screens/tasks_screen_test.dart b/test/ui/screens/tasks_screen_test.dart deleted file mode 100644 index 645a148..0000000 --- a/test/ui/screens/tasks_screen_test.dart +++ /dev/null @@ -1,125 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:todoapp/ui/components/widgets/progress_widget.dart'; -import 'package:todoapp/ui/screens/tasks/tasks_screen.dart'; - -import '../../test_utils/fakes/fake_callbacks.dart'; -import '../../test_utils/fakes/fake_navigator_provider.dart'; -import '../../test_utils/fakes/fake_states.dart'; -import '../../test_utils/widgets_util.dart'; - -void main() { - testWidgets( - 'TasksScreen - Empty state message should appear if there is no task', - (tester) async { - const emptyMessage = 'No tasks available'; - - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: TasksScaffold( - navigatorProvider: FakeNavigatorProvider(), - uiState: FakeStates.fakeTasksEmptyState, - checklistId: 1, - checklistName: 'Pets', - callbacks: FakeCallbacks.emptyTasksScreenCallbacks, - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - expect(find.text(emptyMessage), findsOneWidget); - }, - ); - - testWidgets( - 'TasksScreen - Progress bar should be blue if it is not 100% completed', - (tester) async { - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: TasksScaffold( - navigatorProvider: FakeNavigatorProvider(), - uiState: FakeStates.fakeTasks50PercentState, - callbacks: FakeCallbacks.emptyTasksScreenCallbacks, - checklistId: 1, - checklistName: 'Pets', - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - ProgressWidget? progressWidget = find - .byType(ProgressWidget) - .evaluate() - .first - .widget as ProgressWidget?; - - expect(progressWidget!.baseColor(), Colors.blueAccent); - }, - ); - - testWidgets( - 'TasksScreen - Progress bar should be green if it is 100% completed', - (tester) async { - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: TasksScaffold( - navigatorProvider: FakeNavigatorProvider(), - uiState: FakeStates.fakeTasks100PercentState, - callbacks: FakeCallbacks.emptyTasksScreenCallbacks, - checklistId: 1, - checklistName: 'pets', - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - ProgressWidget? progressWidget = find - .byType(ProgressWidget) - .evaluate() - .first - .widget as ProgressWidget?; - - expect(progressWidget!.baseColor(), Colors.green); - }, - ); - - testWidgets( - 'TasksScreen - Share option should not appear if it is 100% completed', - (tester) async { - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: TasksScaffold( - navigatorProvider: FakeNavigatorProvider(), - uiState: FakeStates.fakeTasks100PercentState, - callbacks: FakeCallbacks.emptyTasksScreenCallbacks, - checklistId: 1, - checklistName: 'pets', - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - expect(find.byKey(const ValueKey(shareOptionKey)), findsNothing); - }, - ); - - testWidgets( - 'TasksScreen - Share option should appear if it is 50% completed', - (tester) async { - final widget = WidgetsUtil.buildMaterialAppWidgetTest( - child: TasksScaffold( - navigatorProvider: FakeNavigatorProvider(), - uiState: FakeStates.fakeTasks50PercentState, - callbacks: FakeCallbacks.emptyTasksScreenCallbacks, - checklistId: 1, - checklistName: 'pets', - ), - tester: tester, - ); - - await tester.pumpWidget(widget); - - expect(find.byKey(const ValueKey(shareOptionKey)), findsOneWidget); - }, - ); -}