Skip to content

Commit 7dcc575

Browse files
committed
binding: Add flutter_local_notifications bindings
1 parent 18ba66d commit 7dcc575

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

lib/model/binding.dart

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:device_info_plus/device_info_plus.dart' as device_info_plus;
22
import 'package:firebase_core/firebase_core.dart' as firebase_core;
33
import 'package:firebase_messaging/firebase_messaging.dart' as firebase_messaging;
44
import 'package:flutter/foundation.dart';
5+
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
56
import 'package:url_launcher/url_launcher.dart' as url_launcher;
67

78
import '../firebase_options.dart';
@@ -98,6 +99,9 @@ abstract class ZulipBinding {
9899

99100
/// Wraps [firebase_messaging.FirebaseMessaging.onMessage].
100101
Stream<firebase_messaging.RemoteMessage> get firebaseMessagingOnMessage;
102+
103+
/// Wraps the [FlutterLocalNotificationsPlugin] singleton constructor.
104+
FlutterLocalNotificationsPlugin get notifications;
101105
}
102106

103107
/// Like [device_info_plus.BaseDeviceInfo], but without things we don't use.
@@ -194,4 +198,7 @@ class LiveZulipBinding extends ZulipBinding {
194198
Stream<firebase_messaging.RemoteMessage> get firebaseMessagingOnMessage {
195199
return firebase_messaging.FirebaseMessaging.onMessage;
196200
}
201+
202+
@override
203+
FlutterLocalNotificationsPlugin get notifications => FlutterLocalNotificationsPlugin();
197204
}

test/model/binding.dart

+105
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import 'dart:async';
22

33
import 'package:firebase_messaging/firebase_messaging.dart';
44
import 'package:flutter/foundation.dart';
5+
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
6+
import 'package:flutter_local_notifications_platform_interface/flutter_local_notifications_platform_interface.dart';
57
import 'package:test/fake.dart';
68
import 'package:url_launcher/url_launcher.dart' as url_launcher;
79
import 'package:zulip/model/binding.dart';
@@ -63,6 +65,7 @@ class TestZulipBinding extends ZulipBinding {
6365
_resetLaunchUrl();
6466
_resetDeviceInfo();
6567
_resetFirebase();
68+
_resetNotifications();
6669
}
6770

6871
/// The current global store offered to a [GlobalStoreWidget].
@@ -188,6 +191,17 @@ class TestZulipBinding extends ZulipBinding {
188191

189192
@override
190193
Stream<RemoteMessage> get firebaseMessagingOnMessage => firebaseMessaging.onMessage.stream;
194+
195+
void _resetNotifications() {
196+
_notificationsPlugin = null;
197+
}
198+
199+
FakeFlutterLocalNotificationsPlugin? _notificationsPlugin;
200+
201+
@override
202+
FakeFlutterLocalNotificationsPlugin get notifications {
203+
return (_notificationsPlugin ??= FakeFlutterLocalNotificationsPlugin());
204+
}
191205
}
192206

193207
class FakeFirebaseMessaging extends Fake implements FirebaseMessaging {
@@ -228,3 +242,94 @@ class FakeFirebaseMessaging extends Fake implements FirebaseMessaging {
228242

229243
StreamController<RemoteMessage> onMessage = StreamController.broadcast();
230244
}
245+
246+
class FakeFlutterLocalNotificationsPlugin extends Fake implements FlutterLocalNotificationsPlugin {
247+
InitializationSettings? initializationSettings;
248+
DidReceiveNotificationResponseCallback? onDidReceiveNotificationResponse;
249+
DidReceiveBackgroundNotificationResponseCallback? onDidReceiveBackgroundNotificationResponse;
250+
251+
@override
252+
Future<bool?> initialize(
253+
InitializationSettings initializationSettings, {
254+
DidReceiveNotificationResponseCallback? onDidReceiveNotificationResponse,
255+
DidReceiveBackgroundNotificationResponseCallback? onDidReceiveBackgroundNotificationResponse,
256+
}) async {
257+
assert(this.initializationSettings == null);
258+
this.initializationSettings = initializationSettings;
259+
this.onDidReceiveNotificationResponse = onDidReceiveNotificationResponse;
260+
this.onDidReceiveBackgroundNotificationResponse = onDidReceiveBackgroundNotificationResponse;
261+
return true;
262+
}
263+
264+
FlutterLocalNotificationsPlatform? _platform;
265+
266+
@override
267+
T? resolvePlatformSpecificImplementation<T extends FlutterLocalNotificationsPlatform>() {
268+
// This follows the logic of the base class's implementation,
269+
// but supplies our fakes for the per-platform classes.
270+
assert(initializationSettings != null);
271+
assert(T != FlutterLocalNotificationsPlatform);
272+
if (kIsWeb) return null;
273+
switch (defaultTargetPlatform) {
274+
case TargetPlatform.android:
275+
assert(_platform == null || _platform is FakeAndroidFlutterLocalNotificationsPlugin);
276+
if (T != AndroidFlutterLocalNotificationsPlugin) return null;
277+
return (_platform ??= FakeAndroidFlutterLocalNotificationsPlugin()) as T?;
278+
279+
case TargetPlatform.iOS:
280+
assert(_platform == null || _platform is FakeIOSFlutterLocalNotificationsPlugin);
281+
if (T != IOSFlutterLocalNotificationsPlugin) return null;
282+
return (_platform ??= FakeIOSFlutterLocalNotificationsPlugin()) as T?;
283+
284+
case TargetPlatform.linux:
285+
case TargetPlatform.macOS:
286+
case TargetPlatform.windows:
287+
case TargetPlatform.fuchsia:
288+
return null;
289+
}
290+
}
291+
292+
/// Consume the log of calls made to [show].
293+
///
294+
/// This returns a list of the arguments to all calls made
295+
/// to [show] since the last call to this method.
296+
List<FlutterLocalNotificationsPluginShowCall> takeShowCalls() {
297+
final result = _showCalls;
298+
_showCalls = [];
299+
return result;
300+
}
301+
List<FlutterLocalNotificationsPluginShowCall> _showCalls = [];
302+
303+
@override
304+
Future<void> show(int id, String? title, String? body,
305+
NotificationDetails? notificationDetails, {String? payload}) async {
306+
assert(initializationSettings != null);
307+
_showCalls.add((id, title, body, notificationDetails, payload: payload));
308+
}
309+
}
310+
311+
typedef FlutterLocalNotificationsPluginShowCall = (
312+
int id, String? title, String? body,
313+
NotificationDetails? notificationDetails, {String? payload}
314+
);
315+
316+
class FakeAndroidFlutterLocalNotificationsPlugin extends Fake implements AndroidFlutterLocalNotificationsPlugin {
317+
/// Consume the log of calls made to [createNotificationChannel].
318+
///
319+
/// This returns a list of the arguments to all calls made
320+
/// to [createNotificationChannel] since the last call to this method.
321+
List<AndroidNotificationChannel> takeCreatedChannels() {
322+
final result = _createdChannels;
323+
_createdChannels = [];
324+
return result;
325+
}
326+
List<AndroidNotificationChannel> _createdChannels = [];
327+
328+
@override
329+
Future<void> createNotificationChannel(AndroidNotificationChannel notificationChannel) async {
330+
_createdChannels.add(notificationChannel);
331+
}
332+
}
333+
334+
class FakeIOSFlutterLocalNotificationsPlugin extends Fake implements IOSFlutterLocalNotificationsPlugin {
335+
}

0 commit comments

Comments
 (0)