diff --git a/lib/models/Configuration.dart b/lib/models/Configuration.dart index 1c716e4..f5d1e76 100644 --- a/lib/models/Configuration.dart +++ b/lib/models/Configuration.dart @@ -56,7 +56,7 @@ class AndroidSettings { Map toJson() => { - 'firebaseOptions': firebaseOptions, + 'firebaseOptions': firebaseOptions.toJson(), 'notificationIcon': notificationIcon, 'multipleNotifications': multipleNotifications, 'notificationAccentColor': notificationAccentColor diff --git a/lib/models/Installation.dart b/lib/models/Installation.dart index 472e0de..9c4ad3f 100644 --- a/lib/models/Installation.dart +++ b/lib/models/Installation.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import 'package:collection/collection.dart'; enum OS { Android, iOS } @@ -25,26 +26,27 @@ class Installation { final String? deviceName; Map? customAttributes; - Installation( - {this.pushRegistrationId, - this.pushServiceType, - this.pushServiceToken, - this.isPrimaryDevice, - this.isPushRegistrationEnabled, - this.notificationsEnabled, - this.geoEnabled, - this.sdkVersion, - this.appVersion, - this.os, - this.osVersion, - this.deviceManufacturer, - this.deviceModel, - this.deviceSecure, - this.language, - this.deviceTimezoneOffset, - this.applicationUserId, - this.deviceName, - this.customAttributes}); + Installation({ + this.pushRegistrationId, + this.pushServiceType, + this.pushServiceToken, + this.isPrimaryDevice, + this.isPushRegistrationEnabled, + this.notificationsEnabled, + this.geoEnabled, + this.sdkVersion, + this.appVersion, + this.os, + this.osVersion, + this.deviceManufacturer, + this.deviceModel, + this.deviceSecure, + this.language, + this.deviceTimezoneOffset, + this.applicationUserId, + this.deviceName, + this.customAttributes, + }); static PushServiceType? resolvePushServiceType(String? pst) { if (pst == null) { @@ -70,27 +72,27 @@ class Installation { } Map toJson() => { - 'pushRegistrationId': pushRegistrationId, - 'pushServiceToken': pushServiceToken, - 'pushServiceType': - pushServiceType != null ? describeEnum(pushServiceType!) : null, - 'isPrimaryDevice': isPrimaryDevice, - 'isPushRegistrationEnabled': isPushRegistrationEnabled, - 'notificationsEnabled': notificationsEnabled, - 'geoEnabled': geoEnabled, - 'sdkVersion': sdkVersion, - 'appVersion': appVersion, - 'os': os != null ? describeEnum(os!) : null, - 'osVersion': osVersion, - 'deviceManufacturer': deviceManufacturer, - 'deviceModel': deviceModel, - 'deviceSecure': deviceSecure, - 'language': language, - 'deviceTimezoneOffset': deviceTimezoneOffset, - 'applicationUserId': applicationUserId, - 'deviceName': deviceName, - 'customAttributes': customAttributes, - }; + 'pushRegistrationId': pushRegistrationId, + 'pushServiceToken': pushServiceToken, + 'pushServiceType': + pushServiceType != null ? describeEnum(pushServiceType!) : null, + 'isPrimaryDevice': isPrimaryDevice, + 'isPushRegistrationEnabled': isPushRegistrationEnabled, + 'notificationsEnabled': notificationsEnabled, + 'geoEnabled': geoEnabled, + 'sdkVersion': sdkVersion, + 'appVersion': appVersion, + 'os': os != null ? describeEnum(os!) : null, + 'osVersion': osVersion, + 'deviceManufacturer': deviceManufacturer, + 'deviceModel': deviceModel, + 'deviceSecure': deviceSecure, + 'language': language, + 'deviceTimezoneOffset': deviceTimezoneOffset, + 'applicationUserId': applicationUserId, + 'deviceName': deviceName, + 'customAttributes': customAttributes, + }; Installation.fromJson(Map json) : isPrimaryDevice = json['isPrimaryDevice'], @@ -117,6 +119,54 @@ class Installation { String? getPushRegistrationId() { return this.pushRegistrationId; } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is Installation && + runtimeType == other.runtimeType && + pushRegistrationId == other.pushRegistrationId && + pushServiceToken == other.pushServiceToken && + pushServiceType == other.pushServiceType && + isPrimaryDevice == other.isPrimaryDevice && + isPushRegistrationEnabled == other.isPushRegistrationEnabled && + notificationsEnabled == other.notificationsEnabled && + geoEnabled == other.geoEnabled && + sdkVersion == other.sdkVersion && + appVersion == other.appVersion && + os == other.os && + osVersion == other.osVersion && + deviceManufacturer == other.deviceManufacturer && + deviceModel == other.deviceModel && + deviceSecure == other.deviceSecure && + language == other.language && + deviceTimezoneOffset == other.deviceTimezoneOffset && + applicationUserId == other.applicationUserId && + deviceName == other.deviceName && + DeepCollectionEquality() + .equals(customAttributes, other.customAttributes); + + @override + int get hashCode => + pushRegistrationId.hashCode ^ + pushServiceToken.hashCode ^ + pushServiceType.hashCode ^ + isPrimaryDevice.hashCode ^ + isPushRegistrationEnabled.hashCode ^ + notificationsEnabled.hashCode ^ + geoEnabled.hashCode ^ + sdkVersion.hashCode ^ + appVersion.hashCode ^ + os.hashCode ^ + osVersion.hashCode ^ + deviceManufacturer.hashCode ^ + deviceModel.hashCode ^ + deviceSecure.hashCode ^ + language.hashCode ^ + deviceTimezoneOffset.hashCode ^ + applicationUserId.hashCode ^ + deviceName.hashCode ^ + customAttributes.hashCode; } class InstallationPrimary { diff --git a/lib/models/UserData.dart b/lib/models/UserData.dart index a121369..706adff 100644 --- a/lib/models/UserData.dart +++ b/lib/models/UserData.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import 'package:collection/collection.dart'; enum Gender { Male, Female } @@ -16,15 +17,15 @@ class UserData { UserData( {this.externalUserId, - this.firstName, - this.lastName, - this.middleName, - this.gender, - this.birthday, - this.phones, - this.emails, - this.tags, - this.customAttributes}); + this.firstName, + this.lastName, + this.middleName, + this.gender, + this.birthday, + this.phones, + this.emails, + this.tags, + this.customAttributes}); static Gender? resolveGender(String? str) { if (str == null) { @@ -58,15 +59,45 @@ class UserData { customAttributes = json['customAttributes']; Map toJson() => { - 'externalUserId': externalUserId, - 'firstName': firstName, - 'lastName': lastName, - 'middleName': middleName, - 'gender': gender != null ? describeEnum(gender!) : null, - 'birthday': birthday, - 'phones': phones, - 'emails': emails, - 'tags': tags, - 'customAttributes': customAttributes - }; + 'externalUserId': externalUserId, + 'firstName': firstName, + 'lastName': lastName, + 'middleName': middleName, + 'gender': gender != null ? describeEnum(gender!) : null, + 'birthday': birthday, + 'phones': phones, + 'emails': emails, + 'tags': tags, + 'customAttributes': customAttributes + }; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is UserData && + runtimeType == other.runtimeType && + externalUserId == other.externalUserId && + firstName == other.firstName && + lastName == other.lastName && + middleName == other.middleName && + gender == other.gender && + birthday == other.birthday && + listEquals(phones, other.phones) && + listEquals(emails, other.emails) && + listEquals(tags, other.tags) && + DeepCollectionEquality() + .equals(customAttributes, other.customAttributes); + + @override + int get hashCode => + externalUserId.hashCode ^ + firstName.hashCode ^ + lastName.hashCode ^ + middleName.hashCode ^ + gender.hashCode ^ + birthday.hashCode ^ + phones.hashCode ^ + emails.hashCode ^ + tags.hashCode ^ + customAttributes.hashCode; } diff --git a/test/json_test.dart b/test/json_test.dart index cb68108..74ad6d9 100644 --- a/test/json_test.dart +++ b/test/json_test.dart @@ -1,124 +1,56 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:infobip_mobilemessaging/models/Configuration.dart'; +import 'package:infobip_mobilemessaging/models/Installation.dart'; import 'package:infobip_mobilemessaging/models/Message.dart'; +import 'package:infobip_mobilemessaging/models/UserData.dart'; + +import 'utils/json_test_stubs.dart'; +import 'utils/models_examples.dart'; void main() { - Configuration getConfiguration() { - return new Configuration( - applicationCode: 'abc', - pluginVersion: "1.2.3", - inAppChatEnabled: true, - androidSettings: AndroidSettings( - firebaseOptions: FirebaseOptions( - apiKey: "Some-API-Key", - applicationId: "1:1234567890:android:abc123", - projectId: "project-123ab" - ), - notificationIcon: 'icon.png', - multipleNotifications: true, - notificationAccentColor: "#ABCDEF"), - iosSettings: IOSSettings( - notificationTypes: ['sound'], - forceCleanup: true, - logging: true, - webViewSettings: WebViewSettings( - title: 'webViewTitle', - barTintColor: '#012345', - titleColor: '#135', - tintColor: '#246')), - privacySettings: PrivacySettings( - applicationCodePersistingDisabled: true, - userDataPersistingDisabled: true, - carrierInfoSendingDisabled: true, - systemInfoSendingDisabled: true), - notificationCategories: [ - NotificationCategory(identifier: '123', actions: [ - NotificationAction( - identifier: '123456', - title: 'Action Title', - foreground: true, - authenticationRequired: true, - moRequired: true, - destructive: true, - icon: 'icon-action.png', - textInputActionButtonTitle: 'Button Title', - textInputPlaceholder: 'Placeholder Title') - ]) - ], - defaultMessageStorage: true, - ); - } + group('toJSON', () { + test('Configuration', () { + expect(configurationModelExample.toJson(), configurationExampleJson); + }); - Message getMessage() { - return new Message( - messageId: 'mess-123', - title: 'Message Title', - body: 'message body', - sound: 'Sound1', - vibrate: true, - icon: 'icon.png', - silent: true, - category: 'Category1', - customPayload: {'customParam1': 'customValue1'}, - internalData: 'internalData1', - receivedTimestamp: 1234567890, - seenDate: 1234567890, - contentUrl: 'https://some.url', - seen: true, - geo: true, - originalPayload: {'param1': 'value1'}, - browserUrl: 'https://some-browser.url', - deeplink: 'https://some-deeplink.url', - webViewUrl: 'https://some-browser.url', - inAppOpenTitle: 'InApp Title', - inAppDismissTitle: 'Dismiss title', - chat: true - ); - } + test('Installation', () { + expect(installationModelExample.toJson(), installationExampleJson); + }); - Map getMessageMap() { - return { - 'messageId': 'mess-123', - 'title': 'Message Title', - 'body': 'message body', - 'sound': 'Sound1', - 'vibrate': true, - 'icon': 'icon.png', - 'silent': true, - 'category': 'Category1', - 'customPayload': {'customParam1': 'customValue1'}, - 'internalData': 'internalData1', - 'receivedTimestamp': 1234567890, - 'seenDate': 1234567890, - 'contentUrl': 'https://some.url', - 'seen': true, - 'geo': true, - 'originalPayload': {'param1': 'value1'}, - 'browserUrl': 'https://some-browser.url', - 'deeplink': 'https://some-deeplink.url', - 'webViewUrl': 'https://some-browser.url', - 'inAppOpenTitle': 'InApp Title', - 'inAppDismissTitle': 'Dismiss title', - 'chat': true - }; - } + test('InstallationPrimary', () { + expect(installationPrimaryModelExample.toJson(), + installationPrimaryExampleJson); + }); - group('toJSON', () { - test('Configuration', () { - Configuration configuration = getConfiguration(); - String jsonString = "{applicationCode: abc, pluginVersion: 1.2.3, inAppChatEnabled: true, androidSettings: {firebaseSenderId: ABC-XYZ, notificationIcon: icon.png, multipleNotifications: true, notificationAccentColor: #ABCDEF}, iosSettings: {notificationTypes: [sound], forceCleanup: true, logging: true, webViewSettings: {title: webViewTitle, barTintColor: #012345, titleColor: #135, tintColor: #246}}, privacySettings: {applicationCodePersistingDisabled: true, userDataPersistingDisabled: true, carrierInfoSendingDisabled: true, systemInfoSendingDisabled: true}, notificationCategories: ({identifier: 123, actions: [{identifier: 123456, title: Action Title, foreground: true, authenticationRequired: true, moRequired: true, destructive: true, icon: icon-action.png, textInputActionButtonTitle: Button Title, textInputPlaceholder: Placeholder Title}]}), defaultMessageStorage: true}"; + test('IOSChatSettings', () { + expect(iosChatSettingsModelExample.toJson(), iosChatSettingsExampleJson); + }); - expect(configuration.toJson().toString(), jsonString); + test('UserIdentity', () { + expect(userIdentityModelExample.toJson(), userIdentityExampleJson); + }); + + test('PersonalizeContext', () { + expect(personalizeContextModelExample.toJson(), + personalizeContextExampleJson); }); - }); + test('UserData', () { + expect(userDataModelExample.toJson(), userDataExampleJson); + }); + }); group('fromJSON', () { test('Message', () { - Message fromJson = Message.fromJson(getMessageMap()); - Message message = getMessage(); + expect(Message.fromJson(messageExampleJson), messageModelExample); + }); + + test('Installation', () { + expect(Installation.fromJson(installationExampleJson), + installationModelExample); + }); - expect(message, fromJson); + test('UserData', () { + expect(UserData.fromJson(userDataExampleJson), userDataModelExample); }); }); } diff --git a/test/utils/json_test_stubs.dart b/test/utils/json_test_stubs.dart new file mode 100755 index 0000000..35e8ded --- /dev/null +++ b/test/utils/json_test_stubs.dart @@ -0,0 +1,182 @@ +Map get configurationExampleJson => { + 'applicationCode': 'abc', + 'pluginVersion': '1.2.3', + 'inAppChatEnabled': true, + 'androidSettings': { + 'firebaseOptions': { + 'apiKey': 'Some-API-Key', + 'applicationId': '1:1234567890:android:abc123', + 'projectId': 'project-123ab', + 'databaseUrl': null, + 'gaTrackingId': null, + 'gcmSenderId': null, + 'storageBucket': null, + }, + 'notificationIcon': 'icon.png', + 'multipleNotifications': true, + 'notificationAccentColor': '#ABCDEF', + }, + 'iosSettings': { + 'notificationTypes': ['sound'], + 'forceCleanup': true, + 'logging': true, + 'webViewSettings': { + 'title': 'webViewTitle', + 'barTintColor': '#012345', + 'titleColor': '#135', + 'tintColor': '#246', + } + }, + 'privacySettings': { + 'applicationCodePersistingDisabled': true, + 'userDataPersistingDisabled': true, + 'carrierInfoSendingDisabled': true, + 'systemInfoSendingDisabled': true, + }, + 'notificationCategories': [ + { + 'identifier': '123', + 'actions': [ + { + 'identifier': '123456', + 'title': 'Action Title', + 'foreground': true, + 'authenticationRequired': true, + 'moRequired': true, + 'destructive': true, + 'icon': 'icon-action.png', + 'textInputActionButtonTitle': 'Button Title', + 'textInputPlaceholder': 'Placeholder Title', + }, + ], + }, + ], + 'defaultMessageStorage': true, + }; + +Map get installationExampleJson => { + 'pushRegistrationId': 'someRegistrationId', + 'pushServiceToken': 'pushServiceToken', + 'pushServiceType': 'GCM', + 'isPrimaryDevice': true, + 'isPushRegistrationEnabled': true, + 'notificationsEnabled': true, + 'geoEnabled': true, + 'sdkVersion': 'someSdkVersion', + 'appVersion': 'appVersion', + 'os': 'Android', + 'osVersion': '12.0', + 'deviceManufacturer': 'deviceManufacturer', + 'deviceModel': 'deviceModel', + 'deviceSecure': true, + 'language': 'EN', + 'deviceTimezoneOffset': '1234567', + 'applicationUserId': '123', + 'deviceName': 'deviceName', + 'customAttributes': { + 'alList': [ + { + 'alDate': '2021-10-11', + 'alWhole': 2, + 'alString': 'someAnotherString', + 'alBoolean': true, + 'alDecimal': 0.66 + }, + ], + } + }; + +Map get installationPrimaryExampleJson => { + 'pushRegistrationId': '123456', + 'primary': true, + }; + +Map get iosChatSettingsExampleJson => { + 'title': 'title', + 'sendButtonColor': 'green', + 'navigationBarItemsColor': 'red', + 'navigationBarColor': 'blue', + 'navigationBarTitleColor': 'yellow', + }; + +Map get userIdentityExampleJson => { + 'phones': [ + '123', + '234', + ], + 'emails': [ + 'test@gmail.com', + 'test2@gmail.com', + ], + 'externalUserId': '123456', + }; + +Map get personalizeContextExampleJson => { + 'userIdentity': userIdentityExampleJson, + 'userAttributes': { + 'alList': [ + { + 'alDate': '2021-10-11', + 'alWhole': 2, + 'alString': 'someAnotherString', + 'alBoolean': true, + 'alDecimal': 0.66 + }, + ], + }, + 'forceDepersonalize': true, + }; + +Map get userDataExampleJson => { + 'externalUserId': 'randomUID123', + 'firstName': 'First', + 'lastName': 'Last', + 'middleName': 'Middle', + 'gender': 'Male', + 'birthday': '01-01-1999', + 'phones': [ + '79123456789', + ], + 'emails': [ + 'some.email@email.com', + ], + 'tags': [ + 'randomTag', + ], + 'customAttributes': { + 'alList': [ + { + 'alDate': '2021-10-11', + 'alWhole': 2, + 'alString': 'someAnotherString', + 'alBoolean': true, + 'alDecimal': 0.66 + } + ] + } + }; + +Map get messageExampleJson => { + 'messageId': 'mess-123', + 'title': 'Message Title', + 'body': 'message body', + 'sound': 'Sound1', + 'vibrate': true, + 'icon': 'icon.png', + 'silent': true, + 'category': 'Category1', + 'customPayload': {'customParam1': 'customValue1'}, + 'internalData': 'internalData1', + 'receivedTimestamp': 1234567890, + 'seenDate': 1234567890, + 'contentUrl': 'https://some.url', + 'seen': true, + 'geo': true, + 'originalPayload': {'param1': 'value1'}, + 'browserUrl': 'https://some-browser.url', + 'deeplink': 'https://some-deeplink.url', + 'webViewUrl': 'https://some-browser.url', + 'inAppOpenTitle': 'InApp Title', + 'inAppDismissTitle': 'Dismiss title', + 'chat': true + }; diff --git a/test/utils/models_examples.dart b/test/utils/models_examples.dart new file mode 100644 index 0000000..3374e75 --- /dev/null +++ b/test/utils/models_examples.dart @@ -0,0 +1,176 @@ +import 'package:infobip_mobilemessaging/models/Configuration.dart'; +import 'package:infobip_mobilemessaging/models/IOSChatSettings.dart'; +import 'package:infobip_mobilemessaging/models/Installation.dart'; +import 'package:infobip_mobilemessaging/models/Message.dart'; +import 'package:infobip_mobilemessaging/models/PersonalizeContext.dart'; +import 'package:infobip_mobilemessaging/models/UserData.dart'; + +Configuration get configurationModelExample => Configuration( + applicationCode: 'abc', + pluginVersion: "1.2.3", + inAppChatEnabled: true, + androidSettings: AndroidSettings( + firebaseOptions: FirebaseOptions( + apiKey: "Some-API-Key", + applicationId: "1:1234567890:android:abc123", + projectId: "project-123ab"), + notificationIcon: 'icon.png', + multipleNotifications: true, + notificationAccentColor: "#ABCDEF"), + iosSettings: IOSSettings( + notificationTypes: ['sound'], + forceCleanup: true, + logging: true, + webViewSettings: WebViewSettings( + title: 'webViewTitle', + barTintColor: '#012345', + titleColor: '#135', + tintColor: '#246')), + privacySettings: PrivacySettings( + applicationCodePersistingDisabled: true, + userDataPersistingDisabled: true, + carrierInfoSendingDisabled: true, + systemInfoSendingDisabled: true), + notificationCategories: [ + NotificationCategory(identifier: '123', actions: [ + NotificationAction( + identifier: '123456', + title: 'Action Title', + foreground: true, + authenticationRequired: true, + moRequired: true, + destructive: true, + icon: 'icon-action.png', + textInputActionButtonTitle: 'Button Title', + textInputPlaceholder: 'Placeholder Title') + ]) + ], + defaultMessageStorage: true, + ); + +Installation get installationModelExample => Installation( + pushRegistrationId: 'someRegistrationId', + pushServiceToken: 'pushServiceToken', + pushServiceType: PushServiceType.GCM, + isPrimaryDevice: true, + isPushRegistrationEnabled: true, + notificationsEnabled: true, + geoEnabled: true, + sdkVersion: 'someSdkVersion', + appVersion: 'appVersion', + os: OS.Android, + osVersion: '12.0', + deviceManufacturer: 'deviceManufacturer', + deviceModel: 'deviceModel', + deviceSecure: true, + language: 'EN', + deviceTimezoneOffset: '1234567', + applicationUserId: '123', + deviceName: 'deviceName', + customAttributes: { + 'alList': [ + { + 'alDate': '2021-10-11', + 'alWhole': 2, + 'alString': 'someAnotherString', + 'alBoolean': true, + 'alDecimal': 0.66 + } + ] + }, + ); + +InstallationPrimary get installationPrimaryModelExample => InstallationPrimary( + '123456', + true, + ); + +IOSChatSettings get iosChatSettingsModelExample => IOSChatSettings( + title: 'title', + sendButtonColor: 'green', + navigationBarItemsColor: 'red', + navigationBarColor: 'blue', + navigationBarTitleColor: 'yellow', + ); + +UserIdentity get userIdentityModelExample => UserIdentity( + phones: [ + '123', + '234', + ], + emails: [ + 'test@gmail.com', + 'test2@gmail.com', + ], + externalUserId: '123456', + ); + +PersonalizeContext get personalizeContextModelExample => PersonalizeContext( + userIdentity: userIdentityModelExample, + forceDepersonalize: true, + userAttributes: { + 'alList': [ + { + 'alDate': '2021-10-11', + 'alWhole': 2, + 'alString': 'someAnotherString', + 'alBoolean': true, + 'alDecimal': 0.66 + } + ] + }, + ); + +UserData get userDataModelExample => UserData( + externalUserId: 'randomUID123', + firstName: 'First', + lastName: 'Last', + middleName: 'Middle', + gender: Gender.Male, + birthday: '01-01-1999', + phones: [ + '79123456789', + ], + emails: [ + 'some.email@email.com', + ], + tags: [ + 'randomTag', + ], + customAttributes: { + 'alList': [ + { + 'alDate': '2021-10-11', + 'alWhole': 2, + 'alString': 'someAnotherString', + 'alBoolean': true, + 'alDecimal': 0.66 + } + ] + }, + ); + +Message get messageModelExample => Message( + messageId: 'mess-123', + title: 'Message Title', + body: 'message body', + sound: 'Sound1', + vibrate: true, + icon: 'icon.png', + silent: true, + category: 'Category1', + customPayload: {'customParam1': 'customValue1'}, + internalData: 'internalData1', + receivedTimestamp: 1234567890, + seenDate: 1234567890, + contentUrl: 'https://some.url', + seen: true, + geo: true, + originalPayload: {'param1': 'value1'}, + browserUrl: 'https://some-browser.url', + deeplink: 'https://some-deeplink.url', + webViewUrl: 'https://some-browser.url', + inAppOpenTitle: 'InApp Title', + inAppDismissTitle: 'Dismiss title', + chat: true, + );