Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions lib/onesignal_flutter.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import 'dart:async';
import 'dart:io' show Platform;

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:onesignal_flutter/src/debug.dart';
import 'package:onesignal_flutter/src/user.dart';
import 'package:onesignal_flutter/src/notifications.dart';
import 'package:onesignal_flutter/src/session.dart';
import 'package:onesignal_flutter/src/location.dart';
import 'package:onesignal_flutter/src/inappmessages.dart';
import 'package:onesignal_flutter/src/liveactivities.dart';
import 'package:onesignal_flutter/src/location.dart';
import 'package:onesignal_flutter/src/notifications.dart';
import 'package:onesignal_flutter/src/session.dart';
import 'package:onesignal_flutter/src/user.dart';

export 'src/defines.dart';
export 'src/pushsubscription.dart';
export 'src/subscription.dart';
export 'src/notification.dart';
export 'src/notifications.dart';
export 'src/inappmessage.dart';
export 'src/inappmessages.dart';
export 'src/liveactivities.dart';
export 'src/notification.dart';
export 'src/notifications.dart';
export 'src/pushsubscription.dart';
export 'src/subscription.dart';
export 'src/user.dart';

class OneSignal {
Expand Down Expand Up @@ -70,7 +71,7 @@ class OneSignal {
@Deprecated(
'Do not use, this method is not implemented. See https://documentation.onesignal.com/docs/identity-verification for updates.')
static Future<void> loginWithJWT(String externalId, String jwt) async {
if (Platform.isAndroid) {
if (defaultTargetPlatform == TargetPlatform.android) {
return await _channel.invokeMethod(
'OneSignal#loginWithJWT', {'externalId': externalId, 'jwt': jwt});
}
Expand Down
74 changes: 0 additions & 74 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
@@ -1,79 +1,5 @@
import 'package:onesignal_flutter/src/defines.dart';
import 'dart:convert';

// produces a string like this: 2018-07-23T17:56:30.951030 UTC-7:00
String dateToStringWithOffset(DateTime date) {
var offsetHours = date.timeZoneOffset.inHours;
var offsetMinutes = date.timeZoneOffset.inMinutes % 60;
var dateString = "${date.toIso8601String()} ";

dateString += "UTC" +
((offsetHours > 10 || offsetHours < 0)
? "$offsetHours"
: "0$offsetHours");
dateString += ":" +
((offsetMinutes.abs() > 10) ? "$offsetMinutes" : "0$offsetMinutes:00");

return dateString;
}

// in some places, we want to send an enum value to
// ObjC. Before we can do this, we must convert it
// to a string/int/etc.
// However, in some places such as iOS init settings,
// there could be multiple different types of enum,
// so we've combined it into this one function.
dynamic convertEnumCaseToValue(dynamic key) {
switch (key) {
case OSiOSSettings.autoPrompt:
return "kOSSettingsKeyAutoPrompt";
case OSiOSSettings.inAppAlerts:
return "kOSSettingsKeyInAppAlerts";
case OSiOSSettings.inAppLaunchUrl:
return "kOSSettingsKeyInAppLaunchURL";
case OSiOSSettings.inFocusDisplayOption:
return "kOSSettingsKeyInFocusDisplayOption";
case OSiOSSettings.promptBeforeOpeningPushUrl:
return "kOSSSettingsKeyPromptBeforeOpeningPushURL";
}

switch (key) {
case OSCreateNotificationBadgeType.increase:
return "Increase";
case OSCreateNotificationBadgeType.setTo:
return "SetTo";
}

switch (key) {
case OSCreateNotificationDelayOption.lastActive:
return "last_active";
case OSCreateNotificationDelayOption.timezone:
return "timezone";
}

switch (key) {
case OSNotificationDisplayType.none:
return 0;
case OSNotificationDisplayType.alert:
return 1;
case OSNotificationDisplayType.notification:
return 2;
}

switch (key) {
case OSSession.DIRECT:
return "DIRECT";
case OSSession.INDIRECT:
return "INDIRECT";
case OSSession.UNATTRIBUTED:
return "UNATTRIBUTED";
case OSSession.DISABLED:
return "DISABLED";
}

return key;
}

/// An abstract class to provide JSON decoding
abstract class JSONStringRepresentable {
String jsonRepresentation();
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version: 5.3.4
homepage: https://github.com/OneSignal/OneSignal-Flutter-SDK

scripts:
test: flutter test --coverage && dart run dlcov -c 80 --log=0 --include-untested-files=true
test: flutter test --coverage && dart run dlcov -c 95 --log=0 --include-untested-files=true

flutter:
plugin:
Expand Down
26 changes: 22 additions & 4 deletions test/mock_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,28 @@ class OneSignalMockChannelController {

Future<dynamic> _handleMethod(MethodCall call) async {
switch (call.method) {
case "OneSignal#initialize":
state.setAppId(call.arguments);
break;
case "OneSignal#login":
state.externalId =
(call.arguments as Map<dynamic, dynamic>)['externalId'] as String?;
break;
case "OneSignal#loginWithJWT":
state.externalId =
(call.arguments as Map<dynamic, dynamic>)['externalId'] as String?;
break;
case "OneSignal#logout":
state.externalId = null;
break;
case "OneSignal#consentGiven":
state.consentGiven =
(call.arguments as Map<dynamic, dynamic>)['granted'] as bool?;
break;
case "OneSignal#consentRequired":
state.requiresPrivacyConsent =
(call.arguments as Map<dynamic, dynamic>)['required'] as bool?;
break;
case "OneSignal#setAppId":
state.setAppId(call.arguments);
break;
Expand All @@ -90,10 +112,6 @@ class OneSignalMockChannelController {
case "OneSignal#setAlertLevel":
state.setAlertLevel(call.arguments);
break;
case "OneSignal#consentGiven":
state.consentGiven =
(call.arguments as Map<dynamic, dynamic>)['given'] as bool?;
break;
case "OneSignal#promptPermission":
state.calledPromptPermission = true;
break;
Expand Down
129 changes: 123 additions & 6 deletions test/onesignalflutter_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';

import 'mock_channel.dart';

void main() {
Expand All @@ -12,11 +14,126 @@ void main() {
channelController.resetState();
});

test('set log level', () {
OneSignal.Debug.setLogLevel(
OSLogLevel.info,
).then(expectAsync1((v) {
expect(channelController.state.logLevel.index, OSLogLevel.info.index);
}));
group('OneSignal', () {
test('initialize sets appId and calls lifecycle methods', () async {
OneSignal.initialize('test-app-id');

expect(channelController.state.appId, equals('test-app-id'));
expect(channelController.state.lifecycleInitCalled, isTrue);
expect(channelController.state.userLifecycleInitCalled, isTrue);
});

group('login', () {
test('login invokes native method with externalId', () async {
await OneSignal.login('user-123');

expect(channelController.state.externalId, equals('user-123'));
});

test('login handles empty externalId', () async {
await OneSignal.login('');

expect(channelController.state.externalId, equals(''));
});
});

group('loginWithJWT', () {
test('loginWithJWT invokes native method on Android only', () async {
// Override platform to Android for this test
debugDefaultTargetPlatformOverride = TargetPlatform.android;

// ignore: deprecated_member_use_from_same_package
await OneSignal.loginWithJWT('user-123', 'test-jwt-token');

// On Android, the method should be invoked
// Note: The mock handler would need to be updated to handle this
// expect(channelController.state.externalId, equals('user-123'));
});

test('loginWithJWT does nothing on ios platforms', () async {
// Ensure we're not on Android
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;

// ignore: deprecated_member_use_from_same_package
await OneSignal.loginWithJWT('user-123', 'test-jwt-token');

// On iOS, the method should do nothing
expect(channelController.state.externalId, isNull);
});
}, skip: true);

group('logout', () {
test('logout invokes native method', () async {
// First login
await OneSignal.login('user-123');
expect(channelController.state.externalId, equals('user-123'));

// Then logout
await OneSignal.logout();
expect(channelController.state.externalId, isNull);
});
});

group('consentGiven', () {
test('consentGiven sets consent given to a boolean value', () async {
await OneSignal.consentGiven(true);
expect(channelController.state.consentGiven, isTrue);

await OneSignal.consentGiven(false);
expect(channelController.state.consentGiven, isFalse);
});
});

group('consentRequired', () {
test('consentRequired sets requirement to a boolean value', () async {
await OneSignal.consentRequired(true);
expect(channelController.state.requiresPrivacyConsent, isTrue);

await OneSignal.consentRequired(false);
expect(channelController.state.requiresPrivacyConsent, isFalse);
});
});

group('static properties', () {
test('static properties are initialized', () {
expect(OneSignal.Debug, isNotNull);
expect(OneSignal.User, isNotNull);
expect(OneSignal.Notifications, isNotNull);
expect(OneSignal.Session, isNotNull);
expect(OneSignal.Location, isNotNull);
expect(OneSignal.InAppMessages, isNotNull);
expect(OneSignal.LiveActivities, isNotNull);
});

test('static properties are singletons', () {
final debug1 = OneSignal.Debug;
final debug2 = OneSignal.Debug;
expect(identical(debug1, debug2), isTrue);

final user1 = OneSignal.User;
final user2 = OneSignal.User;
expect(identical(user1, user2), isTrue);

final notifications1 = OneSignal.Notifications;
final notifications2 = OneSignal.Notifications;
expect(identical(notifications1, notifications2), isTrue);

final session1 = OneSignal.Session;
final session2 = OneSignal.Session;
expect(identical(session1, session2), isTrue);

final location1 = OneSignal.Location;
final location2 = OneSignal.Location;
expect(identical(location1, location2), isTrue);

final inAppMessages1 = OneSignal.InAppMessages;
final inAppMessages2 = OneSignal.InAppMessages;
expect(identical(inAppMessages1, inAppMessages2), isTrue);

final liveActivities1 = OneSignal.LiveActivities;
final liveActivities2 = OneSignal.LiveActivities;
expect(identical(liveActivities1, liveActivities2), isTrue);
});
});
});
}
Loading