Updated on 2026-08-14
This commit is contained in:
parent
3737e94127
commit
def54395ce
5 changed files with 11 additions and 65 deletions
|
|
@ -20,7 +20,6 @@ import com.tangem.common.constants.TestConstants.ALLURE_LABEL_NAME
|
||||||
import com.tangem.common.constants.TestConstants.ALLURE_LABEL_VALUE
|
import com.tangem.common.constants.TestConstants.ALLURE_LABEL_VALUE
|
||||||
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
|
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
|
||||||
import com.tangem.common.rules.ApiEnvironmentRule
|
import com.tangem.common.rules.ApiEnvironmentRule
|
||||||
import com.tangem.data.pay.TangemPayMockControl
|
|
||||||
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
|
|
@ -112,9 +111,6 @@ abstract class BaseTestCase : TestCase(
|
||||||
additionalBeforeSection: () -> Unit = {},
|
additionalBeforeSection: () -> Unit = {},
|
||||||
additionalAfterSection: () -> Unit = {},
|
additionalAfterSection: () -> Unit = {},
|
||||||
) = before {
|
) = before {
|
||||||
// Reset opt-in Tangem Pay mock switches so a previous Tangem Pay test can't leak an active Payment
|
|
||||||
// account into the next (e.g. generic openMainScreen) test running in the same process.
|
|
||||||
TangemPayMockControl.reset()
|
|
||||||
Allure.label(ALLURE_LABEL_NAME, ALLURE_LABEL_VALUE)
|
Allure.label(ALLURE_LABEL_NAME, ALLURE_LABEL_VALUE)
|
||||||
// Setup WireMock redirect for CI with local WireMock instances
|
// Setup WireMock redirect for CI with local WireMock instances
|
||||||
val wiremockUrl = InstrumentationRegistry.getArguments().getString(WIREMOCK_BASE_URL_ARG)
|
val wiremockUrl = InstrumentationRegistry.getArguments().getString(WIREMOCK_BASE_URL_ARG)
|
||||||
|
|
@ -184,16 +180,6 @@ abstract class BaseTestCase : TestCase(
|
||||||
|
|
||||||
fun waitForIdle() = composeTestRule.waitForIdle()
|
fun waitForIdle() = composeTestRule.waitForIdle()
|
||||||
|
|
||||||
/**
|
|
||||||
* Opts the current test's wallet into the Tangem Pay mock so it is treated as an existing customer
|
|
||||||
* (an active Payment account appears). MUST be called before the wallet is imported, so the first
|
|
||||||
* payment-account status fetch observes it. Paired with the [TangemPayMockControl] reset in [setupHooks],
|
|
||||||
* which restores the Payment-free default for every other (e.g. generic openMainScreen) test.
|
|
||||||
*/
|
|
||||||
fun markExistingTangemPayCustomer() {
|
|
||||||
TangemPayMockControl.hasTangemPayInWallet = true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits until [block] stops throwing (or [timeoutMillis] elapses). Use in scenario (BaseTestCase extension)
|
* Waits until [block] stops throwing (or [timeoutMillis] elapses). Use in scenario (BaseTestCase extension)
|
||||||
* code where flakySafely is unavailable; in test bodies prefer flakySafely.
|
* code where flakySafely is unavailable; in test bodies prefer flakySafely.
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import com.tangem.screens.tangempay.*
|
||||||
import io.qameta.allure.kotlin.Allure.step
|
import io.qameta.allure.kotlin.Allure.step
|
||||||
|
|
||||||
fun BaseTestCase.openTangemPay() {
|
fun BaseTestCase.openTangemPay() {
|
||||||
// Opt this wallet into the Tangem Pay mock (existing customer) before importing the wallet.
|
// Existing customer: callers set the `tangem_pay_eligibility` scenario to PaeraCustomer (in
|
||||||
markExistingTangemPayCustomer()
|
// additionalBeforeSection, before this runs), which drives the checkCustomerWalletId mock -> Payment account.
|
||||||
step("Import hot wallet from Tangem Pay seed phrase (with access code)") {
|
step("Import hot wallet from Tangem Pay seed phrase (with access code)") {
|
||||||
openMainScreenWithExistingHotWallet(SVS_SEED_PHRASE_12, accessCode = TANGEM_PAY_ACCESS_CODE)
|
openMainScreenWithExistingHotWallet(SVS_SEED_PHRASE_12, accessCode = TANGEM_PAY_ACCESS_CODE)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,6 @@ class TangemPayOnboardingKycTest : BaseTestCase() {
|
||||||
val paeraCustomerState = "PaeraCustomer"
|
val paeraCustomerState = "PaeraCustomer"
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
// Existing customer: opt into the Tangem Pay mock so the Payment account (tile) appears.
|
|
||||||
additionalBeforeSection = { markExistingTangemPayCustomer() },
|
|
||||||
additionalAfterSection = {
|
additionalAfterSection = {
|
||||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||||
},
|
},
|
||||||
|
|
@ -136,9 +134,6 @@ class TangemPayOnboardingKycTest : BaseTestCase() {
|
||||||
val viewStatusText = getResourceString(CoreResR.string.tangempay_kyc_in_progress_notification_button)
|
val viewStatusText = getResourceString(CoreResR.string.tangempay_kyc_in_progress_notification_button)
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
// Existing customer: the tile must appear so its KYC-status subtitle can be asserted.
|
|
||||||
// The KYC status itself comes from the WireMock TANGEM_PAY_KYC_STATUS_SCENARIO via getCustomerInfo.
|
|
||||||
additionalBeforeSection = { markExistingTangemPayCustomer() },
|
|
||||||
additionalAfterSection = {
|
additionalAfterSection = {
|
||||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||||
resetWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO)
|
resetWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO)
|
||||||
|
|
@ -192,9 +187,6 @@ class TangemPayOnboardingKycTest : BaseTestCase() {
|
||||||
val goToSupportText = getResourceString(CoreResR.string.tangempay_go_to_support)
|
val goToSupportText = getResourceString(CoreResR.string.tangempay_go_to_support)
|
||||||
|
|
||||||
setupHooks(
|
setupHooks(
|
||||||
// Existing customer: the tile must appear so its KYC-status subtitle can be asserted.
|
|
||||||
// The KYC status itself comes from the WireMock TANGEM_PAY_KYC_STATUS_SCENARIO via getCustomerInfo.
|
|
||||||
additionalBeforeSection = { markExistingTangemPayCustomer() },
|
|
||||||
additionalAfterSection = {
|
additionalAfterSection = {
|
||||||
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
resetWireMockScenarioState(TANGEM_PAY_ELIGIBILITY_SCENARIO)
|
||||||
resetWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO)
|
resetWireMockScenarioState(TANGEM_PAY_KYC_STATUS_SCENARIO)
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package com.tangem.data.pay
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test-only switch for the mocked Tangem Pay graph.
|
|
||||||
*
|
|
||||||
* Kept in the `main` source set (not `mocked`) on purpose: it is read only by the `mocked`-only
|
|
||||||
* [com.tangem.data.pay.repository.MockAwareOnboardingRepository], but it is also written from `app`
|
|
||||||
* `androidTest` sources, which are shared across build-type variants. Restricting it to the `mocked` source set
|
|
||||||
* would leave it off the classpath of any non-mocked androidTest variant and break their compilation. Being in
|
|
||||||
* `main`, it is unreferenced in production/release (only the mocked repository reads it) and is dropped by R8.
|
|
||||||
*
|
|
||||||
* [hasTangemPayInWallet] gates whether a wallet is treated as an existing Tangem Pay customer. It defaults to
|
|
||||||
* `false` so that the many generic `openMainScreen*` UI tests keep a Payment-account-free wallet (and thus stay
|
|
||||||
* out of accounts mode). Tangem Pay scenarios opt in by flipping it to `true` before the wallet is loaded; the
|
|
||||||
* value is reset to the default at the start of every test in `BaseTestCase.setupHooks`.
|
|
||||||
*
|
|
||||||
* @see com.tangem.data.pay.repository.MockAwareOnboardingRepository
|
|
||||||
*/
|
|
||||||
object TangemPayMockControl {
|
|
||||||
|
|
||||||
private const val DEFAULT_HAS_TANGEM_PAY_IN_WALLET = false
|
|
||||||
|
|
||||||
@Volatile
|
|
||||||
var hasTangemPayInWallet: Boolean = DEFAULT_HAS_TANGEM_PAY_IN_WALLET
|
|
||||||
|
|
||||||
/** Restores every switch to its default. Called between tests to prevent state leaking across the process. */
|
|
||||||
fun reset() {
|
|
||||||
hasTangemPayInWallet = DEFAULT_HAS_TANGEM_PAY_IN_WALLET
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,7 +3,6 @@ package com.tangem.data.pay.repository
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
import arrow.core.right
|
import arrow.core.right
|
||||||
import com.tangem.core.error.UniversalError
|
import com.tangem.core.error.UniversalError
|
||||||
import com.tangem.data.pay.TangemPayMockControl
|
|
||||||
import com.tangem.datasource.api.common.config.ApiConfig
|
import com.tangem.datasource.api.common.config.ApiConfig
|
||||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||||
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
||||||
|
|
@ -22,8 +21,9 @@ import javax.inject.Singleton
|
||||||
* customer-facing state — whether a wallet has Tangem Pay ([hasTangemPayInWallet]), KYC status, ACTIVE /
|
* customer-facing state — whether a wallet has Tangem Pay ([hasTangemPayInWallet]), KYC status, ACTIVE /
|
||||||
* INACTIVE, balances ([getCustomerInfo]) — is driven by the WireMock test scenario (authenticated with the
|
* INACTIVE, balances ([getCustomerInfo]) — is driven by the WireMock test scenario (authenticated with the
|
||||||
* synthetic tokens from [com.tangem.data.pay.store.MockAwareTangemPayStorage]) rather than hardcoded:
|
* synthetic tokens from [com.tangem.data.pay.store.MockAwareTangemPayStorage]) rather than hardcoded:
|
||||||
* - [hasTangemPayInWallet] is answered locally via [TangemPayMockControl] (WireMock does not mock the
|
* - [hasTangemPayInWallet] delegates to the real repo, so the "existing customer" gate follows the
|
||||||
* underlying checkCustomerWalletId endpoint) — default false, opt-in true for Tangem Pay scenarios;
|
* checkCustomerWalletId mock (the `tangem_pay_eligibility` scenario: `Started` → 404/NotPaeraCustomer →
|
||||||
|
* no Payment account, `PaeraCustomer` → 200 → Payment account);
|
||||||
* - [getCustomerInfo] delegates to the real repo (WireMock), so KYC / customer-state scenarios take effect.
|
* - [getCustomerInfo] delegates to the real repo (WireMock), so KYC / customer-state scenarios take effect.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|
@ -113,14 +113,12 @@ internal class MockAwareOnboardingRepository @Inject constructor(
|
||||||
real.storeVirtualAccountOrderId(userWalletId, vaOrderId)
|
real.storeVirtualAccountOrderId(userWalletId, vaOrderId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the gate that decides whether a wallet is treated as an existing Tangem Pay customer (and thus
|
// The "existing Tangem Pay customer" gate (decides whether an active Payment account — and accounts mode —
|
||||||
// whether an active Payment account — and accounts mode — appears). WireMock does NOT mock the underlying
|
// appears). Delegates to WireMock's checkCustomerWalletId via the real repo (static token, no signing), so it
|
||||||
// checkCustomerWalletId endpoint, so we answer locally: default false (generic UI tests stay Payment-free),
|
// is driven by the `tangem_pay_eligibility` scenario: `Started` (default) → 404/NotPaeraCustomer → no account;
|
||||||
// opt-in true via TangemPayMockControl for Tangem Pay scenarios. Never delegate to `real` here.
|
// `PaeraCustomer` → 200 → account. Generic UI tests never set the scenario, so they stay Payment-free.
|
||||||
override suspend fun hasTangemPayInWallet(userWalletId: UserWalletId): Either<VisaApiError, Boolean> {
|
override suspend fun hasTangemPayInWallet(userWalletId: UserWalletId): Either<VisaApiError, Boolean> =
|
||||||
if (isMockMode) return TangemPayMockControl.hasTangemPayInWallet.right()
|
real.hasTangemPayInWallet(userWalletId)
|
||||||
return real.hasTangemPayInWallet(userWalletId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun checkCustomerEligibility(): List<TangemPayEligibilityType> =
|
override suspend fun checkCustomerEligibility(): List<TangemPayEligibilityType> =
|
||||||
real.checkCustomerEligibility()
|
real.checkCustomerEligibility()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue