Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add advancedFraudSignalsEnabled property #2436

Merged
merged 1 commit into from
Apr 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,37 @@ internal interface FingerprintDataRepository {
)

override fun refresh() {
handler.post {
val liveData = store.get()
// LiveData observation must occur on the main thread
liveData.observeForever(object : Observer<FingerprintData> {
override fun onChanged(localFingerprintData: FingerprintData) {
if (localFingerprintData.isExpired(timestampSupplier())) {
fingerprintRequestExecutor.execute(
request = fingerprintRequestFactory.create(
localFingerprintData.guid
)
) { remoteFingerprintData ->
remoteFingerprintData?.let {
save(it)
if (Stripe.advancedFraudSignalsEnabled) {
handler.post {
val liveData = store.get()
// LiveData observation must occur on the main thread
liveData.observeForever(object : Observer<FingerprintData> {
override fun onChanged(localFingerprintData: FingerprintData) {
if (localFingerprintData.isExpired(timestampSupplier())) {
fingerprintRequestExecutor.execute(
request = fingerprintRequestFactory.create(
localFingerprintData.guid
)
) { remoteFingerprintData ->
remoteFingerprintData?.let {
save(it)
}
liveData.removeObserver(this)
}
} else {
cachedFingerprintData = localFingerprintData
liveData.removeObserver(this)
}
} else {
cachedFingerprintData = localFingerprintData
liveData.removeObserver(this)
}
}
})
})
}
}
}

override fun get(): FingerprintData? {
return cachedFingerprintData
return cachedFingerprintData.takeIf {
Stripe.advancedFraudSignalsEnabled
}
}

override fun save(fingerprintData: FingerprintData) {
Expand Down
13 changes: 13 additions & 0 deletions stripe/src/main/java/com/stripe/android/Stripe.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1612,5 +1612,18 @@ class Stripe internal constructor(
*/
@JvmStatic
var appInfo: AppInfo? = null

/**
* [advancedFraudSignalsEnabled] determines whether additional device data is sent to Stripe
* for fraud prevention. By default, this property is set to `true`.
*
* Disabling this setting will reduce Stripe's ability to protect your business from
* fraudulent payments.
*
* For more details on the information we collect, visit
* https://stripe.com/docs/disputes/prevention/advanced-fraud-detection
*/
@JvmStatic
var advancedFraudSignalsEnabled: Boolean = true
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package com.stripe.android

import android.content.Context
import android.os.Handler
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.KArgumentCaptor
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.argumentCaptor
import com.nhaarman.mockitokotlin2.doNothing
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import java.util.Calendar
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.test.AfterTest
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
Expand All @@ -24,6 +27,11 @@ class FingerprintDataRepositoryTest {
private val fingerprintRequestExecutor: FingerprintRequestExecutor = mock()
private val requestExecutorCallback: KArgumentCaptor<(FingerprintData?) -> Unit> = argumentCaptor()

@AfterTest
fun after() {
Stripe.advancedFraudSignalsEnabled = true
}

@Test
fun roundtrip_shouldReturnOriginalObject() {
val expectedFingerprintData = createFingerprintData(elapsedTime = -5L)
Expand Down Expand Up @@ -77,6 +85,26 @@ class FingerprintDataRepositoryTest {
).isTrue()
}

@Test
fun refresh_whenAdvancedFraudSignalsDisabled_shouldNotFetchFingerprintData() {
Stripe.advancedFraudSignalsEnabled = false

val store: FingerprintDataStore = mock()
val fingerprintRequestFactory: FingerprintRequestFactory = mock()
val handler: Handler = mock()
val repository = FingerprintDataRepository.Default(
store = store,
fingerprintRequestFactory = fingerprintRequestFactory,
fingerprintRequestExecutor = fingerprintRequestExecutor
)
repository.refresh()

verify(store, never()).save(any())
verify(handler, never()).post(any())
verify(fingerprintRequestFactory, never()).create(any())
verify(fingerprintRequestExecutor, never()).execute(any(), any())
}

private companion object {
fun createFingerprintData(elapsedTime: Long = 0L): FingerprintData {
return FingerprintData(
Expand Down