From 7e4fd34bfe61aad1a2d5d9e974e72db412e811c2 Mon Sep 17 00:00:00 2001 From: Rehan Date: Wed, 27 Nov 2024 01:12:49 +0500 Subject: [PATCH] chore: refactor dart call forwarding --- .../lib/src/screens/dashboard.dart | 4 +- lib/customer_io.dart | 33 ++-- lib/customer_io_method_channel.dart | 152 ------------------ .../_native_constants.dart} | 29 ++-- .../customer_io_method_channel.dart | 109 +++++++++++++ .../customer_io_platform_interface.dart | 24 +-- lib/extensions/map_extensions.dart | 2 +- lib/extensions/method_channel_extensions.dart | 40 +++++ lib/messaging_in_app/_native_constants.dart | 8 + lib/messaging_in_app/method_channel.dart | 21 +-- lib/messaging_in_app/platform_interface.dart | 2 +- lib/messaging_push/_native_constants.dart | 11 ++ lib/messaging_push/method_channel.dart | 38 ++--- test/customer_io_method_channel_test.dart | 6 +- test/customer_io_test.dart | 6 +- test/customer_io_test.mocks.dart | 42 +++-- 16 files changed, 257 insertions(+), 270 deletions(-) delete mode 100644 lib/customer_io_method_channel.dart rename lib/{customer_io_const.dart => data_pipelines/_native_constants.dart} (65%) create mode 100644 lib/data_pipelines/customer_io_method_channel.dart rename lib/{ => data_pipelines}/customer_io_platform_interface.dart (78%) create mode 100644 lib/extensions/method_channel_extensions.dart create mode 100644 lib/messaging_in_app/_native_constants.dart create mode 100644 lib/messaging_push/_native_constants.dart diff --git a/apps/amiapp_flutter/lib/src/screens/dashboard.dart b/apps/amiapp_flutter/lib/src/screens/dashboard.dart index 0c32a00..74e3532 100644 --- a/apps/amiapp_flutter/lib/src/screens/dashboard.dart +++ b/apps/amiapp_flutter/lib/src/screens/dashboard.dart @@ -53,8 +53,8 @@ class _DashboardScreenState extends State { .getBuildInfo() .then((value) => setState(() => _buildInfo = value)); - inAppMessageStreamSubscription = - CustomerIO.instance.inAppMessaging.subscribeToInAppEventListener(handleInAppEvent); + inAppMessageStreamSubscription = CustomerIO.inAppMessaging + .subscribeToInAppEventListener(handleInAppEvent); // Setup 3rd party SDK, flutter-fire. // We install this SDK into sample app to make sure the CIO SDK behaves as expected when there is another SDK installed that handles push notifications. diff --git a/lib/customer_io.dart b/lib/customer_io.dart index a231ae8..cdfcb87 100644 --- a/lib/customer_io.dart +++ b/lib/customer_io.dart @@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart'; import 'customer_io_config.dart'; import 'customer_io_enums.dart'; -import 'customer_io_platform_interface.dart'; +import 'data_pipelines/customer_io_platform_interface.dart'; import 'extensions/map_extensions.dart'; import 'messaging_in_app/platform_interface.dart'; import 'messaging_push/platform_interface.dart'; @@ -61,17 +61,13 @@ class CustomerIO { /// Access push messaging functionality static CustomerIOMessagingPushPlatform get pushMessaging { - if (_instance == null) { - throw StateError( - 'CustomerIO SDK must be initialized before accessing push module.\n' - 'Call CustomerIO.initialize() first.', - ); - } - return _instance!._pushMessaging; + return instance._pushMessaging; } /// Access in-app messaging functionality - CustomerIOMessagingInAppPlatform get inAppMessaging => _inAppMessaging; + static CustomerIOMessagingInAppPlatform get inAppMessaging { + return instance._inAppMessaging; + } /// To initialize the plugin /// @@ -95,7 +91,7 @@ class CustomerIO { /// /// @param userId unique identifier for a profile /// @param traits (Optional) params to set profile attributes - void identify( + Future identify( {required String userId, Map traits = const {}}) { return _platform.identify( userId: userId, traits: traits.excludeNullValues()); @@ -105,8 +101,8 @@ class CustomerIO { /// /// If a profile exists, clearIdentify will stop identifying the profile. /// If no profile exists, request to clearIdentify will be ignored. - void clearIdentify() { - _platform.clearIdentify(); + Future clearIdentify() { + return _platform.clearIdentify(); } /// To track user events like loggedIn, addedItemToCart etc. @@ -114,14 +110,14 @@ class CustomerIO { /// /// @param name event name to be tracked /// @param properties (Optional) params to be sent with event - void track( + Future track( {required String name, Map properties = const {}}) { return _platform.track( name: name, properties: properties.excludeNullValues()); } /// Track a push metric - void trackMetric( + Future trackMetric( {required String deliveryID, required String deviceToken, required MetricEvent event}) { @@ -131,7 +127,7 @@ class CustomerIO { /// Register a new device token with Customer.io, associated with the current active customer. If there /// is no active customer, this will fail to register the device - void registerDeviceToken({required String deviceToken}) { + Future registerDeviceToken({required String deviceToken}) { return _platform.registerDeviceToken(deviceToken: deviceToken); } @@ -139,7 +135,7 @@ class CustomerIO { /// /// @param name name of the screen user visited /// @param attributes (Optional) params to be sent with event - void screen( + Future screen( {required String title, Map properties = const {}}) { return _platform.screen( title: title, properties: properties.excludeNullValues()); @@ -149,7 +145,7 @@ class CustomerIO { /// such as app preferences, timezone etc /// /// @param attributes device attributes - void setDeviceAttributes({required Map attributes}) { + Future setDeviceAttributes({required Map attributes}) { return _platform.setDeviceAttributes(attributes: attributes); } @@ -157,7 +153,8 @@ class CustomerIO { /// user actions etc /// /// @param attributes additional attributes for a user profile - void setProfileAttributes({required Map attributes}) { + Future setProfileAttributes( + {required Map attributes}) { return _platform.setProfileAttributes( attributes: attributes.excludeNullValues()); } diff --git a/lib/customer_io_method_channel.dart b/lib/customer_io_method_channel.dart deleted file mode 100644 index 5a303c0..0000000 --- a/lib/customer_io_method_channel.dart +++ /dev/null @@ -1,152 +0,0 @@ -import 'dart:async'; - -import 'package:customer_io/customer_io_enums.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; - -import 'customer_io_config.dart'; -import 'customer_io_const.dart'; -import 'customer_io_platform_interface.dart'; - -/// An implementation of [CustomerIOPlatform] that uses method channels. -class CustomerIOMethodChannel extends CustomerIOPlatform { - /// The method channel used to interact with the native platform. - @visibleForTesting - final methodChannel = const MethodChannel('customer_io'); - - /// To initialize the plugin - @override - Future initialize({ - required CustomerIOConfig config, - }) async { - try { - await methodChannel.invokeMethod(MethodConsts.initialize, config.toMap()); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// Identify a person using a unique userId, eg. email id. - /// Note that you can identify only 1 profile at a time. In case, multiple - /// identifiers are attempted to be identified, then the last identified profile - /// will be removed automatically. - @override - void identify( - {required String userId, - Map traits = const {}}) async { - try { - final payload = { - TrackingConsts.userId: userId, - TrackingConsts.traits: traits - }; - methodChannel.invokeMethod(MethodConsts.identify, payload); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// To track user events like loggedIn, addedItemToCart etc. - /// You may also track events with additional yet optional data. - @override - void track( - {required String name, - Map properties = const {}}) async { - try { - final payload = { - TrackingConsts.name: name, - TrackingConsts.properties: properties - }; - methodChannel.invokeMethod(MethodConsts.track, payload); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// Track a push metric - @override - void trackMetric( - {required String deliveryID, - required String deviceToken, - required MetricEvent event}) async { - try { - final payload = { - TrackingConsts.deliveryId: deliveryID, - TrackingConsts.deliveryToken: deviceToken, - TrackingConsts.metricEvent: event.name, - }; - methodChannel.invokeMethod(MethodConsts.trackMetric, payload); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// Track screen events to record the screens a user visits - @override - void screen( - {required String title, - Map properties = const {}}) async { - try { - final payload = { - TrackingConsts.title: title, - TrackingConsts.properties: properties - }; - methodChannel.invokeMethod(MethodConsts.screen, payload); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// Register a new device token with Customer.io, associated with the current active customer. If there - /// is no active customer, this will fail to register the device - @override - void registerDeviceToken({required String deviceToken}) async { - try { - final payload = { - TrackingConsts.token: deviceToken, - }; - methodChannel.invokeMethod(MethodConsts.registerDeviceToken, payload); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// Call this function to stop identifying a person. - @override - void clearIdentify() { - try { - methodChannel.invokeMethod(MethodConsts.clearIdentify); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// Set custom user profile information such as user preference, specific - /// user actions etc - @override - void setProfileAttributes({required Map attributes}) { - try { - final payload = {TrackingConsts.attributes: attributes}; - methodChannel.invokeMethod(MethodConsts.setProfileAttributes, payload); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - /// Use this function to send custom device attributes - /// such as app preferences, timezone etc - @override - void setDeviceAttributes({required Map attributes}) { - try { - final payload = {TrackingConsts.traits: attributes}; - methodChannel.invokeMethod(MethodConsts.setDeviceAttributes, payload); - } on PlatformException catch (exception) { - handleException(exception); - } - } - - void handleException(PlatformException exception) { - if (kDebugMode) { - print(exception); - } - } -} diff --git a/lib/customer_io_const.dart b/lib/data_pipelines/_native_constants.dart similarity index 65% rename from lib/customer_io_const.dart rename to lib/data_pipelines/_native_constants.dart index 7371cdc..5605452 100644 --- a/lib/customer_io_const.dart +++ b/lib/data_pipelines/_native_constants.dart @@ -1,33 +1,26 @@ -// TODO: Cleanup this file later when all commented methods are implemented - -class MethodConsts { - static const String initialize = "initialize"; - static const String identify = "identify"; +/// Methods specific to Data Pipelines module. +class NativeMethods { static const String clearIdentify = "clearIdentify"; - static const String track = "track"; - static const String trackMetric = "trackMetric"; + static const String identify = "identify"; + static const String initialize = "initialize"; static const String screen = "screen"; static const String setDeviceAttributes = "setDeviceAttributes"; static const String setProfileAttributes = "setProfileAttributes"; static const String registerDeviceToken = "registerDeviceToken"; - static const String onMessageReceived = "onMessageReceived"; - static const String dismissMessage = "dismissMessage"; - static const String getRegisteredDeviceToken = "getRegisteredDeviceToken"; + static const String track = "track"; + static const String trackMetric = "trackMetric"; } -class TrackingConsts { - static const String userId = "userId"; +/// Method parameters specific to DataPipelines module. +class NativeMethodParams { static const String attributes = "attributes"; - static const String traits = "traits"; - static const String eventName = "eventName"; - static const String token = "token"; static const String deliveryId = "deliveryId"; static const String deliveryToken = "deliveryToken"; static const String metricEvent = "metricEvent"; - static const String message = "message"; - static const String handleNotificationTrigger = "handleNotificationTrigger"; - static const String name = "name"; static const String properties = "properties"; static const String title = "title"; + static const String token = "token"; + static const String traits = "traits"; + static const String userId = "userId"; } diff --git a/lib/data_pipelines/customer_io_method_channel.dart b/lib/data_pipelines/customer_io_method_channel.dart new file mode 100644 index 0000000..c9c0011 --- /dev/null +++ b/lib/data_pipelines/customer_io_method_channel.dart @@ -0,0 +1,109 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import '../customer_io_config.dart'; +import '../customer_io_enums.dart'; +import '../extensions/method_channel_extensions.dart'; +import '_native_constants.dart'; +import 'customer_io_platform_interface.dart'; + +/// An implementation of [CustomerIOPlatform] that uses method channels. +class CustomerIOMethodChannel extends CustomerIOPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('customer_io'); + + /// To initialize the plugin + @override + Future initialize({required CustomerIOConfig config}) { + return methodChannel.invokeNativeMethodVoid( + NativeMethods.initialize, config.toMap()); + } + + /// Identify a person using a unique userId, eg. email id. + /// Note that you can identify only 1 profile at a time. In case, multiple + /// identifiers are attempted to be identified, then the last identified profile + /// will be removed automatically. + @override + Future identify( + {required String userId, Map traits = const {}}) { + return methodChannel + .invokeNativeMethodVoidNew(NativeMethods.identify, arguments: { + NativeMethodParams.userId: userId, + NativeMethodParams.traits: traits, + }); + } + + /// To track user events like loggedIn, addedItemToCart etc. + /// You may also track events with additional yet optional data. + @override + Future track( + {required String name, Map properties = const {}}) { + return methodChannel.invokeNativeMethodVoid(NativeMethods.track, { + NativeMethodParams.name: name, + NativeMethodParams.properties: properties, + }); + } + + /// Track a push metric + @override + Future trackMetric( + {required String deliveryID, + required String deviceToken, + required MetricEvent event}) { + return methodChannel.invokeNativeMethodVoid(NativeMethods.trackMetric, { + NativeMethodParams.deliveryId: deliveryID, + NativeMethodParams.deliveryToken: deviceToken, + NativeMethodParams.metricEvent: event.name, + }); + } + + /// Track screen events to record the screens a user visits + @override + Future screen( + {required String title, Map properties = const {}}) { + return methodChannel.invokeNativeMethodVoid(NativeMethods.screen, { + NativeMethodParams.title: title, + NativeMethodParams.properties: properties, + }); + } + + /// Register a new device token with Customer.io, associated with the current active customer. If there + /// is no active customer, this will fail to register the device + @override + Future registerDeviceToken({required String deviceToken}) { + return methodChannel + .invokeNativeMethodVoid(NativeMethods.registerDeviceToken, { + NativeMethodParams.token: deviceToken, + }); + } + + /// Call this function to stop identifying a person. + @override + Future clearIdentify() { + return methodChannel.invokeNativeMethodVoid(NativeMethods.clearIdentify); + } + + /// Set custom user profile information such as user preference, specific + /// user actions etc + @override + Future setProfileAttributes( + {required Map attributes}) { + return methodChannel + .invokeNativeMethodVoid(NativeMethods.setProfileAttributes, { + NativeMethodParams.attributes: attributes, + }); + } + + /// Use this function to send custom device attributes + /// such as app preferences, timezone etc + @override + Future setDeviceAttributes({required Map attributes}) { + return methodChannel + .invokeNativeMethodVoid(NativeMethods.setDeviceAttributes, { + NativeMethodParams.attributes: attributes, + }); + } +} diff --git a/lib/customer_io_platform_interface.dart b/lib/data_pipelines/customer_io_platform_interface.dart similarity index 78% rename from lib/customer_io_platform_interface.dart rename to lib/data_pipelines/customer_io_platform_interface.dart index c9646b5..a5c13d1 100644 --- a/lib/customer_io_platform_interface.dart +++ b/lib/data_pipelines/customer_io_platform_interface.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'package:customer_io/customer_io_config.dart'; -import 'package:customer_io/customer_io_enums.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import '../customer_io_config.dart'; +import '../customer_io_enums.dart'; import 'customer_io_method_channel.dart'; /// The default instance of [CustomerIOPlatform] to use @@ -33,42 +33,42 @@ abstract class CustomerIOPlatform extends PlatformInterface { throw UnimplementedError('initialize() has not been implemented.'); } - void identify( - {required String userId, - Map traits = const {}}) { + Future identify( + {required String userId, Map traits = const {}}) { throw UnimplementedError('identify() has not been implemented.'); } - void clearIdentify() { + Future clearIdentify() { throw UnimplementedError('clearIdentify() has not been implemented.'); } - void track( + Future track( {required String name, Map properties = const {}}) { throw UnimplementedError('track() has not been implemented.'); } - void trackMetric( + Future trackMetric( {required String deliveryID, required String deviceToken, required MetricEvent event}) { throw UnimplementedError('trackMetric() has not been implemented.'); } - void registerDeviceToken({required String deviceToken}) { + Future registerDeviceToken({required String deviceToken}) { throw UnimplementedError('registerDeviceToken() has not been implemented.'); } - void screen( + Future screen( {required String title, Map properties = const {}}) { throw UnimplementedError('screen() has not been implemented.'); } - void setDeviceAttributes({required Map attributes}) { + Future setDeviceAttributes({required Map attributes}) { throw UnimplementedError('setDeviceAttributes() has not been implemented.'); } - void setProfileAttributes({required Map attributes}) { + Future setProfileAttributes( + {required Map attributes}) { throw UnimplementedError( 'setProfileAttributes() has not been implemented.'); } diff --git a/lib/extensions/map_extensions.dart b/lib/extensions/map_extensions.dart index a8baaef..5b0c5a7 100644 --- a/lib/extensions/map_extensions.dart +++ b/lib/extensions/map_extensions.dart @@ -1,5 +1,5 @@ /// Extensions for [Map] class that provide additional functionality and convenience methods. -extension CustomerIOMapExtension on Map { +extension CustomerIOMapExtensions on Map { /// Returns a new map with entries that have non-null values, excluding null values. Map excludeNullValues() { return Map.fromEntries(entries.where((entry) => entry.value != null)); diff --git a/lib/extensions/method_channel_extensions.dart b/lib/extensions/method_channel_extensions.dart new file mode 100644 index 0000000..dd69f44 --- /dev/null +++ b/lib/extensions/method_channel_extensions.dart @@ -0,0 +1,40 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +extension CustomerIOMethodChannelExtensions on MethodChannel { + /// Invokes a native method and returns the result. + /// Logs exceptions internally without propagating them. + Future invokeNativeMethod(String method, + {Map arguments = const {}}) async { + try { + return await invokeMethod(method, arguments); + } on PlatformException catch (ex) { + // Log the exception + if (kDebugMode) { + print("Error invoking native method '$method': ${ex.message}"); + } + // Return null on failure + return null; + } catch (ex) { + // Catch any other exceptions + if (kDebugMode) { + print("Unexpected error invoking native method '$method': $ex"); + } + // Return null on unexpected errors + return null; + } + } + + /// Simplifies invoking a native method that doesn't return a value. + Future invokeNativeMethodVoidNew(String method, + {Map arguments = const {}}) async { + await invokeNativeMethod(method, arguments: arguments); + return Future.value(); + } + + Future invokeNativeMethodVoid(String method, + [Map arguments = const {}]) async { + await invokeNativeMethod(method, arguments: arguments); + return Future.value(); + } +} diff --git a/lib/messaging_in_app/_native_constants.dart b/lib/messaging_in_app/_native_constants.dart new file mode 100644 index 0000000..fa2eb31 --- /dev/null +++ b/lib/messaging_in_app/_native_constants.dart @@ -0,0 +1,8 @@ +/// Methods specific to In-App module. +class NativeMethods { + static const String dismissMessage = "dismissMessage"; +} + +/// Method parameters specific to In-App module. +class NativeMethodParams { +} diff --git a/lib/messaging_in_app/method_channel.dart b/lib/messaging_in_app/method_channel.dart index 2f32c06..ece1ac0 100644 --- a/lib/messaging_in_app/method_channel.dart +++ b/lib/messaging_in_app/method_channel.dart @@ -3,8 +3,9 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import '../customer_io_const.dart'; import '../customer_io_inapp.dart'; +import '../extensions/method_channel_extensions.dart'; +import '_native_constants.dart'; import 'platform_interface.dart'; /// An implementation of [CustomerIOMessagingInAppPlatform] that uses method @@ -17,12 +18,8 @@ class CustomerIOMessagingInAppMethodChannel final _inAppEventStreamController = StreamController.broadcast(); @override - void dismissMessage() async { - try { - methodChannel.invokeMethod(MethodConsts.dismissMessage); - } on PlatformException catch (e) { - handleException(e); - } + Future dismissMessage() { + return methodChannel.invokeNativeMethodVoid(NativeMethods.dismissMessage); } /// Method to subscribe to the In-App event listener. @@ -33,7 +30,7 @@ class CustomerIOMessagingInAppMethodChannel StreamSubscription subscribeToInAppEventListener( void Function(InAppEvent) onEvent) { StreamSubscription subscription = - _inAppEventStreamController.stream.listen(onEvent); + _inAppEventStreamController.stream.listen(onEvent); return subscription; } @@ -45,7 +42,7 @@ class CustomerIOMessagingInAppMethodChannel Future _onMethodCall(MethodCall call) async { /// Cast the arguments to a map of strings to dynamic values. final arguments = - (call.arguments as Map).cast(); + (call.arguments as Map).cast(); switch (call.method) { case "messageShown": @@ -66,10 +63,4 @@ class CustomerIOMessagingInAppMethodChannel break; } } - - void handleException(PlatformException exception) { - if (kDebugMode) { - print(exception); - } - } } diff --git a/lib/messaging_in_app/platform_interface.dart b/lib/messaging_in_app/platform_interface.dart index d123ac0..7473562 100644 --- a/lib/messaging_in_app/platform_interface.dart +++ b/lib/messaging_in_app/platform_interface.dart @@ -27,7 +27,7 @@ abstract class CustomerIOMessagingInAppPlatform extends PlatformInterface { _instance = instance; } - void dismissMessage() { + Future dismissMessage() { throw UnimplementedError('dismissMessage() has not been implemented.'); } diff --git a/lib/messaging_push/_native_constants.dart b/lib/messaging_push/_native_constants.dart new file mode 100644 index 0000000..458b4be --- /dev/null +++ b/lib/messaging_push/_native_constants.dart @@ -0,0 +1,11 @@ +/// Methods specific to Push module. +class NativeMethods { + static const String getRegisteredDeviceToken = "getRegisteredDeviceToken"; + static const String onMessageReceived = "onMessageReceived"; +} + +/// Method parameters specific to Push module. +class NativeMethodParams { + static const String message = "message"; + static const String handleNotificationTrigger = "handleNotificationTrigger"; +} diff --git a/lib/messaging_push/method_channel.dart b/lib/messaging_push/method_channel.dart index 29d6c54..e322da5 100644 --- a/lib/messaging_push/method_channel.dart +++ b/lib/messaging_push/method_channel.dart @@ -1,9 +1,10 @@ import 'dart:io'; +import 'package:customer_io/extensions/method_channel_extensions.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import '../customer_io_const.dart'; +import '_native_constants.dart'; import 'platform_interface.dart'; /// An implementation of [CustomerIOMessagingPushPlatform] that uses method @@ -16,15 +17,8 @@ class CustomerIOMessagingPushMethodChannel @override Future getRegisteredDeviceToken() { - try { - return methodChannel - .invokeMethod(MethodConsts.getRegisteredDeviceToken) - .then((result) => result as String?); - } on PlatformException catch (exception) { - handleException(exception); - return Future.error( - exception.message ?? "Error fetching registered device token"); - } + return methodChannel + .invokeNativeMethod(NativeMethods.getRegisteredDeviceToken); } @override @@ -38,24 +32,10 @@ class CustomerIOMessagingPushMethodChannel return Future.value(true); } - try { - final arguments = { - TrackingConsts.message: message, - TrackingConsts.handleNotificationTrigger: handleNotificationTrigger, - }; - return methodChannel - .invokeMethod(MethodConsts.onMessageReceived, arguments) - .then((handled) => handled == true); - } on PlatformException catch (exception) { - handleException(exception); - return Future.error( - exception.message ?? "Error handling push notification"); - } - } - - void handleException(PlatformException exception) { - if (kDebugMode) { - print(exception); - } + return methodChannel + .invokeNativeMethod(NativeMethods.onMessageReceived, arguments: { + NativeMethodParams.message: message, + NativeMethodParams.handleNotificationTrigger: handleNotificationTrigger, + }).then((handled) => handled == true); } } diff --git a/test/customer_io_method_channel_test.dart b/test/customer_io_method_channel_test.dart index 22ba981..de459bc 100644 --- a/test/customer_io_method_channel_test.dart +++ b/test/customer_io_method_channel_test.dart @@ -1,6 +1,6 @@ import 'package:customer_io/customer_io_config.dart'; import 'package:customer_io/customer_io_enums.dart'; -import 'package:customer_io/customer_io_method_channel.dart'; +import 'package:customer_io/data_pipelines/customer_io_method_channel.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -153,11 +153,11 @@ void main() { 'setDeviceAttributes() should call platform method with correct arguments', () async { final Map args = { - 'traits': {'os': 'Android'} + 'attributes': {'os': 'Android'} }; final customerIO = CustomerIOMethodChannel(); - customerIO.setDeviceAttributes(attributes: args['traits']); + customerIO.setDeviceAttributes(attributes: args['attributes']); expectMethodInvocationArguments('setDeviceAttributes', args); }); diff --git a/test/customer_io_test.dart b/test/customer_io_test.dart index 13d7e3f..1af165c 100644 --- a/test/customer_io_test.dart +++ b/test/customer_io_test.dart @@ -1,7 +1,7 @@ import 'package:customer_io/customer_io.dart'; import 'package:customer_io/customer_io_config.dart'; import 'package:customer_io/customer_io_enums.dart'; -import 'package:customer_io/customer_io_platform_interface.dart'; +import 'package:customer_io/data_pipelines/customer_io_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -93,10 +93,10 @@ void main() { await CustomerIO.initialize(config: config); }); - test('identify() calls platform', () { + test('identify() calls platform', () async { const givenIdentifier = 'user@example.com'; final givenAttributes = {'name': 'John Doe'}; - CustomerIO.instance.identify( + await CustomerIO.instance.identify( userId: givenIdentifier, traits: givenAttributes, ); diff --git a/test/customer_io_test.mocks.dart b/test/customer_io_test.mocks.dart index 4a35717..00cc042 100644 --- a/test/customer_io_test.mocks.dart +++ b/test/customer_io_test.mocks.dart @@ -55,7 +55,7 @@ class MockTestCustomerIoPlatform extends _i1.Mock returnValueForMissingStub: _i2.Future.value(), ) as _i2.Future); @override - void identify({ + _i2.Future identify({ required String? userId, Map? traits = const {}, }) => @@ -68,18 +68,20 @@ class MockTestCustomerIoPlatform extends _i1.Mock #traits: traits, }, ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); @override - void clearIdentify() => super.noSuchMethod( + _i2.Future clearIdentify() => super.noSuchMethod( Invocation.method( #clearIdentify, [], ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); @override - void track({ + _i2.Future track({ required String? name, Map? properties = const {}, }) => @@ -92,10 +94,11 @@ class MockTestCustomerIoPlatform extends _i1.Mock #properties: properties, }, ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); @override - void trackMetric({ + _i2.Future trackMetric({ required String? deliveryID, required String? deviceToken, required _i5.MetricEvent? event, @@ -110,20 +113,22 @@ class MockTestCustomerIoPlatform extends _i1.Mock #event: event, }, ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); @override - void registerDeviceToken({required String? deviceToken}) => + _i2.Future registerDeviceToken({required String? deviceToken}) => super.noSuchMethod( Invocation.method( #registerDeviceToken, [], {#deviceToken: deviceToken}, ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); @override - void screen({ + _i2.Future screen({ required String? title, Map? properties = const {}, }) => @@ -136,27 +141,32 @@ class MockTestCustomerIoPlatform extends _i1.Mock #properties: properties, }, ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); @override - void setDeviceAttributes({required Map? attributes}) => + _i2.Future setDeviceAttributes( + {required Map? attributes}) => super.noSuchMethod( Invocation.method( #setDeviceAttributes, [], {#attributes: attributes}, ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); @override - void setProfileAttributes({required Map? attributes}) => + _i2.Future setProfileAttributes( + {required Map? attributes}) => super.noSuchMethod( Invocation.method( #setProfileAttributes, [], {#attributes: attributes}, ), - returnValueForMissingStub: null, + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), ); _i2.StreamSubscription subscribeToInAppEventListener( void Function(_i6.InAppEvent)? onEvent) =>