Skip to content

Commit d474603

Browse files
committed
improve coverage of notification
1 parent 0c1ebb9 commit d474603

File tree

3 files changed

+213
-10
lines changed

3 files changed

+213
-10
lines changed

lib/src/notification.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import 'package:onesignal_flutter/src/utils.dart';
2-
import 'package:onesignal_flutter/onesignal_flutter.dart';
31
import 'dart:convert';
42

3+
import 'package:onesignal_flutter/onesignal_flutter.dart';
4+
import 'package:onesignal_flutter/src/utils.dart';
5+
56
/// A class representing the notification, including the
67
/// payload of the notification as well as additional
78
/// parameters (such as whether the notification was `shown`

test/mock_channel.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class OneSignalMockChannelController {
1818
const MethodChannel('OneSignal#inappmessages');
1919
final MethodChannel _liveActivitiesChannel =
2020
const MethodChannel('OneSignal#liveactivities');
21+
final MethodChannel _notificationsChannel =
22+
const MethodChannel('OneSignal#notifications');
2123

2224
late OneSignalState state;
2325

@@ -34,6 +36,8 @@ class OneSignalMockChannelController {
3436
.setMockMethodCallHandler(_inAppMessagesChannel, _handleMethod);
3537
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
3638
.setMockMethodCallHandler(_liveActivitiesChannel, _handleMethod);
39+
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
40+
.setMockMethodCallHandler(_notificationsChannel, _handleMethod);
3741
}
3842

3943
void resetState() {
@@ -159,6 +163,16 @@ class OneSignalMockChannelController {
159163
case "OneSignal#lifecycleInit":
160164
state.lifecycleInitCalled = true;
161165
break;
166+
case "OneSignal#displayNotification":
167+
// This is called on OneSignal#notifications channel
168+
state.displayedNotificationId = (call.arguments
169+
as Map<dynamic, dynamic>)['notificationId'] as String?;
170+
break;
171+
case "OneSignal#preventDefault":
172+
// This is called on OneSignal#notifications channel
173+
state.preventedNotificationId = (call.arguments
174+
as Map<dynamic, dynamic>)['notificationId'] as String?;
175+
break;
162176
}
163177
}
164178
}
@@ -217,6 +231,8 @@ class OneSignalState {
217231

218232
// notifications
219233
Map<dynamic, dynamic>? postNotificationJson;
234+
String? displayedNotificationId;
235+
String? preventedNotificationId;
220236

221237
/*
222238
All of the following functions parse the MethodCall

test/notification_test.dart

Lines changed: 194 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import 'package:flutter_test/flutter_test.dart';
2+
import 'package:onesignal_flutter/onesignal_flutter.dart';
23
import 'package:onesignal_flutter/src/notification.dart';
34

5+
import 'mock_channel.dart';
6+
47
const validNotificationJson = {
58
'notificationId': 'notification-123',
69
'title': 'Test Title',
@@ -144,6 +147,44 @@ void main() {
144147
expect(notification.backgroundImageLayout!.bodyTextColor, '#FF666666');
145148
});
146149

150+
test('parses grouped notifications correctly', () {
151+
final groupedNotificationsJson = '''[
152+
{"notificationId": "grouped-1", "title": "Title 1", "body": "Body 1"},
153+
{"notificationId": "grouped-2", "title": "Title 2", "body": "Body 2"},
154+
{"notificationId": "grouped-3", "title": "Title 3", "body": "Body 3"}
155+
]''';
156+
157+
final json = {
158+
'notificationId': 'parent-notification',
159+
'title': 'Parent Title',
160+
'body': 'Parent Body',
161+
'groupedNotifications': groupedNotificationsJson,
162+
};
163+
final notification = OSNotification(json);
164+
165+
expect(notification.groupedNotifications, isNotNull);
166+
expect(notification.groupedNotifications!.length, 3);
167+
expect(notification.groupedNotifications![0].notificationId, 'grouped-1');
168+
expect(notification.groupedNotifications![0].title, 'Title 1');
169+
expect(notification.groupedNotifications![1].notificationId, 'grouped-2');
170+
expect(notification.groupedNotifications![1].body, 'Body 2');
171+
expect(notification.groupedNotifications![2].notificationId, 'grouped-3');
172+
expect(notification.groupedNotifications![2].title, 'Title 3');
173+
});
174+
175+
test('creates with empty grouped notifications', () {
176+
final groupedNotificationsJson = '[]';
177+
178+
final json = {
179+
'notificationId': 'notification-with-empty-group',
180+
'groupedNotifications': groupedNotificationsJson,
181+
};
182+
final notification = OSNotification(json);
183+
184+
expect(notification.groupedNotifications, isNotNull);
185+
expect(notification.groupedNotifications!.length, 0);
186+
});
187+
147188
test('jsonRepresentation returns correct JSON string', () {
148189
final notification = OSNotification(validNotificationJson);
149190
final jsonRep = notification.jsonRepresentation();
@@ -276,14 +317,6 @@ void main() {
276317
expect(layout.bodyTextColor, '#FF666666');
277318
});
278319

279-
test('creates from JSON with missing fields', () {
280-
final layout = OSAndroidBackgroundImageLayout({'image': 'bg.png'});
281-
282-
expect(layout.image, 'bg.png');
283-
expect(layout.titleTextColor, isNull);
284-
expect(layout.bodyTextColor, isNull);
285-
});
286-
287320
test('creates from empty JSON', () {
288321
final layout = OSAndroidBackgroundImageLayout({});
289322

@@ -395,4 +428,157 @@ void main() {
395428
expect(jsonRep, contains('https://example.com/action'));
396429
});
397430
});
431+
432+
group('OSDisplayNotification extension', () {
433+
late OneSignalMockChannelController channelController;
434+
435+
setUp(() {
436+
TestWidgetsFlutterBinding.ensureInitialized();
437+
channelController = OneSignalMockChannelController();
438+
channelController.resetState();
439+
});
440+
441+
test('display() calls displayNotification with correct notification ID',
442+
() {
443+
final notification = OSNotification(validNotificationJson);
444+
445+
notification.display();
446+
447+
expect(
448+
channelController.state.displayedNotificationId, 'notification-123');
449+
});
450+
451+
test('display() works with different notification IDs', () {
452+
final json = {'notificationId': 'custom-notification-id'};
453+
final notification = OSNotification(json);
454+
455+
notification.display();
456+
457+
expect(channelController.state.displayedNotificationId,
458+
'custom-notification-id');
459+
});
460+
461+
test('multiple display() calls update the displayed notification ID', () {
462+
final notification1 = OSNotification({'notificationId': 'first-id'});
463+
final notification2 = OSNotification({'notificationId': 'second-id'});
464+
465+
notification1.display();
466+
expect(channelController.state.displayedNotificationId, 'first-id');
467+
468+
notification2.display();
469+
expect(channelController.state.displayedNotificationId, 'second-id');
470+
});
471+
});
472+
473+
group('OSNotificationWillDisplayEvent preventDefault', () {
474+
late OneSignalMockChannelController channelController;
475+
476+
setUp(() {
477+
TestWidgetsFlutterBinding.ensureInitialized();
478+
channelController = OneSignalMockChannelController();
479+
channelController.resetState();
480+
});
481+
482+
test('preventDefault() calls preventDefault with correct notification ID',
483+
() {
484+
final json = {
485+
'notification': validNotificationJson,
486+
};
487+
final event = OSNotificationWillDisplayEvent(json);
488+
489+
event.preventDefault();
490+
491+
expect(
492+
channelController.state.preventedNotificationId, 'notification-123');
493+
});
494+
495+
test('preventDefault() works with different notification IDs', () {
496+
final json = {
497+
'notification': {'notificationId': 'custom-will-display-id'},
498+
};
499+
final event = OSNotificationWillDisplayEvent(json);
500+
501+
event.preventDefault();
502+
503+
expect(channelController.state.preventedNotificationId,
504+
'custom-will-display-id');
505+
});
506+
507+
test('multiple preventDefault() calls update the prevented notification ID',
508+
() {
509+
final json1 = {
510+
'notification': {'notificationId': 'prevent-1'},
511+
};
512+
final json2 = {
513+
'notification': {'notificationId': 'prevent-2'},
514+
};
515+
final event1 = OSNotificationWillDisplayEvent(json1);
516+
final event2 = OSNotificationWillDisplayEvent(json2);
517+
518+
event1.preventDefault();
519+
expect(channelController.state.preventedNotificationId, 'prevent-1');
520+
521+
event2.preventDefault();
522+
expect(channelController.state.preventedNotificationId, 'prevent-2');
523+
});
524+
});
525+
526+
group('OSNotificationClickEvent preventDefault', () {
527+
late OneSignalMockChannelController channelController;
528+
529+
setUp(() {
530+
TestWidgetsFlutterBinding.ensureInitialized();
531+
channelController = OneSignalMockChannelController();
532+
channelController.resetState();
533+
});
534+
535+
test('preventDefault() calls preventDefault with correct notification ID',
536+
() {
537+
final json = {
538+
'notification': validNotificationJson,
539+
'result': clickResultJson,
540+
};
541+
final event = OSNotificationClickEvent(json);
542+
543+
event.preventDefault();
544+
545+
expect(
546+
channelController.state.preventedNotificationId, 'notification-123');
547+
});
548+
549+
test('preventDefault() works with different notification IDs', () {
550+
final json = {
551+
'notification': {'notificationId': 'custom-click-id'},
552+
'result': <String, dynamic>{},
553+
};
554+
final event = OSNotificationClickEvent(json);
555+
556+
event.preventDefault();
557+
558+
expect(
559+
channelController.state.preventedNotificationId, 'custom-click-id');
560+
});
561+
562+
test('multiple preventDefault() calls update the prevented notification ID',
563+
() {
564+
final json1 = {
565+
'notification': {'notificationId': 'click-prevent-1'},
566+
'result': <String, dynamic>{},
567+
};
568+
final json2 = {
569+
'notification': {'notificationId': 'click-prevent-2'},
570+
'result': <String, dynamic>{},
571+
};
572+
final event1 = OSNotificationClickEvent(json1);
573+
final event2 = OSNotificationClickEvent(json2);
574+
575+
event1.preventDefault();
576+
expect(
577+
channelController.state.preventedNotificationId, 'click-prevent-1');
578+
579+
event2.preventDefault();
580+
expect(
581+
channelController.state.preventedNotificationId, 'click-prevent-2');
582+
});
583+
});
398584
}

0 commit comments

Comments
 (0)