import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:timetrack/core/database/app_database.dart' as db; import 'package:timetrack/features/entries/data/drift_entries_repository.dart'; import 'package:timetrack/features/entries/domain/time_entry.dart'; import 'package:timetrack/features/projects/data/drift_projects_repository.dart'; import '../../helpers/sqlite_test_helper.dart'; TimeEntry makeEntry(int projectId, DateTime start, {DateTime? endTime, bool openEntry = false}) { if (openEntry) { return TimeEntry( id: 0, projectId: projectId, startTime: start, tags: const [], createdAt: start, ); } final end = endTime ?? start.add(const Duration(hours: 1)); return TimeEntry( id: 0, projectId: projectId, startTime: start, endTime: end, durationSeconds: end.difference(start).inSeconds, tags: const [], createdAt: start, ); } void main() { setUpAll(configureSqliteForTests); late db.AppDatabase database; late DriftProjectsRepository projectsRepo; late DriftTimeEntriesRepository entriesRepo; setUp(() { database = db.AppDatabase(NativeDatabase.memory()); projectsRepo = DriftProjectsRepository(database); entriesRepo = DriftTimeEntriesRepository(database); }); tearDown(() => database.close()); group('TimeEntriesRepository', () { Future createProject() => projectsRepo.create(name: 'Test', colorValue: 0xFF2563EB); test('create and watchAll', () async { final pid = await createProject(); final now = DateTime.now(); await entriesRepo.create(makeEntry(pid, now)); final entries = await entriesRepo.watchAll().first; expect(entries, hasLength(1)); expect(entries.first.projectId, equals(pid)); }); test('getActiveEntry returns open entry', () async { final pid = await createProject(); final now = DateTime.now(); await entriesRepo.create(makeEntry(pid, now, openEntry: true)); final active = await entriesRepo.getActiveEntry(); expect(active, isNotNull); expect(active!.endTime, isNull); }); test('getActiveEntry returns null when all entries complete', () async { final pid = await createProject(); final now = DateTime.now(); await entriesRepo.create( makeEntry(pid, now, endTime: now.add(const Duration(hours: 1))), ); final active = await entriesRepo.getActiveEntry(); expect(active, isNull); }); test('update modifies entry note', () async { final pid = await createProject(); final now = DateTime.now(); await entriesRepo.create(makeEntry(pid, now)); final created = (await entriesRepo.watchAll().first).first; await entriesRepo.update(created.copyWith(note: 'Updated note')); final updated = (await entriesRepo.watchAll().first).first; expect(updated.note, equals('Updated note')); }); test('delete removes entry', () async { final pid = await createProject(); final now = DateTime.now(); final id = await entriesRepo.create(makeEntry(pid, now)); await entriesRepo.delete(id); final entries = await entriesRepo.watchAll().first; expect(entries, isEmpty); }); test('watchByDateRange filters correctly', () async { final pid = await createProject(); final base = DateTime(2026, 6, 15); await entriesRepo.create( makeEntry(pid, base, endTime: base.add(const Duration(hours: 1))), ); await entriesRepo.create( makeEntry( pid, base.add(const Duration(days: 10)), endTime: base.add(const Duration(days: 10, hours: 1)), ), ); final inRange = await entriesRepo .watchByDateRange(DateTime(2026, 6, 14), DateTime(2026, 6, 16)) .first; expect(inRange, hasLength(1)); }); }); }