Implement husband-wife connection dialogue and theme support for learn articles

This commit is contained in:
2026-01-05 17:09:15 -06:00
parent 02d25d0cc7
commit 96655f9a74
36 changed files with 3849 additions and 819 deletions

87
test/prediction_test.dart Normal file
View File

@@ -0,0 +1,87 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:christian_period_tracker/services/cycle_service.dart';
import 'package:christian_period_tracker/models/user_profile.dart';
import 'package:christian_period_tracker/models/cycle_entry.dart';
void main() {
group('CycleService Prediction Tests', () {
final baseDate = DateTime(2024, 1, 1);
final user = UserProfile(
id: '1',
name: 'Test',
role: UserRole.wife,
relationshipStatus: RelationshipStatus.married,
lastPeriodStartDate: baseDate,
averageCycleLength: 28,
averagePeriodLength: 5,
isPadTrackingEnabled: true,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
);
test('predictNextPeriodDays returns correct future dates', () {
final predictions = CycleService.predictNextPeriodDays(user, months: 2);
expect(predictions, isNotNull); // Use it
// Expected:
// Cycle 1: Jan 1 + 28 days = Jan 29.
// Period is 5 days: Jan 29, 30, 31, Feb 1, Feb 2.
// Cycle 2: Jan 29 + 28 days = Feb 26.
// Period is 5 days: Feb 26, 27, 28, 29, Mar 1 (2024 is leap year).
// Note: predictNextPeriodDays checks "if (periodDay.isAfter(DateTime.now()))".
// Since DateTime.now() is 2026 in this environment (per system prompt),
// providing a user with lastPeriodDate in 2024 will generate A LOT of dates until 2026+.
// We should use a recent date relative to "now".
// Let's mock "now" or just use a future date for the user profile.
// But the function checks `isAfter(DateTime.now())`.
// If we use a date in the far future, it won't generate anything if logic is "generate FUTURE from NOW".
// The logic is:
/*
while (currentCycleStart.isBefore(limitDate)) {
// ...
if (periodDay.isAfter(DateTime.now())) {
predictedDays.add(periodDay);
}
// ...
}
*/
// So if I set lastPeriodStart to Today, it should generate next month.
final today = DateTime.now();
final recentUser = user.copyWith(
lastPeriodStartDate: today.subtract(const Duration(days: 28)), // Last period was 28 days ago
);
final futurePredictions = CycleService.predictNextPeriodDays(recentUser, months: 2);
expect(futurePredictions.isNotEmpty, true);
// First predicted day should be roughly today or tomorrow (since cycle is 28 days and last was 28 days ago)
// Actually, if last was 28 days ago, next starts TODAY.
// check logic:
// currentCycleStart = lastPeriodStart (T-28)
// Loop 1: T-28. Adds T-28...T-24. checks if isAfter(now). T-28 is NOT after now.
// Loop 2: T-28 + 28 = T (Today). Adds T...T+4. Checks if isAfter(now).
// T might be after now if time is slightly diff, or exact.
// Let's assume standard behavior.
});
test('getPhaseForDate returns correct phase', () {
// Day 1
expect(CycleService.getPhaseForDate(baseDate, user), CyclePhase.menstrual);
// Day 6 (Period is 5 days) -> Follicular
expect(CycleService.getPhaseForDate(baseDate.add(const Duration(days: 5)), user), CyclePhase.follicular);
// Day 14 -> Ovulation (roughly)
// Logic: <=13 Follicular, <=16 Ovulation
expect(CycleService.getPhaseForDate(baseDate.add(const Duration(days: 13)), user), CyclePhase.ovulation);
// Day 20 -> Luteal
expect(CycleService.getPhaseForDate(baseDate.add(const Duration(days: 19)), user), CyclePhase.luteal);
});
});
}