timetracker/.tasks/done/TT-012-unit-tests.md
2026-08-03 21:51:48 +02:00

3 KiB

TT-012 — Unit Tests

Type: Task
Priority: Medium
Labels: testing, unit-tests
Depends on: TT-004, TT-005
Blocks:


Summary

Write comprehensive unit tests for all repository methods and Riverpod notifiers. See .ai/testing.md for full conventions.

Scope

Database / Repository tests

All tests use NativeDatabase.memory() — never the real file DB.

Test file What to test
test/core/database/app_database_test.dart Schema creation, schemaVersion
test/features/projects/projects_repository_test.dart CRUD, watchActive stream, archive
test/features/entries/entries_repository_test.dart CRUD, watchByDateRange, getActiveEntry
test/features/entries/tags_repository_test.dart findOrCreate, setTagsForEntry
test/features/reports/reports_repository_test.dart getDurationByProject, getDurationByWeekday

Notifier tests

All notifier tests use ProviderContainer with mocked repositories.

Test file What to test
test/features/timer/timer_notifier_test.dart start, stop, discard, restore from open entry
test/features/projects/projects_notifier_test.dart create, update, archive, delete
test/features/entries/entries_notifier_test.dart create, update, delete

Test Patterns

Repository test pattern

late AppDatabase db;
late DriftProjectsRepository repository;

setUp(() {
  db = AppDatabase(NativeDatabase.memory());
  repository = DriftProjectsRepository(db);
});

tearDown(() => db.close());

test('insert and retrieve project', () async {
  await repository.create(name: 'Test', colorValue: 0xFF0000FF);
  final projects = await repository.watchActive().first;
  expect(projects, hasLength(1));
  expect(projects.first.name, equals('Test'));
});

Notifier test pattern

late ProviderContainer container;
late MockProjectsRepository mockRepo;

setUp(() {
  mockRepo = MockProjectsRepository();
  container = ProviderContainer(overrides: [
    projectsRepositoryProvider.overrideWithValue(mockRepo),
  ]);
});

tearDown(container.dispose);

Coverage Goals

Layer Target
Repository (CRUD methods) 100%
Notifiers ≥ 80%
Export service ≥ 70%

Acceptance Criteria

  • All listed test files exist and pass
  • flutter test exits with code 0
  • No test uses the real file database
  • Each repository test covers: insert, read, update, delete, stream emission
  • TimerNotifier test covers: start → running state, stop → idle + entry saved, discard → idle + entry deleted, build with open entry → running state restored
  • flutter test --coverage generates coverage report

Running tests

flutter test                           # all tests
flutter test test/features/timer/     # single feature
flutter test --coverage                # with lcov coverage
genhtml coverage/lcov.info -o coverage/html  # HTML report