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:timetrack/features/entries/data/drift_entries_repository.dart'; import 'package:timetrack/features/entries/data/entries_repository.dart'; import 'package:timetrack/features/entries/domain/time_entry.dart'; import 'package:timetrack/features/entries/presentation/entries_screen.dart'; import 'package:timetrack/features/projects/data/drift_projects_repository.dart'; import 'package:timetrack/features/projects/data/projects_repository.dart'; import 'package:timetrack/features/projects/domain/project.dart'; class MockTimeEntriesRepository extends Mock implements TimeEntriesRepository {} class MockProjectsRepository extends Mock implements ProjectsRepository {} TimeEntry makeEntry(int projectId, DateTime start) { final end = start.add(const Duration(hours: 1)); return TimeEntry( id: 0, projectId: projectId, startTime: start, endTime: end, durationSeconds: 3600, tags: const [], createdAt: start, ); } void main() { late MockTimeEntriesRepository mockEntries; late MockProjectsRepository mockProjects; setUp(() { mockEntries = MockTimeEntriesRepository(); mockProjects = MockProjectsRepository(); when(() => mockEntries.watchByDateRange(any(), any())) .thenAnswer((_) => Stream.value([])); when(() => mockProjects.watchAll()) .thenAnswer((_) => Stream.value([])); when(() => mockProjects.watchActive()) .thenAnswer((_) => Stream.value([])); }); Widget buildTestApp() { return ProviderScope( overrides: [ timeEntriesRepositoryProvider.overrideWithValue(mockEntries), projectsRepositoryProvider.overrideWithValue(mockProjects), ], child: const MaterialApp(home: EntriesScreen()), ); } testWidgets('shows empty state when no entries', (tester) async { await tester.pumpWidget(buildTestApp()); await tester.pump(); expect(find.byKey(const Key('entries_empty')), findsOneWidget); }); testWidgets('shows Add Entry button', (tester) async { await tester.pumpWidget(buildTestApp()); await tester.pump(); expect(find.byIcon(Icons.add), findsOneWidget); }); testWidgets('shows date range filter chips', (tester) async { await tester.pumpWidget(buildTestApp()); await tester.pump(); expect(find.text('Today'), findsOneWidget); expect(find.text('This week'), findsOneWidget); expect(find.text('This month'), findsOneWidget); }); testWidgets('renders entry tiles when entries exist', (tester) async { final project = Project( id: 1, name: 'Alpha', colorValue: 0xFF2563EB, createdAt: DateTime(2026), ); when(() => mockProjects.watchAll()) .thenAnswer((_) => Stream.value([project])); final now = DateTime(2026, 7, 12, 10); when(() => mockEntries.watchByDateRange(any(), any())) .thenAnswer((_) => Stream.value([makeEntry(1, now)])); await tester.pumpWidget(buildTestApp()); await tester.pump(); expect(find.byKey(const Key('entry_tile_0')), findsOneWidget); }); }