@@ -334,6 +334,8 @@ describe('Iterable', () => {
334334 expect ( config . pushIntegrationName ) . toBe ( undefined ) ;
335335 expect ( config . urlHandler ) . toBe ( undefined ) ;
336336 expect ( config . useInMemoryStorageForInApps ) . toBe ( false ) ;
337+ expect ( config . androidWakeDelayMs ) . toBe ( 1000 ) ;
338+ expect ( config . authCallbackTimeoutMs ) . toBe ( 1000 ) ;
337339 const configDict = config . toDict ( ) ;
338340 expect ( configDict . allowedProtocols ) . toEqual ( [ ] ) ;
339341 expect ( configDict . androidSdkUseInMemoryStorageForInApps ) . toBe ( false ) ;
@@ -350,6 +352,17 @@ describe('Iterable', () => {
350352 expect ( configDict . pushIntegrationName ) . toBe ( undefined ) ;
351353 expect ( configDict . urlHandlerPresent ) . toBe ( false ) ;
352354 expect ( configDict . useInMemoryStorageForInApps ) . toBe ( false ) ;
355+ expect ( configDict . androidWakeDelayMs ) . toBe ( 1000 ) ;
356+ expect ( configDict . authCallbackTimeoutMs ) . toBe ( 1000 ) ;
357+ } ) ;
358+
359+ it ( 'should allow overriding androidWakeDelayMs and authCallbackTimeoutMs' , ( ) => {
360+ const config = new IterableConfig ( ) ;
361+ config . androidWakeDelayMs = 1500 ;
362+ config . authCallbackTimeoutMs = 2500 ;
363+ const configDict = config . toDict ( ) ;
364+ expect ( configDict . androidWakeDelayMs ) . toBe ( 1500 ) ;
365+ expect ( configDict . authCallbackTimeoutMs ) . toBe ( 2500 ) ;
353366 } ) ;
354367 } ) ;
355368
@@ -1607,6 +1620,88 @@ describe('Iterable', () => {
16071620 expect ( MockLinking . openURL ) . toBeCalledWith ( expectedUrl ) ;
16081621 } ) ;
16091622 } ) ;
1623+
1624+ it ( 'should honor a custom androidWakeDelayMs on Android' , async ( ) => {
1625+ // GIVEN Android platform
1626+ Object . defineProperty ( Platform , 'OS' , {
1627+ value : 'android' ,
1628+ writable : true ,
1629+ } ) ;
1630+
1631+ // sets up event emitter
1632+ const nativeEmitter = new NativeEventEmitter ( ) ;
1633+ nativeEmitter . removeAllListeners ( IterableEventName . handleUrlCalled ) ;
1634+
1635+ // sets up config with a custom wake delay
1636+ const config = new IterableConfig ( ) ;
1637+ config . logReactNativeSdkCalls = false ;
1638+ config . androidWakeDelayMs = 300 ;
1639+ config . urlHandler = jest . fn ( ( ) => false ) ;
1640+
1641+ // initialize Iterable object
1642+ Iterable . initialize ( 'apiKey' , config ) ;
1643+
1644+ // GIVEN the link can be opened
1645+ MockLinking . canOpenURL = jest . fn ( async ( ) => true ) ;
1646+ MockLinking . openURL . mockReset ( ) ;
1647+
1648+ const expectedUrl = 'https://somewhere.com' ;
1649+ const dict = {
1650+ url : expectedUrl ,
1651+ context : {
1652+ action : { type : 'openUrl' } ,
1653+ source : IterableActionSource . inApp ,
1654+ } ,
1655+ } ;
1656+
1657+ // WHEN handleUrlCalled event is emitted
1658+ nativeEmitter . emit ( IterableEventName . handleUrlCalled , dict ) ;
1659+
1660+ // THEN the handler is called after the custom delay, not the default
1661+ return await TestHelper . delayed ( 400 , ( ) => {
1662+ expect ( config . urlHandler ) . toBeCalledWith ( expectedUrl , dict . context ) ;
1663+ expect ( MockLinking . openURL ) . toBeCalledWith ( expectedUrl ) ;
1664+ } ) ;
1665+ } ) ;
1666+
1667+ it ( 'should dispatch synchronously on Android when androidWakeDelayMs is 0' , async ( ) => {
1668+ // GIVEN Android platform
1669+ Object . defineProperty ( Platform , 'OS' , {
1670+ value : 'android' ,
1671+ writable : true ,
1672+ } ) ;
1673+
1674+ // sets up event emitter
1675+ const nativeEmitter = new NativeEventEmitter ( ) ;
1676+ nativeEmitter . removeAllListeners ( IterableEventName . handleUrlCalled ) ;
1677+
1678+ // sets up config with wake delay disabled
1679+ const config = new IterableConfig ( ) ;
1680+ config . logReactNativeSdkCalls = false ;
1681+ config . androidWakeDelayMs = 0 ;
1682+ config . urlHandler = jest . fn ( ( ) => false ) ;
1683+
1684+ // initialize Iterable object
1685+ Iterable . initialize ( 'apiKey' , config ) ;
1686+
1687+ MockLinking . canOpenURL = jest . fn ( async ( ) => true ) ;
1688+ MockLinking . openURL . mockReset ( ) ;
1689+
1690+ const expectedUrl = 'https://somewhere.com' ;
1691+ const dict = {
1692+ url : expectedUrl ,
1693+ context : {
1694+ action : { type : 'openUrl' } ,
1695+ source : IterableActionSource . inApp ,
1696+ } ,
1697+ } ;
1698+
1699+ // WHEN handleUrlCalled event is emitted
1700+ nativeEmitter . emit ( IterableEventName . handleUrlCalled , dict ) ;
1701+
1702+ // THEN the handler is invoked without a setTimeout delay
1703+ expect ( config . urlHandler ) . toBeCalledWith ( expectedUrl , dict . context ) ;
1704+ } ) ;
16101705 } ) ;
16111706
16121707 describe ( 're-initialization' , ( ) => {
@@ -1732,5 +1827,83 @@ describe('Iterable', () => {
17321827 expect ( failureCallback ) . not . toBeCalled ( ) ;
17331828 } ) ;
17341829 } ) ;
1830+
1831+ it ( 'should honor a custom authCallbackTimeoutMs for the safety-net timeout' , async ( ) => {
1832+ // sets up event emitter
1833+ const nativeEmitter = new NativeEventEmitter ( ) ;
1834+ nativeEmitter . removeAllListeners ( IterableEventName . handleAuthCalled ) ;
1835+ nativeEmitter . removeAllListeners (
1836+ IterableEventName . handleAuthSuccessCalled
1837+ ) ;
1838+ nativeEmitter . removeAllListeners (
1839+ IterableEventName . handleAuthFailureCalled
1840+ ) ;
1841+
1842+ // sets up config with a short custom auth callback timeout
1843+ const config = new IterableConfig ( ) ;
1844+ config . logReactNativeSdkCalls = false ;
1845+ config . authCallbackTimeoutMs = 200 ;
1846+ const successCallback = jest . fn ( ) ;
1847+ const failureCallback = jest . fn ( ) ;
1848+ const authResponse = new IterableAuthResponse ( ) ;
1849+ authResponse . authToken = 'short-timeout-token' ;
1850+ authResponse . successCallback = successCallback ;
1851+ authResponse . failureCallback = failureCallback ;
1852+ config . authHandler = jest . fn ( ( ) => Promise . resolve ( authResponse ) ) ;
1853+
1854+ // initialize Iterable object
1855+ Iterable . initialize ( 'apiKey' , config ) ;
1856+
1857+ // WHEN handleAuthCalled event is emitted but no success/failure event follows
1858+ nativeEmitter . emit ( IterableEventName . handleAuthCalled ) ;
1859+
1860+ // THEN the safety-net timer fires at the custom interval, not the default
1861+ return await TestHelper . delayed ( 300 , ( ) => {
1862+ expect ( MockRNIterableAPI . passAlongAuthToken ) . toBeCalledWith (
1863+ 'short-timeout-token'
1864+ ) ;
1865+ expect ( successCallback ) . not . toBeCalled ( ) ;
1866+ expect ( failureCallback ) . not . toBeCalled ( ) ;
1867+ } ) ;
1868+ } ) ;
1869+
1870+ it ( 'should resolve the latch immediately when the native success event arrives before the safety-net timeout' , async ( ) => {
1871+ // sets up event emitter
1872+ const nativeEmitter = new NativeEventEmitter ( ) ;
1873+ nativeEmitter . removeAllListeners ( IterableEventName . handleAuthCalled ) ;
1874+ nativeEmitter . removeAllListeners (
1875+ IterableEventName . handleAuthSuccessCalled
1876+ ) ;
1877+ nativeEmitter . removeAllListeners (
1878+ IterableEventName . handleAuthFailureCalled
1879+ ) ;
1880+
1881+ const config = new IterableConfig ( ) ;
1882+ config . logReactNativeSdkCalls = false ;
1883+ config . authCallbackTimeoutMs = 2000 ;
1884+ const successCallback = jest . fn ( ) ;
1885+ const failureCallback = jest . fn ( ) ;
1886+ const authResponse = new IterableAuthResponse ( ) ;
1887+ authResponse . authToken = 'fast-success-token' ;
1888+ authResponse . successCallback = successCallback ;
1889+ authResponse . failureCallback = failureCallback ;
1890+ config . authHandler = jest . fn ( ( ) => Promise . resolve ( authResponse ) ) ;
1891+
1892+ Iterable . initialize ( 'apiKey' , config ) ;
1893+
1894+ // WHEN handleAuthCalled and handleAuthSuccessCalled both fire
1895+ nativeEmitter . emit ( IterableEventName . handleAuthCalled ) ;
1896+ nativeEmitter . emit ( IterableEventName . handleAuthSuccessCalled ) ;
1897+
1898+ // THEN successCallback resolves on the microtask queue, well before the
1899+ // 2000ms safety-net timeout.
1900+ return await TestHelper . delayed ( 50 , ( ) => {
1901+ expect ( MockRNIterableAPI . passAlongAuthToken ) . toBeCalledWith (
1902+ 'fast-success-token'
1903+ ) ;
1904+ expect ( successCallback ) . toBeCalled ( ) ;
1905+ expect ( failureCallback ) . not . toBeCalled ( ) ;
1906+ } ) ;
1907+ } ) ;
17351908 } ) ;
17361909} ) ;
0 commit comments