Skip to content

Commit

Permalink
Add condition to prevent unnecessary dedup when there is an invalid c…
Browse files Browse the repository at this point in the history
…ache history

Summary: Add a minimum timestamp after which in app purchases are not deduped on the client side when the app is first launched.

Reviewed By: jjiang10

Differential Revision:
D64772693

Privacy Context Container: L1285343

fbshipit-source-id: 34aefb1562e17ce3c33f43534f085a8efcb823ef
  • Loading branch information
maxalbrightmeta authored and facebook-github-bot committed Oct 25, 2024
1 parent d828cf3 commit 26f5048
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArraySet
import org.json.JSONObject
import kotlin.math.max
import kotlin.math.min

@AutoHandleExceptions
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
object InAppPurchaseLoggerManager {
private lateinit var sharedPreferences: SharedPreferences
private const val APPROXIMATE_IAP_ENHANCEMENT_RELEASE_TIME = 1730358000000L
private const val PURCHASE_TIME = "purchaseTime"
private const val IAP_SKU_CACHE_GPBLV1 = "com.facebook.internal.SKU_DETAILS"
private const val IAP_PURCHASE_CACHE_GPBLV1 = "com.facebook.internal.PURCHASE"
Expand Down Expand Up @@ -103,7 +105,7 @@ object InAppPurchaseLoggerManager {
for ((_, time) in cachedPurchaseMap) {
newestPurchaseTime = max(newestPurchaseTime, time)
}
return newestPurchaseTime * 1000L
return min(newestPurchaseTime * 1000L, APPROXIMATE_IAP_ENHANCEMENT_RELEASE_TIME)
}

private fun logPurchases(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,50 @@ class InAppPurchaseLoggerManagerTest : FacebookPowerMockTestCase() {
Assertions.assertThat(timeAddedToCache).isEqualTo(1620000000000)
}

@Test
fun testCacheDeDupPurchaseOnFirstTimeLoggingWithNewIAPImplementationAndInvalidCacheHistory() {
var timeAddedToCache: Long? = null
whenever(mockPrefs.getLong(eq(TIME_OF_LAST_LOGGED_PURCHASE_KEY), any())).thenReturn(0)
whenever(editor.putLong(eq(TIME_OF_LAST_LOGGED_PURCHASE_KEY), any())).thenAnswer {
timeAddedToCache = it.getArgument(1) as Long
return@thenAnswer editor
}
// Construct purchase details map
val mockPurchaseDetailsMap: MutableMap<String, JSONObject> = mutableMapOf()
val purchaseDetailJson1 =
JSONObject(
"{\"productId\":\"espresso\",\"purchaseToken\":\"token123\",\"purchaseTime\":1730358000001,\"developerPayload\":null,\"packageName\":\"sample.packagename\"}"
)
mockPurchaseDetailsMap["espresso"] = purchaseDetailJson1

// Construct cached purchase map
val lastClearedTime = 1_740_000_000L
Whitebox.setInternalState(
InAppPurchaseLoggerManager::class.java,
"cachedPurchaseMap",
mutableMapOf(
"otherpurchasetoken" to
lastClearedTime
)
)
Whitebox.setInternalState(
InAppPurchaseLoggerManager::class.java,
"firstTimeLoggingIAP",
true
)

val cachedMap = InAppPurchaseLoggerManager.cacheDeDupPurchase(mockPurchaseDetailsMap, false)
Assertions.assertThat(cachedMap).isNotEmpty()
Assertions.assertThat(
Whitebox.getInternalState(
InAppPurchaseLoggerManager::class.java,
"firstTimeLoggingIAP"
) as Boolean

).isFalse()
Assertions.assertThat(timeAddedToCache).isEqualTo(1730358000001)
}

@Test
fun testCacheDeDupPurchaseNotFirstTimeLoggingWithNewIAPImplementation() {
var timeAddedToCache: Long? = null
Expand Down

0 comments on commit 26f5048

Please sign in to comment.