import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:todo_app/features/todo/domain/entities/todo.dart'; import 'package:todo_app/features/todo/domain/repositories/todo_repository.dart'; import 'package:todo_app/features/todo/presentation/providers/todo_providers.dart'; import 'package:todo_app/features/todo/presentation/screens/todo_list_screen.dart'; class MockTodoRepository extends Mock implements TodoRepository {} void main() { late MockTodoRepository repository; final testTodo = Todo( id: '1', title: 'Test Todo', priority: 'medium', sortOrder: 0, createdAt: DateTime(2026, 1, 1), updatedAt: DateTime(2026, 1, 1), ); Widget createWidgetUnderTest() { return ProviderScope( overrides: [ todoRepositoryProvider.overrideWithValue(repository), ], child: const MaterialApp( home: TodoListScreen(), ), ); } setUp(() { repository = MockTodoRepository(); }); testWidgets('shows loading indicator initially', (tester) async { when(() => repository.getTodos( priorityFilter: any(named: 'priorityFilter'), completedFilter: any(named: 'completedFilter'), )).thenAnswer((_) async => [testTodo]); await tester.pumpWidget(createWidgetUnderTest()); expect(find.byType(CircularProgressIndicator), findsOneWidget); }); testWidgets('shows todo list when loaded', (tester) async { when(() => repository.getTodos( priorityFilter: any(named: 'priorityFilter'), completedFilter: any(named: 'completedFilter'), )).thenAnswer((_) async => [testTodo]); await tester.pumpWidget(createWidgetUnderTest()); await tester.pumpAndSettle(); expect(find.text('Test Todo'), findsOneWidget); expect(find.text('MEDIUM'), findsOneWidget); }); testWidgets('shows empty state when no todos', (tester) async { when(() => repository.getTodos( priorityFilter: any(named: 'priorityFilter'), completedFilter: any(named: 'completedFilter'), )).thenAnswer((_) async => []); await tester.pumpWidget(createWidgetUnderTest()); await tester.pumpAndSettle(); expect(find.text('No todos yet'), findsOneWidget); expect(find.text('Create Todo'), findsOneWidget); }); testWidgets('shows error state with retry button', (tester) async { when(() => repository.getTodos( priorityFilter: any(named: 'priorityFilter'), completedFilter: any(named: 'completedFilter'), )).thenThrow(Exception('Failed')); await tester.pumpWidget(createWidgetUnderTest()); await tester.pumpAndSettle(); expect(find.text('Something went wrong'), findsOneWidget); expect(find.text('Retry'), findsOneWidget); }); testWidgets('has FAB to create new todo', (tester) async { when(() => repository.getTodos( priorityFilter: any(named: 'priorityFilter'), completedFilter: any(named: 'completedFilter'), )).thenAnswer((_) async => []); await tester.pumpWidget(createWidgetUnderTest()); await tester.pumpAndSettle(); expect(find.byType(FloatingActionButton), findsOneWidget); }); }