timetracker/test/features/entries/entries_screen_test.dart
2026-08-03 21:51:48 +02:00

98 lines
3.2 KiB
Dart

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);
});
}