165 lines
5.9 KiB
Dart
165 lines
5.9 KiB
Dart
import 'package:adhd_scheduler_core/scheduler_core.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
void main() {
|
|
group('MongoDB document mapping helpers', () {
|
|
final createdAt = DateTime.utc(2026, 6, 23, 8);
|
|
|
|
test('task documents round-trip every scheduling field', () {
|
|
final task = scheduledTask(
|
|
id: 'task-1',
|
|
createdAt: createdAt,
|
|
reward: RewardLevel.high,
|
|
difficulty: DifficultyLevel.hard,
|
|
).copyWith(
|
|
stats: const TaskStatistics().incrementManualPush(),
|
|
);
|
|
|
|
final document = task.toDocument();
|
|
final restored = TaskDocumentMapping.fromDocument(document);
|
|
|
|
expect(document[TaskDocumentFields.id], task.id);
|
|
expect(document[TaskDocumentFields.type], 'flexible');
|
|
expect(document[TaskDocumentFields.status], 'planned');
|
|
expect(document[TaskDocumentFields.reward], 'high');
|
|
expect(document[TaskDocumentFields.difficulty], 'hard');
|
|
expect(document[TaskDocumentFields.scheduledStart],
|
|
'2026-06-23T09:00:00.000Z');
|
|
expect(restored.id, task.id);
|
|
expect(restored.title, task.title);
|
|
expect(restored.projectId, task.projectId);
|
|
expect(restored.type, task.type);
|
|
expect(restored.status, task.status);
|
|
expect(restored.priority, task.priority);
|
|
expect(restored.reward, task.reward);
|
|
expect(restored.difficulty, task.difficulty);
|
|
expect(restored.durationMinutes, task.durationMinutes);
|
|
expect(restored.scheduledStart, task.scheduledStart);
|
|
expect(restored.scheduledEnd, task.scheduledEnd);
|
|
expect(restored.actualStart, task.actualStart);
|
|
expect(restored.actualEnd, task.actualEnd);
|
|
expect(restored.completedAt, task.completedAt);
|
|
expect(restored.parentTaskId, task.parentTaskId);
|
|
expect(restored.backlogTags, task.backlogTags);
|
|
expect(restored.reminderOverride, task.reminderOverride);
|
|
expect(restored.createdAt, task.createdAt);
|
|
expect(restored.updatedAt, task.updatedAt);
|
|
expect(restored.stats.manuallyPushedCount, 1);
|
|
});
|
|
|
|
test('task documents preserve not-set reward distinctly from very low', () {
|
|
final noReward = scheduledTask(
|
|
id: 'no-reward',
|
|
createdAt: createdAt,
|
|
reward: RewardLevel.notSet,
|
|
);
|
|
final veryLowReward = scheduledTask(
|
|
id: 'very-low',
|
|
createdAt: createdAt,
|
|
reward: RewardLevel.veryLow,
|
|
);
|
|
|
|
final noRewardDocument = noReward.toDocument();
|
|
final veryLowRewardDocument = veryLowReward.toDocument();
|
|
|
|
expect(noRewardDocument[TaskDocumentFields.reward], 'notSet');
|
|
expect(veryLowRewardDocument[TaskDocumentFields.reward], 'veryLow');
|
|
expect(
|
|
TaskDocumentMapping.fromDocument(noRewardDocument).reward,
|
|
RewardLevel.notSet,
|
|
);
|
|
expect(
|
|
TaskDocumentMapping.fromDocument(veryLowRewardDocument).reward,
|
|
RewardLevel.veryLow,
|
|
);
|
|
});
|
|
|
|
test('task documents support explicit nullable schedule clearing', () {
|
|
final task = scheduledTask(
|
|
id: 'scheduled',
|
|
createdAt: createdAt,
|
|
);
|
|
|
|
final clearedDocument = task.toDocument(clearSchedule: true);
|
|
final restored = TaskDocumentMapping.fromDocument(clearedDocument);
|
|
|
|
expect(clearedDocument[TaskDocumentFields.scheduledStart], isNull);
|
|
expect(clearedDocument[TaskDocumentFields.scheduledEnd], isNull);
|
|
expect(restored.scheduledStart, isNull);
|
|
expect(restored.scheduledEnd, isNull);
|
|
expect(restored.id, task.id);
|
|
});
|
|
|
|
test('task statistics document mapping preserves every counter', () {
|
|
const stats = TaskStatistics(
|
|
skippedDuringBurnoutCount: 1,
|
|
manuallyPushedCount: 2,
|
|
autoPushedCount: 3,
|
|
movedToBacklogCount: 4,
|
|
restoredFromBacklogCount: 5,
|
|
missedCount: 6,
|
|
cancelledCount: 7,
|
|
completedLateCount: 8,
|
|
completedDuringLockedHoursCount: 9,
|
|
completedDuringLockedHoursMinutes: 10,
|
|
completedAfterShieldCount: 11,
|
|
completedAfterPushCount: 12,
|
|
totalPushesBeforeCompletion: 13,
|
|
);
|
|
|
|
final document = stats.toDocument();
|
|
final restored = TaskStatisticsDocumentMapping.fromDocument(document);
|
|
|
|
expect(document.keys.toSet(), TaskStatisticsDocumentFields.all);
|
|
expect(restored.skippedDuringBurnoutCount, 1);
|
|
expect(restored.manuallyPushedCount, 2);
|
|
expect(restored.autoPushedCount, 3);
|
|
expect(restored.movedToBacklogCount, 4);
|
|
expect(restored.restoredFromBacklogCount, 5);
|
|
expect(restored.missedCount, 6);
|
|
expect(restored.cancelledCount, 7);
|
|
expect(restored.completedLateCount, 8);
|
|
expect(restored.completedDuringLockedHoursCount, 9);
|
|
expect(restored.completedDuringLockedHoursMinutes, 10);
|
|
expect(restored.completedAfterShieldCount, 11);
|
|
expect(restored.completedAfterPushCount, 12);
|
|
expect(restored.totalPushesBeforeCompletion, 13);
|
|
});
|
|
|
|
test('enum document mapping rejects unknown persistence names', () {
|
|
expect(
|
|
() => PersistenceEnumMapping.decodeTaskType('unknown'),
|
|
throwsArgumentError,
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
Task scheduledTask({
|
|
required String id,
|
|
required DateTime createdAt,
|
|
RewardLevel reward = RewardLevel.notSet,
|
|
DifficultyLevel difficulty = DifficultyLevel.medium,
|
|
}) {
|
|
return Task(
|
|
id: id,
|
|
title: 'Scheduled task',
|
|
projectId: 'project-1',
|
|
type: TaskType.flexible,
|
|
status: TaskStatus.planned,
|
|
priority: PriorityLevel.medium,
|
|
reward: reward,
|
|
difficulty: difficulty,
|
|
durationMinutes: 30,
|
|
scheduledStart: DateTime.utc(2026, 6, 23, 9),
|
|
scheduledEnd: DateTime.utc(2026, 6, 23, 9, 30),
|
|
actualStart: DateTime.utc(2026, 6, 23, 9, 5),
|
|
actualEnd: DateTime.utc(2026, 6, 23, 9, 25),
|
|
completedAt: DateTime.utc(2026, 6, 23, 9, 30),
|
|
parentTaskId: 'parent-1',
|
|
backlogTags: const {BacklogTag.wishlist},
|
|
reminderOverride: ReminderProfile.persistent,
|
|
createdAt: createdAt,
|
|
updatedAt: createdAt.add(const Duration(minutes: 5)),
|
|
);
|
|
}
|