Skip to content

Commit 0c1ebb9

Browse files
committed
add notification test
1 parent d411cb7 commit 0c1ebb9

File tree

1 file changed

+398
-0
lines changed

1 file changed

+398
-0
lines changed

test/notification_test.dart

Lines changed: 398 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,398 @@
1+
import 'package:flutter_test/flutter_test.dart';
2+
import 'package:onesignal_flutter/src/notification.dart';
3+
4+
const validNotificationJson = {
5+
'notificationId': 'notification-123',
6+
'title': 'Test Title',
7+
'body': 'Test Body',
8+
'sound': 'default',
9+
'launchUrl': 'https://example.com',
10+
'templateId': 'template-456',
11+
'templateName': 'Template Name',
12+
'rawPayload': '{"key":"value"}',
13+
'additionalData': {'custom_key': 'custom_value'},
14+
'buttons': [
15+
{'id': 'btn1', 'text': 'Button 1'},
16+
{'id': 'btn2', 'text': 'Button 2', 'icon': 'icon.png'},
17+
],
18+
};
19+
20+
const iosOnlyJson = {
21+
'notificationId': 'ios-notification-123',
22+
'contentAvailable': true,
23+
'mutableContent': true,
24+
'category': 'CUSTOM_CATEGORY',
25+
'badge': 5,
26+
'badgeIncrement': 1,
27+
'subtitle': 'iOS Subtitle',
28+
'relevanceScore': 0.75,
29+
'interruptionLevel': 'timeSensitive',
30+
'attachments': {
31+
'image': 'https://example.com/image.png',
32+
'video': 'https://example.com/video.mp4',
33+
},
34+
};
35+
36+
const androidOnlyJson = {
37+
'notificationId': 'android-notification-123',
38+
'smallIcon': 'icon_small',
39+
'largeIcon': 'icon_large',
40+
'bigPicture': 'https://example.com/big_picture.png',
41+
'smallIconAccentColor': '#FF0000FF',
42+
'ledColor': '#FFFF0000',
43+
'lockScreenVisibility': 1,
44+
'groupKey': 'group_key_1',
45+
'groupMessage': 'You have 2 messages',
46+
'fromProjectNumber': '123456789',
47+
'collapseId': 'collapse_1',
48+
'priority': 10,
49+
'androidNotificationId': 1,
50+
'backgroundImageLayout': {
51+
'image': 'https://example.com/bg.png',
52+
'titleTextColor': '#FF000000',
53+
'bodyTextColor': '#FF666666',
54+
},
55+
};
56+
57+
const clickResultJson = {
58+
'action_id': 'action-123',
59+
'url': 'https://example.com/action',
60+
};
61+
62+
void main() {
63+
group('OSNotification', () {
64+
test('creates from valid JSON with all shared parameters', () {
65+
final notification = OSNotification(validNotificationJson);
66+
67+
expect(notification.notificationId, 'notification-123');
68+
expect(notification.title, 'Test Title');
69+
expect(notification.body, 'Test Body');
70+
expect(notification.sound, 'default');
71+
expect(notification.launchUrl, 'https://example.com');
72+
expect(notification.templateId, 'template-456');
73+
expect(notification.templateName, 'Template Name');
74+
});
75+
76+
test('creates from JSON with null optional fields', () {
77+
final json = {'notificationId': 'simple-notification'};
78+
final notification = OSNotification(json);
79+
80+
expect(notification.notificationId, 'simple-notification');
81+
expect(notification.title, isNull);
82+
expect(notification.body, isNull);
83+
expect(notification.sound, isNull);
84+
expect(notification.launchUrl, isNull);
85+
});
86+
87+
test('parses additionalData correctly', () {
88+
final notification = OSNotification(validNotificationJson);
89+
90+
expect(notification.additionalData, isNotNull);
91+
expect(notification.additionalData!['custom_key'], 'custom_value');
92+
});
93+
94+
test('parses buttons correctly', () {
95+
final notification = OSNotification(validNotificationJson);
96+
97+
expect(notification.buttons, isNotNull);
98+
expect(notification.buttons!.length, 2);
99+
expect(notification.buttons![0].id, 'btn1');
100+
expect(notification.buttons![0].text, 'Button 1');
101+
expect(notification.buttons![1].id, 'btn2');
102+
expect(notification.buttons![1].text, 'Button 2');
103+
expect(notification.buttons![1].icon, 'icon.png');
104+
});
105+
106+
test('parses iOS-specific parameters', () {
107+
final notification = OSNotification(iosOnlyJson);
108+
109+
expect(notification.contentAvailable, true);
110+
expect(notification.mutableContent, true);
111+
expect(notification.category, 'CUSTOM_CATEGORY');
112+
expect(notification.badge, 5);
113+
expect(notification.badgeIncrement, 1);
114+
expect(notification.subtitle, 'iOS Subtitle');
115+
expect(notification.relevanceScore, 0.75);
116+
expect(notification.interruptionLevel, 'timeSensitive');
117+
expect(notification.attachments, isNotNull);
118+
});
119+
120+
test('parses Android-specific parameters', () {
121+
final notification = OSNotification(androidOnlyJson);
122+
123+
expect(notification.smallIcon, 'icon_small');
124+
expect(notification.largeIcon, 'icon_large');
125+
expect(notification.bigPicture, 'https://example.com/big_picture.png');
126+
expect(notification.smallIconAccentColor, '#FF0000FF');
127+
expect(notification.ledColor, '#FFFF0000');
128+
expect(notification.lockScreenVisibility, 1);
129+
expect(notification.groupKey, 'group_key_1');
130+
expect(notification.groupMessage, 'You have 2 messages');
131+
expect(notification.fromProjectNumber, '123456789');
132+
expect(notification.collapseId, 'collapse_1');
133+
expect(notification.priority, 10);
134+
expect(notification.androidNotificationId, 1);
135+
});
136+
137+
test('parses backgroundImageLayout correctly', () {
138+
final notification = OSNotification(androidOnlyJson);
139+
140+
expect(notification.backgroundImageLayout, isNotNull);
141+
expect(notification.backgroundImageLayout!.image,
142+
'https://example.com/bg.png');
143+
expect(notification.backgroundImageLayout!.titleTextColor, '#FF000000');
144+
expect(notification.backgroundImageLayout!.bodyTextColor, '#FF666666');
145+
});
146+
147+
test('jsonRepresentation returns correct JSON string', () {
148+
final notification = OSNotification(validNotificationJson);
149+
final jsonRep = notification.jsonRepresentation();
150+
151+
expect(jsonRep, isA<String>());
152+
expect(jsonRep, contains('key'));
153+
expect(jsonRep, contains('value'));
154+
});
155+
});
156+
157+
group('OSNotificationClickResult', () {
158+
test('creates from valid JSON', () {
159+
final result = OSNotificationClickResult(clickResultJson);
160+
161+
expect(result.actionId, 'action-123');
162+
expect(result.url, 'https://example.com/action');
163+
});
164+
165+
test('creates from JSON with null fields', () {
166+
final json = <String, dynamic>{};
167+
final result = OSNotificationClickResult(json);
168+
169+
expect(result.actionId, isNull);
170+
expect(result.url, isNull);
171+
});
172+
173+
test('jsonRepresentation returns correct JSON string', () {
174+
final result = OSNotificationClickResult(clickResultJson);
175+
final jsonRep = result.jsonRepresentation();
176+
177+
expect(jsonRep, isA<String>());
178+
expect(jsonRep, contains('action-123'));
179+
expect(jsonRep, contains('https://example.com/action'));
180+
});
181+
182+
test('jsonRepresentation handles null values', () {
183+
final json = <String, dynamic>{};
184+
final result = OSNotificationClickResult(json);
185+
final jsonRep = result.jsonRepresentation();
186+
187+
expect(jsonRep, isA<String>());
188+
expect(jsonRep, contains('action_id'));
189+
expect(jsonRep, contains('url'));
190+
});
191+
});
192+
193+
group('OSActionButton', () {
194+
test('creates with required parameters', () {
195+
final button = OSActionButton(id: 'btn1', text: 'Click Me');
196+
197+
expect(button.id, 'btn1');
198+
expect(button.text, 'Click Me');
199+
expect(button.icon, isNull);
200+
});
201+
202+
test('creates with all parameters', () {
203+
final button = OSActionButton(
204+
id: 'btn2',
205+
text: 'Share',
206+
icon: 'share_icon.png',
207+
);
208+
209+
expect(button.id, 'btn2');
210+
expect(button.text, 'Share');
211+
expect(button.icon, 'share_icon.png');
212+
});
213+
214+
test('creates from JSON', () {
215+
final json = {
216+
'id': 'action1',
217+
'text': 'Open',
218+
'icon': 'open.png',
219+
};
220+
final button = OSActionButton.fromJson(json);
221+
222+
expect(button.id, 'action1');
223+
expect(button.text, 'Open');
224+
expect(button.icon, 'open.png');
225+
});
226+
227+
test('creates from JSON without icon', () {
228+
final json = {
229+
'id': 'action2',
230+
'text': 'Dismiss',
231+
};
232+
final button = OSActionButton.fromJson(json);
233+
234+
expect(button.id, 'action2');
235+
expect(button.text, 'Dismiss');
236+
expect(button.icon, isNull);
237+
});
238+
239+
test('mapRepresentation returns correct map', () {
240+
final button = OSActionButton(
241+
id: 'btn',
242+
text: 'Text',
243+
icon: 'icon.png',
244+
);
245+
final map = button.mapRepresentation();
246+
247+
expect(map['id'], 'btn');
248+
expect(map['text'], 'Text');
249+
expect(map['icon'], 'icon.png');
250+
});
251+
252+
test('jsonRepresentation returns correct JSON string', () {
253+
final button = OSActionButton(
254+
id: 'btn1',
255+
text: 'Action Text',
256+
icon: 'icon.png',
257+
);
258+
final jsonRep = button.jsonRepresentation();
259+
260+
expect(jsonRep, isA<String>());
261+
expect(jsonRep, contains('btn1'));
262+
expect(jsonRep, contains('Action Text'));
263+
});
264+
});
265+
266+
group('OSAndroidBackgroundImageLayout', () {
267+
test('creates from valid JSON', () {
268+
final layout = OSAndroidBackgroundImageLayout({
269+
'image': 'https://example.com/bg.png',
270+
'titleTextColor': '#FF000000',
271+
'bodyTextColor': '#FF666666',
272+
});
273+
274+
expect(layout.image, 'https://example.com/bg.png');
275+
expect(layout.titleTextColor, '#FF000000');
276+
expect(layout.bodyTextColor, '#FF666666');
277+
});
278+
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+
287+
test('creates from empty JSON', () {
288+
final layout = OSAndroidBackgroundImageLayout({});
289+
290+
expect(layout.image, isNull);
291+
expect(layout.titleTextColor, isNull);
292+
expect(layout.bodyTextColor, isNull);
293+
});
294+
295+
test('jsonRepresentation returns correct JSON string', () {
296+
final layout = OSAndroidBackgroundImageLayout({
297+
'image': 'https://example.com/bg.png',
298+
'titleTextColor': '#FF000000',
299+
'bodyTextColor': '#FF666666',
300+
});
301+
final jsonRep = layout.jsonRepresentation();
302+
303+
expect(jsonRep, isA<String>());
304+
expect(jsonRep, contains('image'));
305+
expect(jsonRep, contains('titleTextColor'));
306+
expect(jsonRep, contains('bodyTextColor'));
307+
});
308+
});
309+
310+
group('OSNotificationWillDisplayEvent', () {
311+
test('creates from valid JSON', () {
312+
final json = {
313+
'notification': validNotificationJson,
314+
};
315+
final event = OSNotificationWillDisplayEvent(json);
316+
317+
expect(event.notification, isNotNull);
318+
expect(event.notification.notificationId, 'notification-123');
319+
expect(event.notification.title, 'Test Title');
320+
});
321+
322+
test('creates with iOS notification data', () {
323+
final json = {
324+
'notification': iosOnlyJson,
325+
};
326+
final event = OSNotificationWillDisplayEvent(json);
327+
328+
expect(event.notification.contentAvailable, true);
329+
expect(event.notification.category, 'CUSTOM_CATEGORY');
330+
});
331+
332+
test('jsonRepresentation returns correct JSON string', () {
333+
final json = {
334+
'notification': validNotificationJson,
335+
};
336+
final event = OSNotificationWillDisplayEvent(json);
337+
final jsonRep = event.jsonRepresentation();
338+
339+
expect(jsonRep, isA<String>());
340+
expect(jsonRep, contains('notification'));
341+
});
342+
});
343+
344+
group('OSNotificationClickEvent', () {
345+
test('creates from valid JSON with both notification and result', () {
346+
final json = {
347+
'notification': validNotificationJson,
348+
'result': clickResultJson,
349+
};
350+
final event = OSNotificationClickEvent(json);
351+
352+
expect(event.notification, isNotNull);
353+
expect(event.notification.notificationId, 'notification-123');
354+
expect(event.result, isNotNull);
355+
expect(event.result.actionId, 'action-123');
356+
expect(event.result.url, 'https://example.com/action');
357+
});
358+
359+
test('creates from JSON with minimal data', () {
360+
final json = {
361+
'notification': {'notificationId': 'click-123'},
362+
'result': <String, dynamic>{},
363+
};
364+
final event = OSNotificationClickEvent(json);
365+
366+
expect(event.notification.notificationId, 'click-123');
367+
expect(event.result.actionId, isNull);
368+
expect(event.result.url, isNull);
369+
});
370+
371+
test('jsonRepresentation returns correct JSON string', () {
372+
final json = {
373+
'notification': validNotificationJson,
374+
'result': clickResultJson,
375+
};
376+
final event = OSNotificationClickEvent(json);
377+
final jsonRep = event.jsonRepresentation();
378+
379+
expect(jsonRep, isA<String>());
380+
expect(jsonRep, contains('notification'));
381+
expect(jsonRep, contains('result'));
382+
});
383+
384+
test('jsonRepresentation includes action data from result', () {
385+
final json = {
386+
'notification': validNotificationJson,
387+
'result': clickResultJson,
388+
};
389+
final event = OSNotificationClickEvent(json);
390+
final jsonRep = event.jsonRepresentation();
391+
392+
// The notification's jsonRepresentation only includes rawPayload
393+
// The result includes actionId and url
394+
expect(jsonRep, contains('action-123'));
395+
expect(jsonRep, contains('https://example.com/action'));
396+
});
397+
});
398+
}

0 commit comments

Comments
 (0)