125 lines
3.8 KiB
Dart
125 lines
3.8 KiB
Dart
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<int> 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));
|
|
});
|
|
});
|
|
}
|