forked from eva/focus-flow
147 lines
4.5 KiB
Dart
147 lines
4.5 KiB
Dart
import 'package:adhd_scheduler_core/scheduler_core.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
void main() {
|
|
group('Repository interfaces', () {
|
|
final createdAt = DateTime(2026, 6, 21, 8);
|
|
final window = SchedulingWindow(
|
|
start: DateTime(2026, 6, 21, 9),
|
|
end: DateTime(2026, 6, 21, 17),
|
|
);
|
|
|
|
test('task repository supports in-memory fakes for domain services',
|
|
() async {
|
|
final backlogTask = task(
|
|
id: 'backlog',
|
|
title: 'Backlog task',
|
|
status: TaskStatus.backlog,
|
|
createdAt: createdAt,
|
|
);
|
|
final scheduledTask = task(
|
|
id: 'scheduled',
|
|
title: 'Scheduled task',
|
|
status: TaskStatus.planned,
|
|
createdAt: createdAt,
|
|
scheduledStart: DateTime(2026, 6, 21, 10),
|
|
scheduledEnd: DateTime(2026, 6, 21, 10, 30),
|
|
);
|
|
final repository = InMemoryTaskRepository([backlogTask]);
|
|
|
|
await repository.save(scheduledTask);
|
|
|
|
expect(await repository.findById('backlog'), same(backlogTask));
|
|
expect(await repository.findByStatus(TaskStatus.backlog), [backlogTask]);
|
|
expect(
|
|
(await repository.findScheduledInWindow(window)).map((task) => task.id),
|
|
['scheduled'],
|
|
);
|
|
});
|
|
|
|
test('project repository stores project profiles by stable id', () async {
|
|
final project = ProjectProfile(
|
|
id: 'home',
|
|
name: 'Home',
|
|
colorKey: 'project-home',
|
|
);
|
|
final repository = InMemoryProjectRepository();
|
|
|
|
await repository.save(project);
|
|
|
|
expect(await repository.findById('home'), same(project));
|
|
expect(await repository.findAll(), [project]);
|
|
});
|
|
|
|
test('locked block repository separates blocks from overrides', () async {
|
|
final block = LockedBlock(
|
|
id: 'work',
|
|
name: 'Work',
|
|
startTime: ClockTime(hour: 9, minute: 0),
|
|
endTime: ClockTime(hour: 17, minute: 0),
|
|
recurrence: LockedBlockRecurrence.weekly(
|
|
weekdays: {LockedWeekday.monday},
|
|
),
|
|
createdAt: createdAt,
|
|
updatedAt: createdAt,
|
|
);
|
|
final override = LockedBlockOverride.remove(
|
|
id: 'holiday',
|
|
lockedBlockId: block.id,
|
|
date: CivilDate(2026, 6, 22),
|
|
createdAt: createdAt,
|
|
);
|
|
final repository = InMemoryLockedBlockRepository();
|
|
|
|
await repository.saveBlock(block);
|
|
await repository.saveOverride(override);
|
|
|
|
expect(await repository.findBlockById('work'), same(block));
|
|
expect(await repository.findOverrideById('holiday'), same(override));
|
|
expect(await repository.findAllBlocks(), [block]);
|
|
expect(await repository.findAllOverrides(), [override]);
|
|
});
|
|
|
|
test('scheduling snapshot repository preserves scheduler input shape',
|
|
() async {
|
|
final scheduledTask = task(
|
|
id: 'scheduled',
|
|
title: 'Scheduled task',
|
|
status: TaskStatus.planned,
|
|
createdAt: createdAt,
|
|
scheduledStart: DateTime(2026, 6, 21, 10),
|
|
scheduledEnd: DateTime(2026, 6, 21, 10, 30),
|
|
);
|
|
final lockedInterval = TimeInterval(
|
|
start: DateTime(2026, 6, 21, 12),
|
|
end: DateTime(2026, 6, 21, 13),
|
|
label: 'Lunch',
|
|
);
|
|
final snapshot = SchedulingStateSnapshot(
|
|
id: 'snapshot-1',
|
|
capturedAt: DateTime(2026, 6, 21, 8, 30),
|
|
window: window,
|
|
tasks: [scheduledTask],
|
|
lockedIntervals: [lockedInterval],
|
|
notices: const [
|
|
SchedulingNotice('Saved schedule'),
|
|
],
|
|
operationName: 'load-day',
|
|
);
|
|
final repository = InMemorySchedulingSnapshotRepository();
|
|
|
|
await repository.save(snapshot);
|
|
|
|
final saved = await repository.findById('snapshot-1');
|
|
expect(saved, same(snapshot));
|
|
expect(saved!.input.tasks, [scheduledTask]);
|
|
expect(saved.input.lockedIntervals, [lockedInterval]);
|
|
expect(saved.result.tasks, [scheduledTask]);
|
|
expect(saved.result.notices.single.message, 'Saved schedule');
|
|
expect(
|
|
(await repository.findInWindow(window)).map((snapshot) => snapshot.id),
|
|
['snapshot-1'],
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
Task task({
|
|
required String id,
|
|
required String title,
|
|
required TaskStatus status,
|
|
required DateTime createdAt,
|
|
DateTime? scheduledStart,
|
|
DateTime? scheduledEnd,
|
|
}) {
|
|
return Task(
|
|
id: id,
|
|
title: title,
|
|
projectId: 'inbox',
|
|
type: TaskType.flexible,
|
|
status: status,
|
|
durationMinutes: 30,
|
|
scheduledStart: scheduledStart,
|
|
scheduledEnd: scheduledEnd,
|
|
createdAt: createdAt,
|
|
updatedAt: createdAt,
|
|
);
|
|
}
|