import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:timezone/data/latest_all.dart' as tz; import 'package:timezone/timezone.dart' as tz; import 'package:household_keeper/core/notifications/notification_service.dart'; void main() { setUpAll(() { tz.initializeTimeZones(); tz.setLocalLocation(tz.getLocation('Europe/Berlin')); }); group('NotificationService', () { test('singleton pattern: two instances are identical', () { final a = NotificationService(); final b = NotificationService(); expect(identical(a, b), isTrue); }); group('nextInstanceOf', () { test('returns today when time is in the future', () { final service = NotificationService(); final now = tz.TZDateTime.now(tz.local); // Use a time 2 hours in the future, wrapping midnight if needed final futureHour = (now.hour + 2) % 24; final futureMinute = now.minute; final futureTime = TimeOfDay(hour: futureHour, minute: futureMinute); // Only test this case if futureHour > now.hour (no midnight wrap) if (futureHour > now.hour) { final result = service.nextInstanceOf(futureTime); expect(result.day, now.day); expect(result.hour, futureHour); expect(result.minute, futureMinute); } }); test('returns tomorrow when time has passed', () { final service = NotificationService(); final now = tz.TZDateTime.now(tz.local); // Use a time in the past (1 hour ago), wrapping to previous day if needed final pastHour = now.hour - 1; // Only test if we are not at the beginning of the day if (pastHour >= 0) { final pastTime = TimeOfDay(hour: pastHour, minute: 0); final result = service.nextInstanceOf(pastTime); expect(result.day, now.day + 1); expect(result.hour, pastHour); expect(result.minute, 0); } }); test('scheduled time is in the future (always)', () { final service = NotificationService(); final now = tz.TZDateTime.now(tz.local); // Test with midnight (00:00) — always results in a time in future (tomorrow) final result = service.nextInstanceOf(const TimeOfDay(hour: 0, minute: 0)); expect(result.isAfter(now) || result.isAtSameMomentAs(now), isTrue); }); test('nextInstanceOf respects hours and minutes exactly', () { final service = NotificationService(); final now = tz.TZDateTime.now(tz.local); // Use a far future time today: 23:59, which should be today if we are before it const targetTime = TimeOfDay(hour: 23, minute: 59); final todayTarget = tz.TZDateTime( tz.local, now.year, now.month, now.day, 23, 59, ); final result = service.nextInstanceOf(targetTime); if (now.isBefore(todayTarget)) { expect(result.hour, 23); expect(result.minute, 59); expect(result.day, now.day); } else { // After 23:59, scheduled for tomorrow expect(result.hour, 23); expect(result.minute, 59); expect(result.day, now.day + 1); } }); }); }); }