feat(04-01): NotificationSettingsNotifier with SharedPreferences persistence and full test suite

- Fix NotificationService API calls to use flutter_local_notifications v21 named parameters
- Expose nextInstanceOf as @visibleForTesting public method for unit testing
- Create NotificationSettingsNotifier with @Riverpod(keepAlive: true)
- NotificationSettings data class with enabled bool + TimeOfDay fields
- Persist notifications_enabled, notifications_hour, notifications_minute to SharedPreferences
- Sync default state in build(), async _load() overrides on hydration
- Update tests to use correct Riverpod 3 provider name (notificationSettingsProvider)
- Add makeContainer() helper to await initial _load() before asserting mutations
- All 84 tests pass (72 existing + 12 new notification tests)
This commit is contained in:
2026-03-16 14:57:04 +01:00
parent 0f6789becd
commit 4f72eac933
4 changed files with 151 additions and 31 deletions

View File

@@ -14,15 +14,14 @@ class NotificationService {
const android = AndroidInitializationSettings('@mipmap/ic_launcher');
const settings = InitializationSettings(android: android);
await _plugin.initialize(
settings,
settings: settings,
onDidReceiveNotificationResponse: _onTap,
);
}
Future<bool> requestPermission() async {
final android = _plugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
final android = _plugin.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
return await android?.requestNotificationsPermission() ?? false;
}
@@ -32,7 +31,7 @@ class NotificationService {
required String body,
}) async {
await _plugin.cancelAll();
final scheduledDate = _nextInstanceOf(time);
final scheduledDate = nextInstanceOf(time);
const details = NotificationDetails(
android: AndroidNotificationDetails(
'daily_summary',
@@ -43,11 +42,11 @@ class NotificationService {
),
);
await _plugin.zonedSchedule(
0,
id: 0,
title: title,
body: body,
scheduledDate: scheduledDate,
details,
notificationDetails: details,
androidScheduleMode: AndroidScheduleMode.inexactAllowWhileIdle,
matchDateTimeComponents: DateTimeComponents.time,
);