Files
HouseHoldKeaper/test/features/home/data/daily_plan_dao_test.dart
Jean-Luc Makiola 74b3bd5543 test(03-01): add failing tests for DailyPlanDao cross-room query and completion count
- 7 failing tests for watchAllTasksWithRoomName and watchCompletionsToday
- DAO stub with UnimplementedError methods registered in AppDatabase
- TaskWithRoom and DailyPlanState model classes defined

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:28:21 +01:00

168 lines
5.6 KiB
Dart

import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:household_keeper/core/database/database.dart';
import 'package:household_keeper/features/tasks/domain/effort_level.dart';
import 'package:household_keeper/features/tasks/domain/frequency.dart';
void main() {
late AppDatabase db;
late int room1Id;
late int room2Id;
setUp(() async {
db = AppDatabase(NativeDatabase.memory());
room1Id = await db.roomsDao.insertRoom(
RoomsCompanion.insert(name: 'Kueche', iconName: 'kitchen'),
);
room2Id = await db.roomsDao.insertRoom(
RoomsCompanion.insert(name: 'Badezimmer', iconName: 'bathroom'),
);
});
tearDown(() async {
await db.close();
});
group('DailyPlanDao.watchAllTasksWithRoomName', () {
test('returns empty list when no tasks exist', () async {
final result =
await db.dailyPlanDao.watchAllTasksWithRoomName().first;
expect(result, isEmpty);
});
test('returns tasks with correct room name from join', () async {
await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Abspuelen',
intervalType: IntervalType.daily,
effortLevel: EffortLevel.low,
nextDueDate: DateTime(2026, 3, 16),
));
final result =
await db.dailyPlanDao.watchAllTasksWithRoomName().first;
expect(result.length, 1);
expect(result.first.task.name, 'Abspuelen');
expect(result.first.roomName, 'Kueche');
expect(result.first.roomId, room1Id);
});
test('returns tasks sorted by nextDueDate ascending', () async {
await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Later',
intervalType: IntervalType.weekly,
effortLevel: EffortLevel.medium,
nextDueDate: DateTime(2026, 3, 20),
));
await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Earlier',
intervalType: IntervalType.daily,
effortLevel: EffortLevel.low,
nextDueDate: DateTime(2026, 3, 10),
));
await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Middle',
intervalType: IntervalType.biweekly,
effortLevel: EffortLevel.high,
nextDueDate: DateTime(2026, 3, 15),
));
final result =
await db.dailyPlanDao.watchAllTasksWithRoomName().first;
expect(result.length, 3);
expect(result[0].task.name, 'Earlier');
expect(result[1].task.name, 'Middle');
expect(result[2].task.name, 'Later');
});
test('returns tasks from multiple rooms with correct room name pairing',
() async {
await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Kueche Task',
intervalType: IntervalType.daily,
effortLevel: EffortLevel.low,
nextDueDate: DateTime(2026, 3, 16),
));
await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room2Id,
name: 'Bad Task',
intervalType: IntervalType.weekly,
effortLevel: EffortLevel.medium,
nextDueDate: DateTime(2026, 3, 15),
));
final result =
await db.dailyPlanDao.watchAllTasksWithRoomName().first;
expect(result.length, 2);
// Sorted by due date: Bad Task (Mar 15) before Kueche Task (Mar 16)
expect(result[0].task.name, 'Bad Task');
expect(result[0].roomName, 'Badezimmer');
expect(result[0].roomId, room2Id);
expect(result[1].task.name, 'Kueche Task');
expect(result[1].roomName, 'Kueche');
expect(result[1].roomId, room1Id);
});
});
group('DailyPlanDao.watchCompletionsToday', () {
test('returns 0 when no completions exist', () async {
final count = await db.dailyPlanDao
.watchCompletionsToday(today: DateTime(2026, 3, 16))
.first;
expect(count, 0);
});
test('returns correct count of completions recorded today', () async {
final taskId = await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Abspuelen',
intervalType: IntervalType.daily,
effortLevel: EffortLevel.low,
nextDueDate: DateTime(2026, 3, 16),
));
// Complete the task (which records a completion at the given time)
await db.tasksDao.completeTask(taskId, now: DateTime(2026, 3, 16, 10));
// Create another task and complete it today too
final taskId2 = await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Staubsaugen',
intervalType: IntervalType.weekly,
effortLevel: EffortLevel.medium,
nextDueDate: DateTime(2026, 3, 16),
));
await db.tasksDao.completeTask(taskId2, now: DateTime(2026, 3, 16, 14));
final count = await db.dailyPlanDao
.watchCompletionsToday(today: DateTime(2026, 3, 16))
.first;
expect(count, 2);
});
test('does not count completions from yesterday', () async {
final taskId = await db.tasksDao.insertTask(TasksCompanion.insert(
roomId: room1Id,
name: 'Abspuelen',
intervalType: IntervalType.daily,
effortLevel: EffortLevel.low,
nextDueDate: DateTime(2026, 3, 15),
));
// Complete task yesterday
await db.tasksDao.completeTask(taskId, now: DateTime(2026, 3, 15, 18));
// Query for today (March 16) - should not include yesterday's completion
final count = await db.dailyPlanDao
.watchCompletionsToday(today: DateTime(2026, 3, 16))
.first;
expect(count, 0);
});
});
}