From 2bb8a4e3d0962c71d091846aed9dc46d3da6faa7 Mon Sep 17 00:00:00 2001 From: Satoshi Qazi Muhammed Date: Thu, 9 Jul 2026 09:15:28 -0700 Subject: [PATCH] fix: actually start BalancesUpdateSystem in the full-architecture test First run of this test produced zero BalancesDiag output at all - not even a single balancesSync() call for any chain. Root cause: BalancesUpdateSystem.start() is a cold flow only ever collected by RootInteractor, which is wired to the root Activity/ViewModel lifecycle. This bare instrumented test never launches that Activity, so the pipeline was never started - the test's own timeout, not the production bug, explained the failure. Now collect the same AssetsFeatureApi. updateSystem instance directly instead of relying on app UI lifecycle. --- .../PezkuwiFullArchitectureBalancesTest.kt | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt b/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt index 221f096c..14041e6f 100644 --- a/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt +++ b/app/src/androidTest/java/io/novafoundation/nova/balances/PezkuwiFullArchitectureBalancesTest.kt @@ -8,8 +8,10 @@ import io.novafoundation.nova.core_db.dao.AssetDao import io.novafoundation.nova.core_db.dao.MetaAccountDao import io.novafoundation.nova.core_db.di.DbApi import io.novafoundation.nova.core_db.model.chain.account.MetaAccountLocal +import io.novafoundation.nova.feature_assets.di.AssetsFeatureApi import io.novasama.substrate_sdk_android.ss58.SS58Encoder.toAccountId import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeoutOrNull import org.junit.Assert.assertNotNull @@ -22,6 +24,11 @@ import kotlin.time.Duration.Companion.seconds * is meant to answer one question with hard evidence, not speculation: does the app's real, running background * sync ever write an `assets` cache row for HEZ on the Pezkuwi Asset Hub chain, for a real, well-funded account? * + * BalancesUpdateSystem.start() is a cold flow - in production it's only ever collected by RootInteractor, + * which is wired to the root Activity/ViewModel lifecycle. A bare instrumented test never launches that + * Activity, so we collect it ourselves here via the same AssetsFeatureApi.updateSystem instance the real app + * uses, instead of relying on app UI lifecycle to start it. + * * If this test fails, the failure message + logcat (tag "BalancesDiag", plus the standard per-updater error * logs already wired into BalancesUpdateSystem/FullSyncPaymentUpdater) shows exactly which decision branch or * exception is responsible - not another layer of inference from silence. @@ -40,27 +47,35 @@ class PezkuwiFullArchitectureBalancesTest { private val metaAccountDao = dbApi.metaAccountDao() private val assetDao: AssetDao = dbApi.provideAssetDao() + private val assetsFeatureApi = FeatureUtils.getFeature(context, AssetsFeatureApi::class.java) + @Test fun testPezkuwiAssetHubHezBalanceActuallySyncs() = runBlocking { - val metaId = insertAndSelectFounderWatchAccount(metaAccountDao) + val updateSystemJob = launch { assetsFeatureApi.updateSystem.start().collect {} } - val assetRow = withTimeoutOrNull(90.seconds) { - while (true) { - val asset = assetDao.getAsset(metaId, pezkuwiAssetHubChainId, hezAssetId) - if (asset != null) return@withTimeoutOrNull asset + try { + val metaId = insertAndSelectFounderWatchAccount(metaAccountDao) - delay(2.seconds) + val assetRow = withTimeoutOrNull(90.seconds) { + while (true) { + val asset = assetDao.getAsset(metaId, pezkuwiAssetHubChainId, hezAssetId) + if (asset != null) return@withTimeoutOrNull asset + + delay(2.seconds) + } + @Suppress("UNREACHABLE_CODE") + null } - @Suppress("UNREACHABLE_CODE") - null - } - assertNotNull( - "No `assets` row was ever written for HEZ on Pezkuwi Asset Hub (metaId=$metaId) within 90s. " + - "The real BalancesUpdateSystem pipeline never completed a sync for this asset - check logcat " + - "tag 'BalancesDiag' and the standard FullSyncPaymentUpdater/StatemineAssetBalance error logs.", - assetRow - ) + assertNotNull( + "No `assets` row was ever written for HEZ on Pezkuwi Asset Hub (metaId=$metaId) within 90s. " + + "The real BalancesUpdateSystem pipeline never completed a sync for this asset - check logcat " + + "tag 'BalancesDiag' and the standard FullSyncPaymentUpdater/StatemineAssetBalance error logs.", + assetRow + ) + } finally { + updateSystemJob.cancel() + } } private suspend fun insertAndSelectFounderWatchAccount(dao: MetaAccountDao): Long {