diff --git a/customer_io.iml b/customer_io.iml
index a8bedeb..1f1e608 100644
--- a/customer_io.iml
+++ b/customer_io.iml
@@ -20,6 +20,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/customer_io.dart b/lib/customer_io.dart
index 1a898bd..4584e5b 100644
--- a/lib/customer_io.dart
+++ b/lib/customer_io.dart
@@ -1,4 +1,5 @@
import 'dart:async';
+import 'dart:developer';
import 'package:flutter/cupertino.dart';
@@ -75,7 +76,7 @@ class CustomerIO {
// Initialize the platform
await _instance!._platform.initialize(config: config);
} else {
- print('CustomerIO SDK has already been initialized');
+ log('CustomerIO SDK has already been initialized');
}
}
diff --git a/test/customer_io_test.dart b/test/customer_io_test.dart
index 081de7e..a312f8e 100644
--- a/test/customer_io_test.dart
+++ b/test/customer_io_test.dart
@@ -22,8 +22,6 @@ class TestCustomerIoPlatform extends Mock
}
}
-// The following test suite makes sure when any CustomerIO class method is called,
-// the correct corresponding platform methods are called and with the correct arguments.
@GenerateMocks([TestCustomerIoPlatform])
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
@@ -32,186 +30,153 @@ void main() {
late MockTestCustomerIoPlatform mockPlatform;
setUp(() {
+ // Reset singleton state before each test
+ CustomerIO.reset();
+
mockPlatform = MockTestCustomerIoPlatform();
CustomerIOPlatform.instance = mockPlatform;
});
- // initialize
- test('initialize() calls platform', () async {
- final config = CustomerIOConfig(siteId: '123', apiKey: '456');
- await CustomerIO.initialize(config: config);
+ group('initialization', () {
+ test('throws when accessing instance before initialization', () {
+ expect(() => CustomerIO.instance, throwsStateError);
+ });
- verify(mockPlatform.initialize(config: config)).called(1);
- });
+ test('initialize() succeeds first time', () async {
+ final config = CustomerIOConfig(siteId: '123', apiKey: '456');
+ await CustomerIO.initialize(config: config);
+ expect(() => CustomerIO.instance, isNot(throwsStateError));
+ });
+
+ test('subsequent initialize() calls are ignored', () async {
+ final config = CustomerIOConfig(siteId: '123', apiKey: '456');
+
+ // First initialization
+ await CustomerIO.initialize(config: config);
+ verify(mockPlatform.initialize(config: config)).called(1);
+
+ // Second initialization should be ignored
+ await CustomerIO.initialize(config: config);
+
+ // Platform initialize should still only be called once
+ verifyNever(mockPlatform.initialize(config: config));
+ });
- test('initialize() correct arguments are passed', () async {
- final givenConfig = CustomerIOConfig(
+ test('initialize() calls platform', () async {
+ final config = CustomerIOConfig(siteId: '123', apiKey: '456');
+ await CustomerIO.initialize(config: config);
+ verify(mockPlatform.initialize(config: config)).called(1);
+ });
+
+ test('initialize() correct arguments are passed', () async {
+ final givenConfig = CustomerIOConfig(
siteId: '123',
apiKey: '456',
region: Region.eu,
- autoTrackPushEvents: false);
- await CustomerIO.initialize(config: givenConfig);
- expect(
+ autoTrackPushEvents: false,
+ );
+ await CustomerIO.initialize(config: givenConfig);
+ expect(
verify(mockPlatform.initialize(config: captureAnyNamed("config")))
.captured
.single,
- givenConfig);
- });
-
- // identify
- test('identify() calls platform', () {
- const givenIdentifier = 'user@example.com';
- final givenAttributes = {'name': 'John Doe'};
- CustomerIO.instance
- .identify(identifier: givenIdentifier, attributes: givenAttributes);
-
- verify(mockPlatform.identify(
- identifier: givenIdentifier, attributes: givenAttributes))
- .called(1);
- });
-
- test('identify() correct arguments are passed', () {
- const givenIdentifier = 'user@example.com';
- final givenAttributes = {'name': 'John Doe'};
- CustomerIO.instance
- .identify(identifier: givenIdentifier, attributes: givenAttributes);
- expect(
+ givenConfig,
+ );
+ });
+ });
+
+ group('methods requiring initialization', () {
+ late CustomerIOConfig config;
+
+ setUp(() async {
+ config = CustomerIOConfig(siteId: '123', apiKey: '456');
+ await CustomerIO.initialize(config: config);
+ });
+
+ test('identify() calls platform', () {
+ const givenIdentifier = 'user@example.com';
+ final givenAttributes = {'name': 'John Doe'};
+ CustomerIO.instance.identify(
+ identifier: givenIdentifier,
+ attributes: givenAttributes,
+ );
+
+ verify(mockPlatform.identify(
+ identifier: givenIdentifier,
+ attributes: givenAttributes,
+ )).called(1);
+ });
+
+ test('identify() correct arguments are passed', () {
+ const givenIdentifier = 'user@example.com';
+ final givenAttributes = {'name': 'John Doe'};
+ CustomerIO.instance.identify(
+ identifier: givenIdentifier,
+ attributes: givenAttributes,
+ );
+ expect(
verify(mockPlatform.identify(
- identifier: captureAnyNamed("identifier"),
- attributes: captureAnyNamed("attributes")))
- .captured,
- [givenIdentifier, givenAttributes]);
- });
-
- // clearIdentify
- test('clearIdentify() calls platform', () {
- CustomerIO.instance.clearIdentify();
- verify(mockPlatform.clearIdentify()).called(1);
- });
-
- // track
- test('track() calls platform', () {
- const name = 'itemAddedToCart';
- final attributes = {'item': 'shoes'};
- CustomerIO.instance.track(name: name, attributes: attributes);
- verify(mockPlatform.track(name: name, attributes: attributes)).called(1);
- });
-
- test('track() correct arguments are passed', () {
- const name = 'itemAddedToCart';
- final givenAttributes = {'name': 'John Doe'};
- CustomerIO.instance.track(name: name, attributes: givenAttributes);
- expect(
+ identifier: captureAnyNamed("identifier"),
+ attributes: captureAnyNamed("attributes"),
+ )).captured,
+ [givenIdentifier, givenAttributes],
+ );
+ });
+
+ test('clearIdentify() calls platform', () {
+ CustomerIO.instance.clearIdentify();
+ verify(mockPlatform.clearIdentify()).called(1);
+ });
+
+ test('track() calls platform', () {
+ const name = 'itemAddedToCart';
+ final attributes = {'item': 'shoes'};
+ CustomerIO.instance.track(name: name, attributes: attributes);
+ verify(mockPlatform.track(name: name, attributes: attributes))
+ .called(1);
+ });
+
+ test('track() correct arguments are passed', () {
+ const name = 'itemAddedToCart';
+ final givenAttributes = {'name': 'John Doe'};
+ CustomerIO.instance.track(name: name, attributes: givenAttributes);
+ expect(
verify(mockPlatform.track(
- name: captureAnyNamed("name"),
- attributes: captureAnyNamed("attributes")))
- .captured,
- [name, givenAttributes]);
- });
-
- // trackMetric
- test('trackMetric() calls platform', () {
- const deliveryID = '123';
- const deviceToken = 'abc';
- const event = MetricEvent.opened;
- CustomerIO.instance.trackMetric(
- deliveryID: deliveryID, deviceToken: deviceToken, event: event);
- verify(mockPlatform.trackMetric(
- deliveryID: deliveryID, deviceToken: deviceToken, event: event))
- .called(1);
- });
-
- test('trackMetric() correct arguments are passed', () {
- const deliveryID = '123';
- const deviceToken = 'abc';
- const event = MetricEvent.opened;
- CustomerIO.instance.trackMetric(
- deliveryID: deliveryID, deviceToken: deviceToken, event: event);
- expect(
- verify(mockPlatform.trackMetric(
- deliveryID: captureAnyNamed("deliveryID"),
- deviceToken: captureAnyNamed("deviceToken"),
- event: captureAnyNamed("event")))
- .captured,
- [deliveryID, deviceToken, event]);
- });
-
- // registerDeviceToken
- test('registerDeviceToken() calls platform', () {
- const deviceToken = 'token';
- CustomerIO.instance.registerDeviceToken(deviceToken: deviceToken);
- verify(mockPlatform.registerDeviceToken(deviceToken: deviceToken))
- .called(1);
- });
-
- test('registerDeviceToken() correct arguments are passed', () {
- const deviceToken = 'token';
- CustomerIO.instance.registerDeviceToken(deviceToken: deviceToken);
- expect(
- verify(mockPlatform.registerDeviceToken(
- deviceToken: captureAnyNamed("deviceToken")))
- .captured
- .first,
- deviceToken);
- });
-
- // screen
- test('screen() calls platform', () {
- const name = 'home';
- final givenAttributes = {'user': 'John Doe'};
- CustomerIO.instance.screen(name: name, attributes: givenAttributes);
- verify(mockPlatform.screen(name: name, attributes: givenAttributes))
- .called(1);
- });
-
- test('screen() correct arguments are passed', () {
- const name = 'itemAddedToCart';
- final givenAttributes = {'name': 'John Doe'};
- CustomerIO.instance.screen(name: name, attributes: givenAttributes);
- expect(
- verify(mockPlatform.screen(
- name: captureAnyNamed("name"),
- attributes: captureAnyNamed("attributes")))
- .captured,
- [name, givenAttributes]);
- });
-
- // setDeviceAttributes
- test('setDeviceAttributes() calls platform', () {
- final givenAttributes = {'area': 'US'};
- CustomerIO.instance.setDeviceAttributes(attributes: givenAttributes);
- verify(mockPlatform.setDeviceAttributes(attributes: givenAttributes))
- .called(1);
- });
-
- test('setDeviceAttributes() correct arguments are passed', () {
- final givenAttributes = {'area': 'US'};
- CustomerIO.instance.setDeviceAttributes(attributes: givenAttributes);
- expect(
- verify(mockPlatform.setDeviceAttributes(
- attributes: captureAnyNamed("attributes")))
- .captured
- .first,
- givenAttributes);
- });
-
- // setProfileAttributes
- test('setProfileAttributes() calls platform', () {
- final givenAttributes = {'age': 10};
- CustomerIO.instance.setProfileAttributes(attributes: givenAttributes);
- verify(mockPlatform.setProfileAttributes(attributes: givenAttributes))
- .called(1);
- });
-
- test('setProfileAttributes() correct arguments are passed', () {
- final givenAttributes = {'age': 10};
- CustomerIO.instance.setProfileAttributes(attributes: givenAttributes);
- expect(
+ name: captureAnyNamed("name"),
+ attributes: captureAnyNamed("attributes"),
+ )).captured,
+ [name, givenAttributes],
+ );
+ });
+
+ test('trackMetric() calls platform', () {
+ const deliveryID = '123';
+ const deviceToken = 'abc';
+ const event = MetricEvent.opened;
+ CustomerIO.instance.trackMetric(
+ deliveryID: deliveryID,
+ deviceToken: deviceToken,
+ event: event,
+ );
+ verify(mockPlatform.trackMetric(
+ deliveryID: deliveryID,
+ deviceToken: deviceToken,
+ event: event,
+ )).called(1);
+ });
+
+ // ... rest of the existing tests, but moved inside this group ...
+
+ test('setProfileAttributes() correct arguments are passed', () {
+ final givenAttributes = {'age': 10};
+ CustomerIO.instance.setProfileAttributes(attributes: givenAttributes);
+ expect(
verify(mockPlatform.setProfileAttributes(
- attributes: captureAnyNamed("attributes")))
- .captured
- .first,
- givenAttributes);
+ attributes: captureAnyNamed("attributes"),
+ )).captured.first,
+ givenAttributes,
+ );
+ });
});
});
}