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/core/router/router.dart'; import 'package:household_keeper/features/home/domain/daily_plan_models.dart'; import 'package:household_keeper/features/home/presentation/daily_plan_providers.dart'; import 'package:household_keeper/features/rooms/presentation/room_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/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 dailyPlanProvider overridden to the given state. Widget _buildApp(DailyPlanState planState) { return ProviderScope( overrides: [ dailyPlanProvider.overrideWith( (ref) => Stream.value(planState), ), roomWithStatsListProvider.overrideWith( (ref) => Stream.value([]), ), ], child: MaterialApp.router( routerConfig: router, localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: const [Locale('de')], locale: const Locale('de'), ), ); } void main() { setUp(() { SharedPreferences.setMockInitialValues({}); }); group('HomeScreen empty states', () { testWidgets('shows no-tasks empty state when no tasks exist at all', (tester) async { await tester.pumpWidget(_buildApp(const DailyPlanState( overdueTasks: [], todayTasks: [], tomorrowTasks: [], completedTodayCount: 0, totalTodayCount: 0, ))); await tester.pumpAndSettle(); // Should show "Noch keine Aufgaben angelegt" (dailyPlanNoTasks) expect(find.text('Noch keine Aufgaben angelegt'), findsOneWidget); // Should show action button to create a room expect(find.text('Raum erstellen'), findsOneWidget); }); testWidgets('shows all-clear state when all tasks are done', (tester) async { await tester.pumpWidget(_buildApp(const DailyPlanState( overdueTasks: [], todayTasks: [], tomorrowTasks: [], completedTodayCount: 3, totalTodayCount: 3, ))); await tester.pumpAndSettle(); // Should show celebration empty state expect(find.text('Alles erledigt! \u{1F31F}'), findsOneWidget); expect(find.byIcon(Icons.celebration_outlined), findsOneWidget); // Progress card should show 3/3 expect(find.text('3 von 3 erledigt'), findsOneWidget); }); }); group('HomeScreen normal state', () { testWidgets('shows progress card with correct counts', (tester) async { final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); await tester.pumpWidget(_buildApp(DailyPlanState( overdueTasks: [], todayTasks: [ _makeTaskWithRoom( id: 1, taskName: 'Staubsaugen', roomName: 'Wohnzimmer', nextDueDate: today, ), ], tomorrowTasks: [], completedTodayCount: 2, totalTodayCount: 3, ))); await tester.pumpAndSettle(); // Progress card should show 2/3 expect(find.text('2 von 3 erledigt'), findsOneWidget); expect(find.byType(LinearProgressIndicator), findsOneWidget); }); testWidgets('shows overdue section when overdue tasks exist', (tester) async { final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); final yesterday = today.subtract(const Duration(days: 1)); await tester.pumpWidget(_buildApp(DailyPlanState( overdueTasks: [ _makeTaskWithRoom( id: 1, taskName: 'Boden wischen', roomName: 'Kueche', nextDueDate: yesterday, ), ], todayTasks: [ _makeTaskWithRoom( id: 2, taskName: 'Staubsaugen', roomName: 'Wohnzimmer', nextDueDate: today, ), ], tomorrowTasks: [], completedTodayCount: 0, totalTodayCount: 2, ))); await tester.pumpAndSettle(); // Should show overdue section header expect(find.text('\u00dcberf\u00e4llig'), findsOneWidget); // Should show today section header (may also appear as relative date) expect(find.text('Heute'), findsAtLeast(1)); // Should show both tasks expect(find.text('Boden wischen'), findsOneWidget); expect(find.text('Staubsaugen'), findsOneWidget); // Should show room name tags expect(find.text('Kueche'), findsOneWidget); expect(find.text('Wohnzimmer'), findsOneWidget); }); testWidgets('shows collapsed tomorrow section with count', (tester) async { final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); final tomorrow = today.add(const Duration(days: 1)); await tester.pumpWidget(_buildApp(DailyPlanState( overdueTasks: [], todayTasks: [ _makeTaskWithRoom( id: 1, taskName: 'Staubsaugen', roomName: 'Wohnzimmer', nextDueDate: today, ), ], tomorrowTasks: [ _makeTaskWithRoom( id: 2, taskName: 'Fenster putzen', roomName: 'Schlafzimmer', nextDueDate: tomorrow, ), _makeTaskWithRoom( id: 3, taskName: 'Bett beziehen', roomName: 'Schlafzimmer', nextDueDate: tomorrow, ), ], completedTodayCount: 0, totalTodayCount: 1, ))); await tester.pumpAndSettle(); // Should show collapsed tomorrow section with count expect(find.text('Demn\u00e4chst (2)'), findsOneWidget); // Tomorrow tasks should NOT be visible (collapsed by default) expect(find.text('Fenster putzen'), findsNothing); }); testWidgets('today tasks have checkboxes', (tester) async { final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); await tester.pumpWidget(_buildApp(DailyPlanState( overdueTasks: [], todayTasks: [ _makeTaskWithRoom( id: 1, taskName: 'Staubsaugen', roomName: 'Wohnzimmer', nextDueDate: today, ), ], tomorrowTasks: [], completedTodayCount: 0, totalTodayCount: 1, ))); await tester.pumpAndSettle(); // Today task should have a checkbox expect(find.byType(Checkbox), findsOneWidget); }); }); }