From 15e18946e72ea8f76fb945d148ccee1c37a1ba13 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Fri, 10 Oct 2025 16:34:18 -0700 Subject: [PATCH 01/12] feat: add IterableEmbeddedManager class and update exports for embedded messages --- .../classes/IterableEmbeddedManager.ts | 66 +++++++++++++++++++ src/embedded/classes/index.ts | 1 + src/embedded/index.ts | 1 + src/index.tsx | 1 + 4 files changed, 69 insertions(+) create mode 100644 src/embedded/classes/IterableEmbeddedManager.ts create mode 100644 src/embedded/classes/index.ts create mode 100644 src/embedded/index.ts diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts new file mode 100644 index 000000000..95d558c10 --- /dev/null +++ b/src/embedded/classes/IterableEmbeddedManager.ts @@ -0,0 +1,66 @@ +import { IterableLogger } from '../../core/classes/IterableLogger'; + +/** + * Manages the embedded messages from Iterable. + */ +export class IterableEmbeddedManager { + /** + * Refreshes the local cache of your embedded manager system so that it aligns + * with the server. + * + * At key points during your app's lifecycle, you may want to manually refresh + * your app's local cache of embedded messages. For example, as users navigate + * around, on pull-to-refresh, etc. + * + * @returns A promise that returns messages that the user is *eligible* to see. + * + * @example + * ```typescript + * IterableEmbeddedManager.syncMessages().then(messages => { + * console.log('Messages:', messages); + * }); + * ``` + */ + syncMessages() { + IterableLogger.log('IterableEmbeddedManager.syncMessages'); + } + + getMessages(placementIds?: number[] | null) { + IterableLogger.log( + 'IterableEmbeddedManager.getMessages with placementIds', + placementIds + ); + } + + getPlacementIds() { + IterableLogger.log('IterableEmbeddedManager.getEmbeddedPlacementIds'); + } + + startSession() { + IterableLogger.log('IterableEmbeddedManager.startSession'); + } + + endSession() { + IterableLogger.log('IterableEmbeddedManager.endSession'); + } + + startImpression(messageId: string, placementId: number) { + IterableLogger.log( + 'IterableEmbeddedManager.startImpression', + messageId, + placementId + ); + } + + pauseImpression(messageId: string) { + IterableLogger.log('IterableEmbeddedManager.pauseImpression', messageId); + } + + handleClick() { + IterableLogger.log('IterableEmbeddedManager.handleClick'); + } + + trackClick() { + IterableLogger.log('IterableEmbeddedManager.trackClick'); + } +} diff --git a/src/embedded/classes/index.ts b/src/embedded/classes/index.ts new file mode 100644 index 000000000..be2af76f0 --- /dev/null +++ b/src/embedded/classes/index.ts @@ -0,0 +1 @@ +export * from './IterableEmbeddedManager'; diff --git a/src/embedded/index.ts b/src/embedded/index.ts new file mode 100644 index 000000000..d7d17c691 --- /dev/null +++ b/src/embedded/index.ts @@ -0,0 +1 @@ +export * from './classes'; diff --git a/src/index.tsx b/src/index.tsx index 240ac51f5..c9a014340 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -59,3 +59,4 @@ export { type IterableInboxProps, type IterableInboxRowViewModel, } from './inbox'; +export { IterableEmbeddedManager } from './embedded'; From 2a62913003144ad1f481cd1249aaa3ae0f9c5f4c Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Fri, 10 Oct 2025 17:05:31 -0700 Subject: [PATCH 02/12] feat: add embeddedManager property to Iterable class for managing embedded messages --- src/core/classes/Iterable.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index 9ef784679..ebb928cd6 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -20,6 +20,7 @@ import { IterableAuthResponse } from './IterableAuthResponse'; import type { IterableCommerceItem } from './IterableCommerceItem'; import { IterableConfig } from './IterableConfig'; import { IterableLogger } from './IterableLogger'; +import { IterableEmbeddedManager } from '../../embedded/classes/IterableEmbeddedManager'; const RNEventEmitter = new NativeEventEmitter(RNIterableAPI); @@ -79,6 +80,27 @@ export class Iterable { */ static authManager: IterableAuthManager = new IterableAuthManager(); + /** + * Embedded message manager for the current user. + * + * This property provides access to embedded message functionality including + * retrieving messages, displaying messages, removing messages, and more. + * + * **Documentation** + * - [Embedded Messaging Overview](https://support.iterable.com/hc/en-us/articles/23060529977364-Embedded-Messaging-Overview) + * - [Android Embedded Messaging](https://support.iterable.com/hc/en-us/articles/23061877893652-Embedded-Messages-with-Iterable-s-Android-SDK) + * - [iOS Embedded Messaging](https://support.iterable.com/hc/en-us/articles/23061840746900-Embedded-Messages-with-Iterable-s-iOS-SDK) + * + * @example + * ```typescript + * Iterable.embeddedManager.getMessages().then(messages => { + * console.log('Messages:', messages); + * }); + * ``` + */ + static embeddedManager: IterableEmbeddedManager = + new IterableEmbeddedManager(); + /** * Initializes the Iterable React Native SDK in your app's Javascript or Typescript code. * From 789ae831cebed8d79dc4917850e9134ea6564350 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Fri, 10 Oct 2025 20:48:10 -0700 Subject: [PATCH 03/12] refactor: remove unused methods and improve documentation in IterableEmbeddedManager --- .../classes/IterableEmbeddedManager.ts | 68 +++---------------- 1 file changed, 8 insertions(+), 60 deletions(-) diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts index 95d558c10..f6c59273b 100644 --- a/src/embedded/classes/IterableEmbeddedManager.ts +++ b/src/embedded/classes/IterableEmbeddedManager.ts @@ -1,66 +1,14 @@ -import { IterableLogger } from '../../core/classes/IterableLogger'; - /** - * Manages the embedded messages from Iterable. + * Manages embedded messages from Iterable. + * + * **Documentation** + * - [Embedded Messaging Overview](https://support.iterable.com/hc/en-us/articles/23060529977364-Embedded-Messaging-Overview) + * - [Android Embedded Messaging](https://support.iterable.com/hc/en-us/articles/23061877893652-Embedded-Messages-with-Iterable-s-Android-SDK) + * - [iOS Embedded Messaging](https://support.iterable.com/hc/en-us/articles/23061840746900-Embedded-Messages-with-Iterable-s-iOS-SDK) */ export class IterableEmbeddedManager { /** - * Refreshes the local cache of your embedded manager system so that it aligns - * with the server. - * - * At key points during your app's lifecycle, you may want to manually refresh - * your app's local cache of embedded messages. For example, as users navigate - * around, on pull-to-refresh, etc. - * - * @returns A promise that returns messages that the user is *eligible* to see. - * - * @example - * ```typescript - * IterableEmbeddedManager.syncMessages().then(messages => { - * console.log('Messages:', messages); - * }); - * ``` + * Whether the embedded manager is enabled. */ - syncMessages() { - IterableLogger.log('IterableEmbeddedManager.syncMessages'); - } - - getMessages(placementIds?: number[] | null) { - IterableLogger.log( - 'IterableEmbeddedManager.getMessages with placementIds', - placementIds - ); - } - - getPlacementIds() { - IterableLogger.log('IterableEmbeddedManager.getEmbeddedPlacementIds'); - } - - startSession() { - IterableLogger.log('IterableEmbeddedManager.startSession'); - } - - endSession() { - IterableLogger.log('IterableEmbeddedManager.endSession'); - } - - startImpression(messageId: string, placementId: number) { - IterableLogger.log( - 'IterableEmbeddedManager.startImpression', - messageId, - placementId - ); - } - - pauseImpression(messageId: string) { - IterableLogger.log('IterableEmbeddedManager.pauseImpression', messageId); - } - - handleClick() { - IterableLogger.log('IterableEmbeddedManager.handleClick'); - } - - trackClick() { - IterableLogger.log('IterableEmbeddedManager.trackClick'); - } + isEnabled = false; } From 9940f46b1f4c8cec2fe6252e1dc5a0a6bb3e07ea Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Fri, 10 Oct 2025 20:54:10 -0700 Subject: [PATCH 04/12] docs: enhance documentation --- src/embedded/classes/IterableEmbeddedManager.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts index f6c59273b..333dd3af7 100644 --- a/src/embedded/classes/IterableEmbeddedManager.ts +++ b/src/embedded/classes/IterableEmbeddedManager.ts @@ -1,6 +1,9 @@ /** * Manages embedded messages from Iterable. * + * Provides embedded message functionality including retrieving messages, + * displaying messages, removing messages, and more. + * * **Documentation** * - [Embedded Messaging Overview](https://support.iterable.com/hc/en-us/articles/23060529977364-Embedded-Messaging-Overview) * - [Android Embedded Messaging](https://support.iterable.com/hc/en-us/articles/23061877893652-Embedded-Messages-with-Iterable-s-Android-SDK) From e7d4ecbb6e05bffc26f9c8d92bc77abe29de3dd8 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Fri, 10 Oct 2025 21:08:42 -0700 Subject: [PATCH 05/12] feat: add embeddedMessagingEnabled property to IterableConfig --- src/core/classes/IterableConfig.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/core/classes/IterableConfig.ts b/src/core/classes/IterableConfig.ts index c8ee67400..cbe3cb665 100644 --- a/src/core/classes/IterableConfig.ts +++ b/src/core/classes/IterableConfig.ts @@ -319,6 +319,16 @@ export class IterableConfig { */ encryptionEnforced = false; + /** + * Should the SDK enable and use embedded messaging? + * + * **Documentation** + * - [Embedded Messaging Overview](https://support.iterable.com/hc/en-us/articles/23060529977364-Embedded-Messaging-Overview) + * - [Android Embedded Messaging](https://support.iterable.com/hc/en-us/articles/23061877893652-Embedded-Messages-with-Iterable-s-Android-SDK) + * - [iOS Embedded Messaging](https://support.iterable.com/hc/en-us/articles/23061840746900-Embedded-Messages-with-Iterable-s-iOS-SDK) + */ + embeddedMessagingEnabled = false; + /** * Converts the IterableConfig instance to a dictionary object. * @@ -368,6 +378,7 @@ export class IterableConfig { pushPlatform: this.pushPlatform, encryptionEnforced: this.encryptionEnforced, retryPolicy: this.retryPolicy, + embeddedMessagingEnabled: this.embeddedMessagingEnabled, }; } } From 8201c4da1e98bdf60e657e419940f33a3bb446d6 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Fri, 10 Oct 2025 22:16:56 -0700 Subject: [PATCH 06/12] feat: display embedded manager status in Embedded component --- example/src/components/Embedded/Embedded.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx index 806bb0c23..ce1348e48 100644 --- a/example/src/components/Embedded/Embedded.tsx +++ b/example/src/components/Embedded/Embedded.tsx @@ -1,4 +1,5 @@ import { Text, View } from 'react-native'; +import { Iterable } from '@iterable/react-native-sdk'; import styles from './Embedded.styles'; @@ -6,6 +7,13 @@ export const Embedded = () => { return ( EMBEDDED + + Does embedded class exist? {Iterable.embeddedManager ? 'Yes' : 'No'} + + + Is embedded manager enabled? + {Iterable.embeddedManager.isEnabled ? 'Yes' : 'No'} + ); }; From e13756e15412e8af05ac486756777148a85923a3 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 14 Oct 2025 16:04:58 -0700 Subject: [PATCH 07/12] feat: implement setEnabled method for managing embedded manager state --- example/src/components/Embedded/Embedded.tsx | 2 +- src/core/classes/Iterable.ts | 4 ++++ src/embedded/classes/IterableEmbeddedManager.ts | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx index ce1348e48..0baae1169 100644 --- a/example/src/components/Embedded/Embedded.tsx +++ b/example/src/components/Embedded/Embedded.tsx @@ -11,7 +11,7 @@ export const Embedded = () => { Does embedded class exist? {Iterable.embeddedManager ? 'Yes' : 'No'} - Is embedded manager enabled? + Is embedded manager enabled?{' '} {Iterable.embeddedManager.isEnabled ? 'Yes' : 'No'} diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index ebb928cd6..c46c1830b 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -177,6 +177,10 @@ export class Iterable { IterableLogger.setLoggingEnabled(config.logReactNativeSdkCalls ?? true); IterableLogger.setLogLevel(config.logLevel); + + Iterable.embeddedManager.setEnabled( + config.embeddedMessagingEnabled === true + ); } this.setupEventHandlers(); diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts index 333dd3af7..f792a62c5 100644 --- a/src/embedded/classes/IterableEmbeddedManager.ts +++ b/src/embedded/classes/IterableEmbeddedManager.ts @@ -14,4 +14,13 @@ export class IterableEmbeddedManager { * Whether the embedded manager is enabled. */ isEnabled = false; + + /** + * Sets whether the embedded manager is enabled. + * + * @param enabled - Whether the embedded manager is enabled. + */ + setEnabled(enabled: boolean) { + this.isEnabled = enabled; + } } From 2b4da8aaaf66637018d4924d6268aa5c382b78fd Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 18 Nov 2025 22:10:17 -0800 Subject: [PATCH 08/12] refactor: wrap components in SafeAreaView for improved layout consistency --- example/src/components/Commerce/Commerce.tsx | 57 ++++++++++---------- example/src/components/Embedded/Embedded.tsx | 7 +-- example/src/components/Login/Login.tsx | 7 +-- example/src/components/User/User.tsx | 7 +-- example/src/constants/styles/typography.ts | 1 - 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/example/src/components/Commerce/Commerce.tsx b/example/src/components/Commerce/Commerce.tsx index c840f9199..134a37706 100644 --- a/example/src/components/Commerce/Commerce.tsx +++ b/example/src/components/Commerce/Commerce.tsx @@ -1,4 +1,5 @@ import { Alert, Image, Pressable, ScrollView, Text, View } from 'react-native'; +import { SafeAreaView } from 'react-native-safe-area-context'; import { Iterable, IterableCommerceItem } from '@iterable/react-native-sdk'; @@ -32,35 +33,37 @@ export const Commerce = () => { }; return ( - - - Commerce - - Purchase will be tracked when "Buy" is clicked. See logs for - output. - - {items.map((item) => ( - - - - - - - {item.name} - {item.subtitle} - ${item.price} - handleClick(item)} - > - Buy - + + + + Commerce + + Purchase will be tracked when "Buy" is clicked. See logs for + output. + + {items.map((item) => ( + + + + + + + {item.name} + {item.subtitle} + ${item.price} + handleClick(item)} + > + Buy + + - - ))} - - + ))} + + + ); }; diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx index 0baae1169..3306e2cc4 100644 --- a/example/src/components/Embedded/Embedded.tsx +++ b/example/src/components/Embedded/Embedded.tsx @@ -1,11 +1,12 @@ -import { Text, View } from 'react-native'; import { Iterable } from '@iterable/react-native-sdk'; +import { Text } from 'react-native'; +import { SafeAreaView } from 'react-native-safe-area-context'; import styles from './Embedded.styles'; export const Embedded = () => { return ( - + EMBEDDED Does embedded class exist? {Iterable.embeddedManager ? 'Yes' : 'No'} @@ -14,7 +15,7 @@ export const Embedded = () => { Is embedded manager enabled?{' '} {Iterable.embeddedManager.isEnabled ? 'Yes' : 'No'} - + ); }; diff --git a/example/src/components/Login/Login.tsx b/example/src/components/Login/Login.tsx index 9712792ed..988e9c8db 100644 --- a/example/src/components/Login/Login.tsx +++ b/example/src/components/Login/Login.tsx @@ -1,3 +1,4 @@ +import { useMemo } from 'react'; import { ActivityIndicator, Pressable, @@ -5,7 +6,7 @@ import { TextInput, View, } from 'react-native'; -import { useMemo } from 'react'; +import { SafeAreaView } from 'react-native-safe-area-context'; import { colors, type Route } from '../../constants'; import { useIterableApp } from '../../hooks'; @@ -18,7 +19,7 @@ export const Login = ({ navigation }: RootStackScreenProps) => { const loginIsEnabled = useMemo(() => apiKey && userId, [apiKey, userId]); return ( - + {loginInProgress ? ( @@ -66,7 +67,7 @@ export const Login = ({ navigation }: RootStackScreenProps) => { )} - + ); }; diff --git a/example/src/components/User/User.tsx b/example/src/components/User/User.tsx index 23f8361a5..4f3ee5be1 100644 --- a/example/src/components/User/User.tsx +++ b/example/src/components/User/User.tsx @@ -1,6 +1,7 @@ import { Iterable } from '@iterable/react-native-sdk'; import { useEffect, useState } from 'react'; -import { Text, TouchableOpacity, View } from 'react-native'; +import { Text, TouchableOpacity } from 'react-native'; +import { SafeAreaView } from 'react-native-safe-area-context'; import { useIterableApp } from '../../hooks'; import styles from './User.styles'; @@ -18,13 +19,13 @@ export const User = () => { }, [isLoggedIn]); return ( - + Welcome Iterator Logged in as {loggedInAs} Logout - + ); }; diff --git a/example/src/constants/styles/typography.ts b/example/src/constants/styles/typography.ts index 09b6c2405..af8a3b8e4 100644 --- a/example/src/constants/styles/typography.ts +++ b/example/src/constants/styles/typography.ts @@ -6,7 +6,6 @@ export const appName: TextStyle = { fontWeight: 'bold', fontSize: 14, width: '100%', - marginTop: 41, marginBottom: 64, textTransform: 'uppercase', letterSpacing: 2, From 11f822736742c27c26190c98a11e109af3d8bc74 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 18 Nov 2025 22:23:27 -0800 Subject: [PATCH 09/12] feat: refactor IterableEmbeddedManager to use private variable --- example/src/hooks/useIterableApp.tsx | 2 ++ src/embedded/classes/IterableEmbeddedManager.ts | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/example/src/hooks/useIterableApp.tsx b/example/src/hooks/useIterableApp.tsx index 9f72f0cf8..f47f58ba1 100644 --- a/example/src/hooks/useIterableApp.tsx +++ b/example/src/hooks/useIterableApp.tsx @@ -192,6 +192,8 @@ export const IterableAppProvider: FunctionComponent< config.logLevel = IterableLogLevel.debug; + config.embeddedMessagingEnabled = true; + config.inAppHandler = () => IterableInAppShowResponse.show; if ( diff --git a/src/embedded/classes/IterableEmbeddedManager.ts b/src/embedded/classes/IterableEmbeddedManager.ts index f792a62c5..13a59ddda 100644 --- a/src/embedded/classes/IterableEmbeddedManager.ts +++ b/src/embedded/classes/IterableEmbeddedManager.ts @@ -13,7 +13,14 @@ export class IterableEmbeddedManager { /** * Whether the embedded manager is enabled. */ - isEnabled = false; + private _isEnabled = false; + + /** + * Gets whether the embedded manager is enabled. + */ + get isEnabled(): boolean { + return this._isEnabled; + } /** * Sets whether the embedded manager is enabled. @@ -21,6 +28,6 @@ export class IterableEmbeddedManager { * @param enabled - Whether the embedded manager is enabled. */ setEnabled(enabled: boolean) { - this.isEnabled = enabled; + this._isEnabled = enabled; } } From 935cf22ec866cc43217e29406ead2d41f17da236 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 18 Nov 2025 22:28:29 -0800 Subject: [PATCH 10/12] test: enhance Iterable configuration tests with additional assertions --- src/core/classes/Iterable.test.ts | 38 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/core/classes/Iterable.test.ts b/src/core/classes/Iterable.test.ts index bfe4c26f6..c4ec2c828 100644 --- a/src/core/classes/Iterable.test.ts +++ b/src/core/classes/Iterable.test.ts @@ -300,37 +300,39 @@ describe('Iterable', () => { // WHEN config is initialized const config = new IterableConfig(); // THEN config has default values - expect(config.pushIntegrationName).toBe(undefined); + expect(config.allowedProtocols).toEqual([]); + expect(config.androidSdkUseInMemoryStorageForInApps).toBe(false); + expect(config.authHandler).toBe(undefined); expect(config.autoPushRegistration).toBe(true); expect(config.checkForDeferredDeeplink).toBe(false); - expect(config.inAppDisplayInterval).toBe(30.0); - expect(config.urlHandler).toBe(undefined); expect(config.customActionHandler).toBe(undefined); + expect(config.dataRegion).toBe(IterableDataRegion.US); + expect(config.embeddedMessagingEnabled).toBe(false); + expect(config.encryptionEnforced).toBe(false); + expect(config.expiringAuthTokenRefreshPeriod).toBe(60.0); + expect(config.inAppDisplayInterval).toBe(30.0); expect(config.inAppHandler).toBe(undefined); - expect(config.authHandler).toBe(undefined); expect(config.logLevel).toBe(IterableLogLevel.debug); expect(config.logReactNativeSdkCalls).toBe(true); - expect(config.expiringAuthTokenRefreshPeriod).toBe(60.0); - expect(config.allowedProtocols).toEqual([]); - expect(config.androidSdkUseInMemoryStorageForInApps).toBe(false); + expect(config.pushIntegrationName).toBe(undefined); + expect(config.urlHandler).toBe(undefined); expect(config.useInMemoryStorageForInApps).toBe(false); - expect(config.dataRegion).toBe(IterableDataRegion.US); - expect(config.encryptionEnforced).toBe(false); const configDict = config.toDict(); - expect(configDict.pushIntegrationName).toBe(undefined); + expect(configDict.allowedProtocols).toEqual([]); + expect(configDict.androidSdkUseInMemoryStorageForInApps).toBe(false); + expect(configDict.authHandlerPresent).toBe(false); expect(configDict.autoPushRegistration).toBe(true); - expect(configDict.inAppDisplayInterval).toBe(30.0); - expect(configDict.urlHandlerPresent).toBe(false); expect(configDict.customActionHandlerPresent).toBe(false); + expect(configDict.dataRegion).toBe(IterableDataRegion.US); + expect(configDict.embeddedMessagingEnabled).toBe(false); + expect(configDict.encryptionEnforced).toBe(false); + expect(configDict.expiringAuthTokenRefreshPeriod).toBe(60.0); + expect(configDict.inAppDisplayInterval).toBe(30.0); expect(configDict.inAppHandlerPresent).toBe(false); - expect(configDict.authHandlerPresent).toBe(false); expect(configDict.logLevel).toBe(IterableLogLevel.debug); - expect(configDict.expiringAuthTokenRefreshPeriod).toBe(60.0); - expect(configDict.allowedProtocols).toEqual([]); - expect(configDict.androidSdkUseInMemoryStorageForInApps).toBe(false); + expect(configDict.pushIntegrationName).toBe(undefined); + expect(configDict.urlHandlerPresent).toBe(false); expect(configDict.useInMemoryStorageForInApps).toBe(false); - expect(configDict.dataRegion).toBe(IterableDataRegion.US); - expect(configDict.encryptionEnforced).toBe(false); }); }); From 047f94bb815f22cdc23aac8ca5ee3bdf779c22d0 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 18 Nov 2025 22:28:52 -0800 Subject: [PATCH 11/12] fix: update embeddedMessagingEnabled configuration to use nullish coalescing --- src/core/classes/Iterable.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/classes/Iterable.ts b/src/core/classes/Iterable.ts index 9985ae41a..fa11f9a16 100644 --- a/src/core/classes/Iterable.ts +++ b/src/core/classes/Iterable.ts @@ -196,7 +196,7 @@ export class Iterable { IterableLogger.setLogLevel(config.logLevel); Iterable.embeddedManager.setEnabled( - config.embeddedMessagingEnabled === true + config.embeddedMessagingEnabled ?? false ); } From 92c8c9ebb4e682d0a0924cbf168616a9945c59f0 Mon Sep 17 00:00:00 2001 From: Loren Posen Date: Tue, 18 Nov 2025 22:33:45 -0800 Subject: [PATCH 12/12] test: add unit tests for IterableEmbeddedManager and enhance Iterable configuration tests --- src/core/classes/Iterable.test.ts | 15 +++++ .../classes/IterableEmbeddedManager.test.ts | 59 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/embedded/classes/IterableEmbeddedManager.test.ts diff --git a/src/core/classes/Iterable.test.ts b/src/core/classes/Iterable.test.ts index c4ec2c828..1da4e4e00 100644 --- a/src/core/classes/Iterable.test.ts +++ b/src/core/classes/Iterable.test.ts @@ -1214,4 +1214,19 @@ describe('Iterable', () => { }); }); }); + + describe('embeddedManager', () => { + it('should be disabled by default', () => { + const config = new IterableConfig(); + expect(config.embeddedMessagingEnabled).toBe(false); + expect(Iterable.embeddedManager.isEnabled).toBe(false); + }); + + it('should enable embeddedManager when config is set', async () => { + const config = new IterableConfig(); + config.embeddedMessagingEnabled = true; + await Iterable.initialize('test-key', config); + expect(Iterable.embeddedManager.isEnabled).toBe(true); + }); + }); }); diff --git a/src/embedded/classes/IterableEmbeddedManager.test.ts b/src/embedded/classes/IterableEmbeddedManager.test.ts new file mode 100644 index 000000000..96a09ddf4 --- /dev/null +++ b/src/embedded/classes/IterableEmbeddedManager.test.ts @@ -0,0 +1,59 @@ +import { IterableEmbeddedManager } from './IterableEmbeddedManager'; + +describe('IterableEmbeddedManager', () => { + let embeddedManager: IterableEmbeddedManager; + + beforeEach(() => { + embeddedManager = new IterableEmbeddedManager(); + }); + + describe('isEnabled', () => { + it('should be false by default', () => { + expect(embeddedManager.isEnabled).toBe(false); + }); + + it('should return true after being enabled', () => { + embeddedManager.setEnabled(true); + expect(embeddedManager.isEnabled).toBe(true); + }); + + it('should return false after being disabled', () => { + embeddedManager.setEnabled(false); + expect(embeddedManager.isEnabled).toBe(false); + }); + }); + + describe('setEnabled', () => { + it('should enable the embedded manager', () => { + embeddedManager.setEnabled(true); + expect(embeddedManager.isEnabled).toBe(true); + }); + + it('should disable the embedded manager', () => { + embeddedManager.setEnabled(false); + expect(embeddedManager.isEnabled).toBe(false); + }); + + it('should toggle enabled state multiple times', () => { + embeddedManager.setEnabled(true); + expect(embeddedManager.isEnabled).toBe(true); + + embeddedManager.setEnabled(false); + expect(embeddedManager.isEnabled).toBe(false); + + embeddedManager.setEnabled(true); + expect(embeddedManager.isEnabled).toBe(true); + }); + + it('should handle setting the same state multiple times', () => { + embeddedManager.setEnabled(true); + embeddedManager.setEnabled(true); + expect(embeddedManager.isEnabled).toBe(true); + + embeddedManager.setEnabled(false); + embeddedManager.setEnabled(false); + expect(embeddedManager.isEnabled).toBe(false); + }); + }); +}); +