98 lines
3.2 KiB
Dart
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);
|
|
});
|
|
}
|