test(TaskListScreen): add integration tests for filtered and overdue task states
All checks were successful
Build and Release to F-Droid / build-and-deploy (push) Successful in 10m30s
All checks were successful
Build and Release to F-Droid / build-and-deploy (push) Successful in 10m30s
- Covers empty states, celebration state, and scheduled/overdue task rendering - Verifies proper checkbox behavior for future tasks - Tests AppBar for sort dropdown, edit/delete actions, and calendar strip - Adds necessary test helpers and overrides for room-specific tasks
This commit is contained in:
@@ -283,4 +283,267 @@ void main() {
|
||||
expect(result.first.roomId, room2Id);
|
||||
});
|
||||
});
|
||||
|
||||
group('CalendarDao.watchTasksForDateInRoom', () {
|
||||
test('returns empty list when no tasks exist in room', () async {
|
||||
final result = await db.calendarDao
|
||||
.watchTasksForDateInRoom(DateTime(2026, 3, 16), room1Id)
|
||||
.first;
|
||||
expect(result, isEmpty);
|
||||
});
|
||||
|
||||
test('returns only tasks due on the queried date in the specified room',
|
||||
() async {
|
||||
// Task due on March 16 in room1
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Abspuelen',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 16, 9, 30),
|
||||
));
|
||||
// Task due on March 15 in room1 (should NOT appear)
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Staubsaugen',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 15),
|
||||
));
|
||||
// Task due on March 17 in room1 (should NOT appear)
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Fenster putzen',
|
||||
intervalType: IntervalType.monthly,
|
||||
effortLevel: EffortLevel.high,
|
||||
nextDueDate: DateTime(2026, 3, 17),
|
||||
));
|
||||
|
||||
final result = await db.calendarDao
|
||||
.watchTasksForDateInRoom(DateTime(2026, 3, 16), room1Id)
|
||||
.first;
|
||||
expect(result.length, 1);
|
||||
expect(result.first.task.name, 'Abspuelen');
|
||||
});
|
||||
|
||||
test('does not return tasks from other rooms on the same date', () async {
|
||||
// Task due on March 16 in room1
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Kueche Aufgabe',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 16),
|
||||
));
|
||||
// Task due on March 16 in room2 (should NOT appear when querying room1)
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room2Id,
|
||||
name: 'Bad Aufgabe',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 16),
|
||||
));
|
||||
|
||||
final result = await db.calendarDao
|
||||
.watchTasksForDateInRoom(DateTime(2026, 3, 16), room1Id)
|
||||
.first;
|
||||
expect(result.length, 1);
|
||||
expect(result.first.task.name, 'Kueche Aufgabe');
|
||||
expect(result.first.roomId, room1Id);
|
||||
});
|
||||
|
||||
test('returns tasks sorted alphabetically by name', () async {
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Zitrone putzen',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 18),
|
||||
));
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Abspuelen',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 18, 10),
|
||||
));
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Moppen',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 18, 8),
|
||||
));
|
||||
|
||||
final result = await db.calendarDao
|
||||
.watchTasksForDateInRoom(DateTime(2026, 3, 18), room1Id)
|
||||
.first;
|
||||
expect(result.length, 3);
|
||||
expect(result[0].task.name, 'Abspuelen');
|
||||
expect(result[1].task.name, 'Moppen');
|
||||
expect(result[2].task.name, 'Zitrone putzen');
|
||||
});
|
||||
});
|
||||
|
||||
group('CalendarDao.watchOverdueTasksInRoom', () {
|
||||
test('returns empty list when no overdue tasks in room', () async {
|
||||
final result = await db.calendarDao
|
||||
.watchOverdueTasksInRoom(DateTime(2026, 3, 16), room1Id)
|
||||
.first;
|
||||
expect(result, isEmpty);
|
||||
});
|
||||
|
||||
test('returns only overdue tasks in the specified room', () async {
|
||||
// Task due March 15 in room1 — overdue relative to March 16
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Ueberfaelliges Task',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 15),
|
||||
));
|
||||
// Task due March 10 in room1 — also overdue
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Sehr altes Task',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 10),
|
||||
));
|
||||
// Task due on March 16 in room1 — NOT overdue (should NOT appear)
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Heutiges Task',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 16),
|
||||
));
|
||||
|
||||
final result = await db.calendarDao
|
||||
.watchOverdueTasksInRoom(DateTime(2026, 3, 16), room1Id)
|
||||
.first;
|
||||
expect(result.length, 2);
|
||||
});
|
||||
|
||||
test('does not return overdue tasks from other rooms', () async {
|
||||
// Overdue task in room1
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Kueche Overdue',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 14),
|
||||
));
|
||||
// Overdue task in room2 (should NOT appear when querying room1)
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room2Id,
|
||||
name: 'Bad Overdue',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 14),
|
||||
));
|
||||
|
||||
final result = await db.calendarDao
|
||||
.watchOverdueTasksInRoom(DateTime(2026, 3, 16), room1Id)
|
||||
.first;
|
||||
expect(result.length, 1);
|
||||
expect(result.first.task.name, 'Kueche Overdue');
|
||||
expect(result.first.roomId, room1Id);
|
||||
});
|
||||
|
||||
test('returns overdue tasks sorted by nextDueDate ascending', () async {
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Neues Overdue',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 15),
|
||||
));
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Altes Overdue',
|
||||
intervalType: IntervalType.monthly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 1),
|
||||
));
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Mittleres Overdue',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 10),
|
||||
));
|
||||
|
||||
final result = await db.calendarDao
|
||||
.watchOverdueTasksInRoom(DateTime(2026, 3, 16), room1Id)
|
||||
.first;
|
||||
expect(result.length, 3);
|
||||
expect(result[0].task.name, 'Altes Overdue');
|
||||
expect(result[1].task.name, 'Mittleres Overdue');
|
||||
expect(result[2].task.name, 'Neues Overdue');
|
||||
});
|
||||
});
|
||||
|
||||
group('CalendarDao.getTaskCountInRoom', () {
|
||||
test('returns 0 when room has no tasks', () async {
|
||||
final count = await db.calendarDao.getTaskCountInRoom(room1Id);
|
||||
expect(count, 0);
|
||||
});
|
||||
|
||||
test('returns correct count for room', () async {
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Aufgabe 1',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 16),
|
||||
));
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Aufgabe 2',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 20),
|
||||
));
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Aufgabe 3',
|
||||
intervalType: IntervalType.monthly,
|
||||
effortLevel: EffortLevel.high,
|
||||
nextDueDate: DateTime(2026, 3, 25),
|
||||
));
|
||||
|
||||
final count = await db.calendarDao.getTaskCountInRoom(room1Id);
|
||||
expect(count, 3);
|
||||
});
|
||||
|
||||
test('does not count tasks from other rooms', () async {
|
||||
// Two tasks in room1
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Kueche Aufgabe 1',
|
||||
intervalType: IntervalType.daily,
|
||||
effortLevel: EffortLevel.low,
|
||||
nextDueDate: DateTime(2026, 3, 16),
|
||||
));
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room1Id,
|
||||
name: 'Kueche Aufgabe 2',
|
||||
intervalType: IntervalType.weekly,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: DateTime(2026, 3, 20),
|
||||
));
|
||||
// One task in room2 (should NOT be counted for room1)
|
||||
await db.tasksDao.insertTask(TasksCompanion.insert(
|
||||
roomId: room2Id,
|
||||
name: 'Bad Aufgabe',
|
||||
intervalType: IntervalType.monthly,
|
||||
effortLevel: EffortLevel.high,
|
||||
nextDueDate: DateTime(2026, 3, 18),
|
||||
));
|
||||
|
||||
final count = await db.calendarDao.getTaskCountInRoom(room1Id);
|
||||
expect(count, 2);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
325
test/features/tasks/presentation/task_list_screen_test.dart
Normal file
325
test/features/tasks/presentation/task_list_screen_test.dart
Normal file
@@ -0,0 +1,325 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'package:household_keeper/core/database/database.dart';
|
||||
import 'package:household_keeper/features/home/domain/calendar_models.dart';
|
||||
import 'package:household_keeper/features/home/domain/daily_plan_models.dart';
|
||||
import 'package:household_keeper/features/home/presentation/calendar_providers.dart';
|
||||
import 'package:household_keeper/features/tasks/domain/effort_level.dart';
|
||||
import 'package:household_keeper/features/tasks/domain/frequency.dart';
|
||||
import 'package:household_keeper/features/tasks/domain/task_sort_option.dart';
|
||||
import 'package:household_keeper/features/tasks/presentation/sort_preference_notifier.dart';
|
||||
import 'package:household_keeper/features/tasks/presentation/task_list_screen.dart';
|
||||
import 'package:household_keeper/l10n/app_localizations.dart';
|
||||
|
||||
/// Helper to create a test [Task] with sensible defaults.
|
||||
Task _makeTask({
|
||||
int id = 1,
|
||||
int roomId = 1,
|
||||
String name = 'Test Task',
|
||||
required DateTime nextDueDate,
|
||||
}) {
|
||||
return Task(
|
||||
id: id,
|
||||
roomId: roomId,
|
||||
name: name,
|
||||
intervalType: IntervalType.weekly,
|
||||
intervalDays: 7,
|
||||
effortLevel: EffortLevel.medium,
|
||||
nextDueDate: nextDueDate,
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
}
|
||||
|
||||
/// Helper to create a [TaskWithRoom].
|
||||
TaskWithRoom _makeTaskWithRoom({
|
||||
int id = 1,
|
||||
int roomId = 1,
|
||||
String taskName = 'Test Task',
|
||||
String roomName = 'Kueche',
|
||||
required DateTime nextDueDate,
|
||||
}) {
|
||||
return TaskWithRoom(
|
||||
task: _makeTask(
|
||||
id: id,
|
||||
roomId: roomId,
|
||||
name: taskName,
|
||||
nextDueDate: nextDueDate,
|
||||
),
|
||||
roomName: roomName,
|
||||
roomId: roomId,
|
||||
);
|
||||
}
|
||||
|
||||
/// Build the app with [roomCalendarDayProvider] overridden to the given state.
|
||||
///
|
||||
/// Uses [UncontrolledProviderScope] with a [ProviderContainer] to avoid
|
||||
/// the riverpod_lint scoped_providers_should_specify_dependencies warning.
|
||||
///
|
||||
/// Renders [TaskListScreen] directly with roomId 1, wrapped in a [MaterialApp]
|
||||
/// to avoid router complexity. The _RoomTitle widget will show '...' because
|
||||
/// appDatabaseProvider is not overridden — this is acceptable for these tests.
|
||||
Widget _buildApp(CalendarDayState dayState) {
|
||||
final container = ProviderContainer(overrides: [
|
||||
roomCalendarDayProvider.overrideWith(
|
||||
(ref, roomId) => Stream.value(dayState),
|
||||
),
|
||||
selectedDateProvider.overrideWith(SelectedDateNotifier.new),
|
||||
sortPreferenceProvider.overrideWith(SortPreferenceNotifier.new),
|
||||
]);
|
||||
|
||||
return UncontrolledProviderScope(
|
||||
container: container,
|
||||
child: const MaterialApp(
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: [Locale('de')],
|
||||
locale: Locale('de'),
|
||||
home: TaskListScreen(roomId: 1),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
final now = DateTime.now();
|
||||
final today = DateTime(now.year, now.month, now.day);
|
||||
final yesterday = today.subtract(const Duration(days: 1));
|
||||
|
||||
group('TaskListScreen empty states', () {
|
||||
testWidgets('shows no-tasks empty state when no tasks exist in room',
|
||||
(tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: const [],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 0,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Should show "Noch keine Aufgaben" (taskEmptyTitle)
|
||||
expect(find.text('Noch keine Aufgaben'), findsOneWidget);
|
||||
// Should show action button to create a task
|
||||
expect(find.text('Aufgabe erstellen'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('shows celebration state when tasks exist but today is clear',
|
||||
(tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: const [],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 5, // tasks exist elsewhere
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Should show celebration state
|
||||
expect(find.byIcon(Icons.celebration_outlined), findsOneWidget);
|
||||
expect(find.text('Alles erledigt! \u{1F31F}'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('shows empty-day state for non-today date with no tasks',
|
||||
(tester) async {
|
||||
final tomorrow = today.add(const Duration(days: 1));
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: tomorrow,
|
||||
dayTasks: const [],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 5, // tasks exist on other days
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Should show "Keine Aufgaben" (not celebration — not today)
|
||||
expect(find.text('Keine Aufgaben'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.event_available), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group('TaskListScreen normal state', () {
|
||||
testWidgets('shows overdue section when overdue tasks exist (today)',
|
||||
(tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: [
|
||||
_makeTaskWithRoom(
|
||||
id: 2,
|
||||
taskName: 'Staubsaugen',
|
||||
roomName: 'Wohnzimmer',
|
||||
nextDueDate: today,
|
||||
),
|
||||
],
|
||||
overdueTasks: [
|
||||
_makeTaskWithRoom(
|
||||
id: 1,
|
||||
taskName: 'Boden wischen',
|
||||
roomName: 'Kueche',
|
||||
nextDueDate: yesterday,
|
||||
),
|
||||
],
|
||||
totalTaskCount: 2,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Should show overdue section header
|
||||
expect(find.text('\u00dcberf\u00e4llig'), findsOneWidget);
|
||||
// Should show both tasks
|
||||
expect(find.text('Boden wischen'), findsOneWidget);
|
||||
expect(find.text('Staubsaugen'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('does not show overdue section for non-today date',
|
||||
(tester) async {
|
||||
final tomorrow = today.add(const Duration(days: 1));
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: tomorrow,
|
||||
dayTasks: [
|
||||
_makeTaskWithRoom(
|
||||
id: 1,
|
||||
taskName: 'Staubsaugen',
|
||||
roomName: 'Wohnzimmer',
|
||||
nextDueDate: tomorrow,
|
||||
),
|
||||
],
|
||||
overdueTasks: const [], // No overdue for non-today
|
||||
totalTaskCount: 1,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Should NOT show overdue section header
|
||||
expect(find.text('\u00dcberf\u00e4llig'), findsNothing);
|
||||
// Should show day task
|
||||
expect(find.text('Staubsaugen'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('tasks have checkboxes', (tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: [
|
||||
_makeTaskWithRoom(
|
||||
id: 1,
|
||||
taskName: 'Staubsaugen',
|
||||
roomName: 'Wohnzimmer',
|
||||
nextDueDate: today,
|
||||
),
|
||||
],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 1,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Task should have a checkbox
|
||||
expect(find.byType(Checkbox), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('room tag is NOT shown on task rows', (tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: [
|
||||
_makeTaskWithRoom(
|
||||
id: 1,
|
||||
taskName: 'Staubsaugen',
|
||||
roomName: 'Kueche',
|
||||
nextDueDate: today,
|
||||
),
|
||||
],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 1,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Task name should be visible
|
||||
expect(find.text('Staubsaugen'), findsOneWidget);
|
||||
// Room tag text should NOT appear (showRoomTag is false in room context)
|
||||
expect(find.text('Kueche'), findsNothing);
|
||||
});
|
||||
});
|
||||
|
||||
group('TaskListScreen future task restriction', () {
|
||||
testWidgets('checkboxes are disabled for future tasks', (tester) async {
|
||||
final futureDate = today.add(const Duration(days: 3));
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: futureDate,
|
||||
dayTasks: [
|
||||
_makeTaskWithRoom(
|
||||
id: 1,
|
||||
taskName: 'Fenster putzen',
|
||||
roomName: 'Kueche',
|
||||
nextDueDate: futureDate,
|
||||
),
|
||||
],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 1,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Task should be visible
|
||||
expect(find.text('Fenster putzen'), findsOneWidget);
|
||||
|
||||
// Checkbox should exist but be disabled (onChanged is null)
|
||||
final checkbox = tester.widget<Checkbox>(find.byType(Checkbox));
|
||||
expect(checkbox.onChanged, isNull);
|
||||
});
|
||||
});
|
||||
|
||||
group('TaskListScreen AppBar', () {
|
||||
testWidgets('shows sort dropdown in AppBar', (tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: const [],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 0,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// SortDropdown wraps a PopupMenuButton<TaskSortOption>
|
||||
expect(
|
||||
find.byType(PopupMenuButton<TaskSortOption>),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('shows edit and delete icon buttons', (tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: const [],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 0,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// Edit icon button
|
||||
expect(find.byIcon(Icons.edit), findsOneWidget);
|
||||
// Delete icon button
|
||||
expect(find.byIcon(Icons.delete), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('calendar strip is shown', (tester) async {
|
||||
await tester.pumpWidget(_buildApp(CalendarDayState(
|
||||
selectedDate: today,
|
||||
dayTasks: const [],
|
||||
overdueTasks: const [],
|
||||
totalTaskCount: 0,
|
||||
)));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
// The strip is a horizontal ListView — verify it exists by finding
|
||||
// ListView widgets (strip + potentially the task list).
|
||||
expect(find.byType(ListView), findsWidgets);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user