mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-24 19:56:00 +00:00
Fix bad one-time-payment receipt creation for cancelled iDEAL.
This commit is contained in:
committed by
Greyson Parrelli
parent
fa72a1788b
commit
3eea331e83
@@ -0,0 +1,109 @@
|
||||
package org.thoughtcrime.securesms.jobs
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import org.hamcrest.Matchers
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.signal.core.util.deleteAll
|
||||
import org.signal.core.util.money.FiatMoney
|
||||
import org.signal.donations.InAppPaymentType
|
||||
import org.signal.donations.json.StripeIntentStatus
|
||||
import org.signal.donations.json.StripePaymentIntent
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationSerializationHelper.toFiatValue
|
||||
import org.thoughtcrime.securesms.database.DonationReceiptTable
|
||||
import org.thoughtcrime.securesms.database.InAppPaymentTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.InAppPaymentReceiptRecord
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
||||
import org.thoughtcrime.securesms.dependencies.InstrumentationApplicationDependencyProvider
|
||||
import org.thoughtcrime.securesms.testing.Get
|
||||
import org.thoughtcrime.securesms.testing.SignalActivityRule
|
||||
import org.thoughtcrime.securesms.testing.assert
|
||||
import org.thoughtcrime.securesms.testing.success
|
||||
import org.thoughtcrime.securesms.util.TestStripePaths
|
||||
import java.math.BigDecimal
|
||||
import java.util.Currency
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class InAppPaymentAuthCheckJobTest {
|
||||
|
||||
companion object {
|
||||
private const val TEST_INTENT_ID = "test-intent-id"
|
||||
private const val TEST_CLIENT_SECRET = "test-client-secret"
|
||||
}
|
||||
|
||||
@get:Rule
|
||||
val harness = SignalActivityRule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
SignalDatabase.inAppPayments.writableDatabase.deleteAll(InAppPaymentTable.TABLE_NAME)
|
||||
SignalDatabase.donationReceipts.writableDatabase.deleteAll(DonationReceiptTable.TABLE_NAME)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenCanceledOneTimeAuthRequiredPayment_whenICheck_thenIDoNotExpectAReceipt() {
|
||||
initializeMockGetPaymentIntent(status = StripeIntentStatus.CANCELED)
|
||||
|
||||
SignalDatabase.inAppPayments.insert(
|
||||
type = InAppPaymentType.ONE_TIME_DONATION,
|
||||
state = InAppPaymentTable.State.WAITING_FOR_AUTHORIZATION,
|
||||
subscriberId = null,
|
||||
endOfPeriod = null,
|
||||
inAppPaymentData = InAppPaymentData(
|
||||
amount = FiatMoney(BigDecimal.ONE, Currency.getInstance("USD")).toFiatValue(),
|
||||
waitForAuth = InAppPaymentData.WaitingForAuthorizationState(
|
||||
stripeIntentId = TEST_INTENT_ID,
|
||||
stripeClientSecret = TEST_CLIENT_SECRET
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
InAppPaymentAuthCheckJob().run()
|
||||
|
||||
val receipts = SignalDatabase.donationReceipts.getReceipts(InAppPaymentReceiptRecord.Type.ONE_TIME_DONATION)
|
||||
receipts assert Matchers.empty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenSuccessfulOneTimeAuthRequiredPayment_whenICheck_thenIExpectAReceipt() {
|
||||
initializeMockGetPaymentIntent(status = StripeIntentStatus.SUCCEEDED)
|
||||
|
||||
SignalDatabase.inAppPayments.insert(
|
||||
type = InAppPaymentType.ONE_TIME_DONATION,
|
||||
state = InAppPaymentTable.State.WAITING_FOR_AUTHORIZATION,
|
||||
subscriberId = null,
|
||||
endOfPeriod = null,
|
||||
inAppPaymentData = InAppPaymentData(
|
||||
amount = FiatMoney(BigDecimal.ONE, Currency.getInstance("USD")).toFiatValue(),
|
||||
waitForAuth = InAppPaymentData.WaitingForAuthorizationState(
|
||||
stripeIntentId = TEST_INTENT_ID,
|
||||
stripeClientSecret = TEST_CLIENT_SECRET
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
InAppPaymentAuthCheckJob().run()
|
||||
|
||||
val receipts = SignalDatabase.donationReceipts.getReceipts(InAppPaymentReceiptRecord.Type.ONE_TIME_DONATION)
|
||||
receipts assert Matchers.hasSize(1)
|
||||
}
|
||||
|
||||
private fun initializeMockGetPaymentIntent(status: StripeIntentStatus) {
|
||||
InstrumentationApplicationDependencyProvider.addMockWebRequestHandlers(
|
||||
Get(TestStripePaths.getPaymentIntentPath(TEST_INTENT_ID, TEST_CLIENT_SECRET)) {
|
||||
MockResponse().success(
|
||||
StripePaymentIntent(
|
||||
id = TEST_INTENT_ID,
|
||||
clientSecret = TEST_CLIENT_SECRET,
|
||||
status = status,
|
||||
paymentMethod = null
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import org.signal.donations.StripePaths
|
||||
|
||||
/**
|
||||
* Stripe paths should be prefixed with 'stripe/' in order to access the proper namespacing in
|
||||
* the mock server. This object serves as a convenience delegate to StripePaths.
|
||||
*/
|
||||
object TestStripePaths {
|
||||
/**
|
||||
* @see StripePaths.getPaymentIntentPath
|
||||
*/
|
||||
fun getPaymentIntentPath(paymentIntentId: String, clientSecret: String): String {
|
||||
return withNamespace(StripePaths.getPaymentIntentPath(paymentIntentId, clientSecret))
|
||||
}
|
||||
|
||||
/**
|
||||
* @see StripePaths.getPaymentIntentConfirmationPath
|
||||
*/
|
||||
fun getPaymentIntentConfirmationPath(paymentIntentId: String): String {
|
||||
return withNamespace(StripePaths.getPaymentIntentConfirmationPath(paymentIntentId))
|
||||
}
|
||||
|
||||
/**
|
||||
* @see StripePaths.getSetupIntentPath
|
||||
*/
|
||||
fun getSetupIntentPath(setupIntentId: String, clientSecret: String): String {
|
||||
return withNamespace(StripePaths.getSetupIntentPath(setupIntentId, clientSecret))
|
||||
}
|
||||
|
||||
/**
|
||||
* @see StripePaths.getSetupIntentConfirmationPath
|
||||
*/
|
||||
fun getSetupIntentConfirmationPath(setupIntentId: String): String {
|
||||
return withNamespace(StripePaths.getSetupIntentConfirmationPath(setupIntentId))
|
||||
}
|
||||
|
||||
/**
|
||||
* @see StripePaths.getPaymentIntentPath
|
||||
*/
|
||||
fun getPaymentMethodsPath(): String {
|
||||
return withNamespace(StripePaths.getPaymentMethodsPath())
|
||||
}
|
||||
|
||||
/**
|
||||
* @see StripePaths.getTokensPath
|
||||
*/
|
||||
fun getTokensPath(): String {
|
||||
return withNamespace(StripePaths.getTokensPath())
|
||||
}
|
||||
|
||||
private fun withNamespace(path: String) = "stripe/$path"
|
||||
}
|
||||
Reference in New Issue
Block a user