diff --git a/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseAutoLogger.kt b/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseAutoLogger.kt index f3f3a14b5d..4c32945fba 100644 --- a/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseAutoLogger.kt +++ b/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseAutoLogger.kt @@ -8,10 +8,12 @@ package com.facebook.appevents.iap +import com.facebook.appevents.iap.InAppPurchaseUtils.BillingClientVersion.V2_V4 +import com.facebook.appevents.iap.InAppPurchaseUtils.BillingClientVersion.V5_Plus +import com.facebook.appevents.iap.InAppPurchaseUtils.IAPProductType.INAPP import android.content.Context import androidx.annotation.RestrictTo import com.facebook.internal.instrument.crashshield.AutoHandleExceptions -import java.util.Collections @AutoHandleExceptions @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @@ -19,27 +21,53 @@ object InAppPurchaseAutoLogger { private const val BILLING_CLIENT_PURCHASE_NAME = "com.android.billingclient.api.Purchase" @JvmStatic - fun startIapLogging(context: Context) { + fun startIapLogging( + context: Context, + billingClientVersion: InAppPurchaseUtils.BillingClientVersion + ) { // check if the app has IAP with Billing Lib if (InAppPurchaseUtils.getClass(BILLING_CLIENT_PURCHASE_NAME) == null) { return } - val billingClientWrapper = - InAppPurchaseBillingClientWrapper.getOrCreateInstance(context) ?: return - if (InAppPurchaseBillingClientWrapper.initialized.get()) { + + if (billingClientVersion == V2_V4) { + val billingClientWrapper = + InAppPurchaseBillingClientWrapper.getOrCreateInstance(context) ?: return + if (InAppPurchaseBillingClientWrapper.initialized.get()) { + if (InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()) { + billingClientWrapper.queryPurchaseHistory(INAPP) { + logPurchase(V2_V4) + } + } else { + billingClientWrapper.queryPurchase(INAPP) { + logPurchase(V2_V4) + } + } + } + } else if (billingClientVersion == V5_Plus) { + val billingClientWrapper = + InAppPurchaseBillingClientWrapperV5Plus.getOrCreateInstance(context) ?: return if (InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()) { - billingClientWrapper.queryPurchaseHistory(InAppPurchaseUtils.IAPProductType.INAPP) { logPurchase() } + billingClientWrapper.queryPurchaseHistoryAsync(INAPP) { logPurchase(V5_Plus) } } else { - billingClientWrapper.queryPurchase(InAppPurchaseUtils.IAPProductType.INAPP) { logPurchase() } + billingClientWrapper.queryPurchasesAsync(INAPP) { logPurchase(V5_Plus) } } } } - private fun logPurchase() { - InAppPurchaseLoggerManager.filterPurchaseLogging( - InAppPurchaseBillingClientWrapper.purchaseDetailsMap, - InAppPurchaseBillingClientWrapper.skuDetailsMap - ) - InAppPurchaseBillingClientWrapper.purchaseDetailsMap.clear() + private fun logPurchase(billingClientVersion: InAppPurchaseUtils.BillingClientVersion) { + if (billingClientVersion == V2_V4) { + InAppPurchaseLoggerManager.filterPurchaseLogging( + InAppPurchaseBillingClientWrapper.purchaseDetailsMap, + InAppPurchaseBillingClientWrapper.skuDetailsMap + ) + InAppPurchaseBillingClientWrapper.purchaseDetailsMap.clear() + } else { + InAppPurchaseLoggerManager.filterPurchaseLogging( + InAppPurchaseBillingClientWrapperV5Plus.purchaseDetailsMap, + InAppPurchaseBillingClientWrapperV5Plus.productDetailsMap + ) + InAppPurchaseBillingClientWrapperV5Plus.purchaseDetailsMap.clear() + } } } diff --git a/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5Plus.kt b/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5Plus.kt index 3163ebed1c..b990625871 100644 --- a/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5Plus.kt +++ b/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5Plus.kt @@ -265,12 +265,15 @@ private constructor( ) } - fun queryPurchasesAsync(productType: InAppPurchaseUtils.IAPProductType) { + fun queryPurchasesAsync( + productType: InAppPurchaseUtils.IAPProductType, + loggingRunnable: Runnable + ) { val runnableQuery = Runnable { val listenerObj = Proxy.newProxyInstance( purchasesResponseListenerClazz.classLoader, arrayOf(purchasesResponseListenerClazz), - ListenerWrapper(arrayOf(productType)) + ListenerWrapper(arrayOf(productType, loggingRunnable)) ) invokeMethod( billingClientClazz, @@ -283,12 +286,14 @@ private constructor( executeServiceRequest(runnableQuery) } - fun queryPurchaseHistoryAsync(productType: InAppPurchaseUtils.IAPProductType) { + fun queryPurchaseHistoryAsync( + productType: InAppPurchaseUtils.IAPProductType, loggingRunnable: Runnable + ) { val runnableQuery = Runnable { val listenerObj = Proxy.newProxyInstance( purchaseHistoryResponseListenerClazz.classLoader, arrayOf(purchaseHistoryResponseListenerClazz), - ListenerWrapper(arrayOf(productType)) + ListenerWrapper(arrayOf(productType, loggingRunnable)) ) invokeMethod( billingClientClazz, @@ -303,13 +308,14 @@ private constructor( private fun queryProductDetailsAsync( productType: InAppPurchaseUtils.IAPProductType, - productIds: List + productIds: List, + loggingRunnable: Runnable ) { val runnableQuery = Runnable { val listenerObj = Proxy.newProxyInstance( productDetailsResponseListenerClazz.classLoader, arrayOf(productDetailsResponseListenerClazz), - ListenerWrapper(null) + ListenerWrapper(arrayOf(loggingRunnable)) ) val queryProductDetailsParams = getQueryProductDetailsParams(productType, productIds) if (queryProductDetailsParams != null) { @@ -353,17 +359,23 @@ private constructor( return matchResult?.groupValues?.get(1) } + @AutoHandleExceptions private fun onQueryPurchasesResponse(wrapperArgs: Array?, listenerArgs: Array?) { val productType = wrapperArgs?.get(0) if (productType == null || productType !is InAppPurchaseUtils.IAPProductType) { return } + val loggingRunnable = wrapperArgs.get(1) + if (loggingRunnable !is Runnable) { + return + } val purchaseList = listenerArgs?.get(1) if (purchaseList == null || purchaseList !is List<*>) { return } val productIds = mutableListOf() + var newPurchasesToBeLogged = false for (purchase in purchaseList) { val purchaseJsonStr = invokeMethod( @@ -378,10 +390,15 @@ private constructor( productIds.add(productId) } purchaseDetailsMap[productId] = purchaseJson + newPurchasesToBeLogged = true } } if (productIds.isNotEmpty()) { - queryProductDetailsAsync(productType, productIds) + queryProductDetailsAsync(productType, productIds, loggingRunnable) + } else if (newPurchasesToBeLogged) { + // If there is at least one purchase to be logged, but productIds is empty, + // it means we already have the productDetails and can log immediately. + loggingRunnable.run() } } @@ -391,11 +408,17 @@ private constructor( if (productType == null || productType !is InAppPurchaseUtils.IAPProductType) { return } + val loggingRunnable = wrapperArgs.get(1) + if (loggingRunnable !is Runnable) { + return + } val purchaseHistoryRecordList = listenerArgs?.get(1) + if (purchaseHistoryRecordList == null || purchaseHistoryRecordList !is List<*>) { return } val productIds = mutableListOf() + var newPurchasesToBeLogged = false for (purchaseHistoryRecord in purchaseHistoryRecordList) { try { val purchaseHistoryRecordJsonStr = invokeMethod( @@ -412,18 +435,24 @@ private constructor( productIds.add(productId) } purchaseDetailsMap[productId] = purchaseHistoryRecordJson + newPurchasesToBeLogged = true } } catch (e: Exception) { /* swallow */ } } if (productIds.isNotEmpty()) { - queryProductDetailsAsync(productType, productIds) + queryProductDetailsAsync(productType, productIds, loggingRunnable) + } else if (newPurchasesToBeLogged) { + // If there is at least one purchase to be logged, but productIds is empty, + // it means we already have the productDetails and can log immediately. + loggingRunnable.run() } } @AutoHandleExceptions private fun onProductDetailsResponse(wrapperArgs: Array?, listenerArgs: Array?) { + val loggingRunnable = wrapperArgs?.get(0) val productDetailsList = listenerArgs?.get(1) if (productDetailsList == null || productDetailsList !is List<*>) { @@ -445,6 +474,9 @@ private constructor( } catch (e: Exception) { /* swallow */ } + if (loggingRunnable != null && loggingRunnable is Runnable) { + loggingRunnable.run() + } } } diff --git a/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseManager.kt b/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseManager.kt index a19c61c9fe..e55091cfaf 100644 --- a/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseManager.kt +++ b/facebook-core/src/main/java/com/facebook/appevents/iap/InAppPurchaseManager.kt @@ -34,26 +34,33 @@ object InAppPurchaseManager { @JvmStatic fun startTracking() { + if (!enabled.get()) { return } // Delegate IAP logic to separate handler based on Google Play Billing Library version - when (getIAPHandler()) { + when (val billingClientVersion = getBillingClientVersion()) { NONE -> return V1 -> InAppPurchaseActivityLifecycleTracker.startIapLogging() V2_V4 -> { if (isEnabled(FeatureManager.Feature.IapLoggingLib2)) { - InAppPurchaseAutoLogger.startIapLogging(getApplicationContext()) + InAppPurchaseAutoLogger.startIapLogging( + getApplicationContext(), + billingClientVersion + ) } else { InAppPurchaseActivityLifecycleTracker.startIapLogging() } } - V5_Plus -> return + V5_Plus -> InAppPurchaseAutoLogger.startIapLogging( + getApplicationContext(), + billingClientVersion + ) } } - private fun getIAPHandler(): InAppPurchaseUtils.BillingClientVersion { + private fun getBillingClientVersion(): InAppPurchaseUtils.BillingClientVersion { try { val context = getApplicationContext() val info = diff --git a/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseAutoLoggerTest.kt b/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseAutoLoggerTest.kt index df24d77eef..e5f1af3dc6 100644 --- a/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseAutoLoggerTest.kt +++ b/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseAutoLoggerTest.kt @@ -23,83 +23,140 @@ import org.powermock.reflect.Whitebox @PrepareForTest( InAppPurchaseBillingClientWrapper::class, + InAppPurchaseBillingClientWrapperV5Plus::class, InAppPurchaseUtils::class, - InAppPurchaseLoggerManager::class) + InAppPurchaseLoggerManager::class +) class InAppPurchaseAutoLoggerTest : FacebookPowerMockTestCase() { - private lateinit var mockBillingClientWrapper: InAppPurchaseBillingClientWrapper - private lateinit var mockContext: Context - private val className = "com.facebook.appevents.iap.InAppPurchaseAutoLoggerTest" - @Before - fun init() { - mockBillingClientWrapper = mock() - mockContext = mock() - PowerMockito.mockStatic(InAppPurchaseBillingClientWrapper::class.java) + private lateinit var mockBillingClientWrapperV2_V4: InAppPurchaseBillingClientWrapper + private lateinit var mockBillingClientWrapperV5Plus: InAppPurchaseBillingClientWrapperV5Plus + private lateinit var mockContext: Context + private val className = "com.facebook.appevents.iap.InAppPurchaseAutoLoggerTest" - PowerMockito.mockStatic(InAppPurchaseLoggerManager::class.java) - PowerMockito.mockStatic(InAppPurchaseUtils::class.java) - PowerMockito.doAnswer { Class.forName(className) } - .`when`(InAppPurchaseUtils::class.java, "getClass", any()) + @Before + fun init() { + mockBillingClientWrapperV2_V4 = mock() + mockBillingClientWrapperV5Plus = mock() + mockContext = mock() + PowerMockito.mockStatic(InAppPurchaseBillingClientWrapper::class.java) + PowerMockito.mockStatic(InAppPurchaseBillingClientWrapperV5Plus::class.java) + PowerMockito.mockStatic(InAppPurchaseLoggerManager::class.java) + PowerMockito.mockStatic(InAppPurchaseUtils::class.java) + PowerMockito.doAnswer { Class.forName(className) } + .`when`(InAppPurchaseUtils::class.java, "getClass", any()) - Whitebox.setInternalState( - InAppPurchaseBillingClientWrapper::class.java, "initialized", AtomicBoolean(true)) + Whitebox.setInternalState( + InAppPurchaseBillingClientWrapper::class.java, "initialized", AtomicBoolean(true) + ) - Whitebox.setInternalState( - InAppPurchaseBillingClientWrapper::class.java, "instance", mockBillingClientWrapper) - } + Whitebox.setInternalState( + InAppPurchaseBillingClientWrapper::class.java, "instance", mockBillingClientWrapperV2_V4 + ) - @Test - fun testStartIapLoggingNotCallLogPurchase() { - var logPurchaseCallTimes = 0 - Whitebox.setInternalState( - InAppPurchaseBillingClientWrapper::class.java, "isServiceConnected", AtomicBoolean(false)) - whenever(InAppPurchaseLoggerManager.filterPurchaseLogging(any(), any())).thenAnswer { - logPurchaseCallTimes++ - Unit + Whitebox.setInternalState( + InAppPurchaseBillingClientWrapperV5Plus::class.java, + "instance", + mockBillingClientWrapperV5Plus + ) } - assertThat(logPurchaseCallTimes).isEqualTo(0) - } - @Test - fun testStartIapLoggingWhenEligibleQueryPurchaseHistory() { - var logPurchaseCallTimes = 0 - var runnable: Runnable? = null - Whitebox.setInternalState( - InAppPurchaseBillingClientWrapper::class.java, "isServiceConnected", AtomicBoolean(true)) - whenever(InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()).thenReturn(true) - whenever(InAppPurchaseLoggerManager.filterPurchaseLogging(any(), any())).thenAnswer { - logPurchaseCallTimes++ - Unit - } - whenever(mockBillingClientWrapper.queryPurchaseHistory(any(), any())).thenAnswer { - runnable = it.getArgument(1) as Runnable - Unit + @Test + fun testStartIapLoggingNotCallLogPurchase() { + var logPurchaseCallTimes = 0 + Whitebox.setInternalState( + InAppPurchaseBillingClientWrapper::class.java, + "isServiceConnected", + AtomicBoolean(false) + ) + whenever(InAppPurchaseLoggerManager.filterPurchaseLogging(any(), any())).thenAnswer { + logPurchaseCallTimes++ + Unit + } + assertThat(logPurchaseCallTimes).isEqualTo(0) } - InAppPurchaseAutoLogger.startIapLogging(mockContext) - assertThat(runnable).isNotNull - runnable?.run() - assertThat(logPurchaseCallTimes).isEqualTo(1) - } + @Test + fun testStartIapLoggingWhenEligibleQueryPurchaseHistory_V2_V4() { + var logPurchaseCallTimes = 0 + var runnable: Runnable? = null + Whitebox.setInternalState( + InAppPurchaseBillingClientWrapper::class.java, "isServiceConnected", AtomicBoolean(true) + ) + whenever(InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()).thenReturn(true) + whenever(InAppPurchaseLoggerManager.filterPurchaseLogging(any(), any())).thenAnswer { + logPurchaseCallTimes++ + Unit + } + whenever(mockBillingClientWrapperV2_V4.queryPurchaseHistory(any(), any())).thenAnswer { + runnable = it.getArgument(1) as Runnable + Unit + } - @Test - fun testStartIapLoggingWhenNotEligibleQueryPurchaseHistory() { - var logPurchaseCallTimes = 0 - var runnable: Runnable? = null - Whitebox.setInternalState( - InAppPurchaseBillingClientWrapper::class.java, "isServiceConnected", AtomicBoolean(true)) - whenever(InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()).thenReturn(false) - whenever(InAppPurchaseLoggerManager.filterPurchaseLogging(any(), any())).thenAnswer { - logPurchaseCallTimes++ - Unit + InAppPurchaseAutoLogger.startIapLogging( + mockContext, + InAppPurchaseUtils.BillingClientVersion.V2_V4 + ) + assertThat(runnable).isNotNull + runnable?.run() + assertThat(logPurchaseCallTimes).isEqualTo(1) } - whenever(mockBillingClientWrapper.queryPurchase(any(), any())).thenAnswer { - runnable = it.getArgument(1) as Runnable - Unit + + @Test + fun testStartIapLoggingWhenNotEligibleQueryPurchaseHistory_V2_V4() { + var logPurchaseCallTimes = 0 + var runnable: Runnable? = null + Whitebox.setInternalState( + InAppPurchaseBillingClientWrapper::class.java, "isServiceConnected", AtomicBoolean(true) + ) + whenever(InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()).thenReturn(false) + whenever(InAppPurchaseLoggerManager.filterPurchaseLogging(any(), any())).thenAnswer { + logPurchaseCallTimes++ + Unit + } + whenever(mockBillingClientWrapperV2_V4.queryPurchase(any(), any())).thenAnswer { + runnable = it.getArgument(1) as Runnable + Unit + } + + InAppPurchaseAutoLogger.startIapLogging( + mockContext, + InAppPurchaseUtils.BillingClientVersion.V2_V4 + ) + assertThat(runnable).isNotNull + runnable?.run() + assertThat(logPurchaseCallTimes).isEqualTo(1) } - InAppPurchaseAutoLogger.startIapLogging(mockContext) - assertThat(runnable).isNotNull - runnable?.run() - assertThat(logPurchaseCallTimes).isEqualTo(1) - } + @Test + fun testStartIapLoggingWhenEligibleQueryPurchaseHistory_V5_Plus() { + var logPurchaseCallTimes = 0 + var runnable: Runnable? = null + Whitebox.setInternalState( + InAppPurchaseBillingClientWrapperV5Plus::class.java, + "isServiceConnected", + AtomicBoolean(true) + ) + whenever(InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()).thenReturn(true) + whenever(InAppPurchaseLoggerManager.filterPurchaseLogging(any(), any())).thenAnswer { + logPurchaseCallTimes++ + Unit + } + whenever( + mockBillingClientWrapperV5Plus.queryPurchaseHistoryAsync( + any(), + any() + ) + ).thenAnswer { + runnable = it.getArgument(1) as Runnable + Unit + } + + InAppPurchaseAutoLogger.startIapLogging( + mockContext, + InAppPurchaseUtils.BillingClientVersion.V5_Plus + ) + assertThat(runnable).isNotNull + runnable?.run() + assertThat(logPurchaseCallTimes).isEqualTo(1) + } } diff --git a/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5PlusTest.kt b/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5PlusTest.kt index cbac822147..66c95d998f 100644 --- a/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5PlusTest.kt +++ b/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseBillingClientWrapperV5PlusTest.kt @@ -207,9 +207,10 @@ class InAppPurchaseBillingClientWrapperV5PlusTest : FacebookPowerMockTestCase() fun testQueryPurchasesAsync() { val billingResult: Any = mock() val proxy: Any = mock() + val runnable: Runnable = mock() val purchase: Any = mock() val productType: Any = InAppPurchaseUtils.IAPProductType.INAPP - val wrapperArgs = arrayOf(productType) + val wrapperArgs = arrayOf(productType, runnable) val purchaseList: List<*> = listOf(purchase) val args = arrayOf(billingResult, purchaseList) @@ -232,15 +233,17 @@ class InAppPurchaseBillingClientWrapperV5PlusTest : FacebookPowerMockTestCase() ) Assertions.assertThat(InAppPurchaseBillingClientWrapperV5Plus.purchaseDetailsMap["product_1"].toString()) .isEqualTo(JSONObject(purchaseJsonStr).toString()) + } @Test fun testQueryPurchaseHistoryAsync() { val billingResult: Any = mock() val proxy: Any = mock() + val runnable: Runnable = mock() val purchaseHistoryRecord: Any = mock() val productType: Any = InAppPurchaseUtils.IAPProductType.INAPP - val wrapperArgs = arrayOf(productType) + val wrapperArgs = arrayOf(productType, runnable) val purchaseHistoryRecordList: List<*> = listOf(purchaseHistoryRecord) val args = arrayOf(billingResult, purchaseHistoryRecordList) diff --git a/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseManagerTest.kt b/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseManagerTest.kt index ebc00953ae..782bc223da 100644 --- a/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseManagerTest.kt +++ b/facebook-core/src/test/kotlin/com/facebook/appevents/iap/InAppPurchaseManagerTest.kt @@ -19,6 +19,7 @@ import java.util.concurrent.atomic.AtomicBoolean import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.mockito.kotlin.any +import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.whenever import org.powermock.api.mockito.PowerMockito @@ -50,7 +51,7 @@ class InAppPurchaseManagerTest : FacebookPowerMockTestCase() { @Test fun `test start iap logging when billing lib 2+ is not available`() { MemberModifier.stub( - PowerMockito.method(InAppPurchaseManager::class.java, "getIAPHandler") + PowerMockito.method(InAppPurchaseManager::class.java, "getBillingClientVersion") ) .toReturn(InAppPurchaseUtils.BillingClientVersion.V1) var isStartIapLoggingCalled = false @@ -65,7 +66,7 @@ class InAppPurchaseManagerTest : FacebookPowerMockTestCase() { @Test fun `test start iap logging when cant find dependency`() { MemberModifier.stub( - PowerMockito.method(InAppPurchaseManager::class.java, "getIAPHandler") + PowerMockito.method(InAppPurchaseManager::class.java, "getBillingClientVersion") ) .toReturn(InAppPurchaseUtils.BillingClientVersion.NONE) var isStartIapLoggingCalled = false @@ -80,7 +81,7 @@ class InAppPurchaseManagerTest : FacebookPowerMockTestCase() { @Test fun `test start iap logging when billing lib 2+ is available but feature is off`() { MemberModifier.stub( - PowerMockito.method(InAppPurchaseManager::class.java, "getIAPHandler") + PowerMockito.method(InAppPurchaseManager::class.java, "getBillingClientVersion") ) .toReturn(InAppPurchaseUtils.BillingClientVersion.V2_V4) whenever(FeatureManager.isEnabled(FeatureManager.Feature.IapLoggingLib2)).thenReturn(false) @@ -111,11 +112,47 @@ class InAppPurchaseManagerTest : FacebookPowerMockTestCase() { mockApplicationInfo.metaData = metaData var isStartIapLoggingCalled = false - whenever(InAppPurchaseAutoLogger.startIapLogging(any())).thenAnswer { + whenever( + InAppPurchaseAutoLogger.startIapLogging( + any(), + eq(InAppPurchaseUtils.BillingClientVersion.V2_V4) + ) + ).thenAnswer { isStartIapLoggingCalled = true Unit } InAppPurchaseManager.enableAutoLogging() assertThat(isStartIapLoggingCalled).isTrue } + + @Test + fun `test start iap logging when billing library is v5_`() { + val mockPackageManager: PackageManager = mock() + val mockApplicationInfo = ApplicationInfo() + val metaData = Bundle() + metaData.putString("com.google.android.play.billingclient.version", "5.0.3") + whenever(mockContext.packageManager).thenReturn(mockPackageManager) + whenever(mockContext.packageName).thenReturn("com.facebook.test") + whenever( + mockPackageManager.getApplicationInfo( + any(), + any() + ) + ).thenReturn(mockApplicationInfo) + mockApplicationInfo.metaData = metaData + + var isStartIapLoggingCalled = false + whenever( + InAppPurchaseAutoLogger.startIapLogging( + any(), + eq(InAppPurchaseUtils.BillingClientVersion.V5_Plus) + ) + ).thenAnswer { + isStartIapLoggingCalled = true + Unit + } + InAppPurchaseManager.enableAutoLogging() + assertThat(isStartIapLoggingCalled).isTrue + + } }