diff --git a/android-foundation b/android-foundation index a5be15486..f6b9d333c 160000 --- a/android-foundation +++ b/android-foundation @@ -1 +1 @@ -Subproject commit a5be154865d8cb01051f6fc827126487210de7c9 +Subproject commit f6b9d333c30adcb41c94720dca256f48aac25d2a diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 09c2e4476..107152d64 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -155,6 +155,11 @@ android { configurations { all { exclude(module = "bcprov-jdk15on") +// resolutionStrategy { +// dependencySubstitution { +// substitute(module("")).using(module("")) +// } +// } } } } @@ -234,8 +239,11 @@ dependencies { implementation(libs.webSocketLibDep) - // Tests - testImplementation(project(":test_shared")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) kover(project(":common")) kover(project(":common_wallet")) diff --git a/app/src/test/java/jp/co/soramitsu/sora/splash/domain/SplashInteractorTest.kt b/app/src/test/java/jp/co/soramitsu/sora/splash/domain/SplashInteractorTest.kt index 0a0709da0..6762db0fb 100644 --- a/app/src/test/java/jp/co/soramitsu/sora/splash/domain/SplashInteractorTest.kt +++ b/app/src/test/java/jp/co/soramitsu/sora/splash/domain/SplashInteractorTest.kt @@ -33,9 +33,9 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.sora.splash.domain import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_account_api.domain.model.OnboardingState -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals diff --git a/app/src/test/java/jp/co/soramitsu/sora/splash/presentation/SplashViewModelTest.kt b/app/src/test/java/jp/co/soramitsu/sora/splash/presentation/SplashViewModelTest.kt index e0b9fa7e2..2fbd4a485 100644 --- a/app/src/test/java/jp/co/soramitsu/sora/splash/presentation/SplashViewModelTest.kt +++ b/app/src/test/java/jp/co/soramitsu/sora/splash/presentation/SplashViewModelTest.kt @@ -35,11 +35,11 @@ package jp.co.soramitsu.sora.splash.presentation import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.every import io.mockk.mockkObject +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.logger.FirebaseWrapper import jp.co.soramitsu.feature_account_api.domain.model.OnboardingState import jp.co.soramitsu.sora.splash.domain.SplashInteractor -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 0df7171ad..c1a864169 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -138,6 +138,16 @@ android { buildConfigField("String", "GOOGLE_API_TOKEN", maybeWrapQuotes(secret("SORA_GOOGLE_TOKEN_PROD"))) } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -218,7 +228,9 @@ dependencies { implementation(libs.navigationComposeDep) debugImplementation(libs.composeToolingDep) - testImplementation(project(":test_shared")) + testImplementation(libs.mockitoDep) + testImplementation(libs.archCoreTestDep) + testImplementation(libs.coroutineTestDep) } kapt { diff --git a/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt b/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt index 9cfa97e8e..5e1b7c96e 100644 --- a/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt +++ b/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt @@ -82,15 +82,17 @@ import jp.co.soramitsu.common.util.json_decoder.JsonAccountsEncoder import jp.co.soramitsu.common.vibration.DeviceVibrator import jp.co.soramitsu.crypto.ed25519.Ed25519Sha3 import jp.co.soramitsu.xbackup.BackupService -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuHttpClientProvider -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuHttpClientProviderImpl -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuNetworkClient -import jp.co.soramitsu.xnetworking.sorawallet.blockexplorerinfo.SoraWalletBlockExplorerInfo -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraRemoteConfigBuilder -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraRemoteConfigProvider -import jp.co.soramitsu.xnetworking.sorawallet.tokenwhitelist.SoraTokensWhitelistManager -import jp.co.soramitsu.xnetworking.sorawallet.txhistory.client.SubQueryClientForSoraWalletFactory +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.api.BlockExplorerRepository +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.impl.BlockExplorerRepositoryImpl +import jp.co.soramitsu.xnetworking.lib.datasources.chainsconfig.api.ConfigDAO +import jp.co.soramitsu.xnetworking.lib.datasources.chainsconfig.api.data.ConfigParser +import jp.co.soramitsu.xnetworking.lib.datasources.chainsconfig.impl.SuperWalletConfigDAOImpl +import jp.co.soramitsu.xnetworking.lib.datasources.chainsconfig.impl.data.RemoteConfigParserImpl +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.models.AbstractRestClientConfig +import jp.co.soramitsu.xnetworking.lib.engines.rest.impl.RestClientImpl import jp.co.soramitsu.xsubstrate.encrypt.json.JsonSeedEncoder +import kotlinx.serialization.json.Json @InstallIn(SingletonComponent::class) @Module @@ -133,91 +135,86 @@ class CommonModule { @Singleton @Provides - fun provideSvgDecoder(): SvgDecoder.Factory { - return SvgDecoder.Factory() + fun provideJson(): Json = Json { + prettyPrint = true + isLenient = true + ignoreUnknownKeys = true } @Singleton @Provides - fun provideInAppUpdateManager( - @ApplicationContext c: Context, - sp: SoraPreferences - ): InAppUpdateManager = InAppUpdateManager(c, sp) + fun provideConfigParser( + restClient: RestClient + ): ConfigParser = RemoteConfigParserImpl( + restClient = restClient, + chainsRequestUrl = OptionsProvider.configXn, + ) @Singleton @Provides - fun provideAppStateManager(): AppStateProvider = AppStateProviderImpl() + fun provideConfigDAO(configParser: ConfigParser): ConfigDAO = + SuperWalletConfigDAOImpl(configParser = configParser) @Singleton @Provides - fun provideCoroutineManager(): CoroutineManager = - CoroutineManager() - - @Provides - fun provideWithProgress(): WithProgress = WithProgressImpl() + fun provideBlockExplorerRepository( + configDAO: ConfigDAO, + restClient: RestClient + ): BlockExplorerRepository = BlockExplorerRepositoryImpl( + configDAO = configDAO, + restClient = restClient + ) @Singleton @Provides - fun providesPushHandler(): PushHandler = PushHandler() + fun provideRestClient(json: Json): RestClient = RestClientImpl( + restClientConfig = object : AbstractRestClientConfig() { + override fun getConnectTimeoutMillis(): Long = 30_000L + override fun getOrCreateJsonConfig(): Json = json + override fun getRequestTimeoutMillis(): Long = 30_000L + override fun getSocketTimeoutMillis(): Long = 30_000L + override fun isLoggingEnabled(): Boolean = BuildConfig.DEBUG + } + ) @Singleton @Provides - fun provideNetworkStateListener(): NetworkStateListener = NetworkStateListener() + fun provideSvgDecoder(): SvgDecoder.Factory { + return SvgDecoder.Factory() + } @Singleton @Provides - fun provideQrCodeGenerator(): QrCodeGenerator { - return QrCodeGenerator(Color.BLACK) - } + fun provideInAppUpdateManager( + @ApplicationContext c: Context, + sp: SoraPreferences + ): InAppUpdateManager = InAppUpdateManager(c, sp) @Singleton @Provides - fun provideSoramitsuNetworkClient(): SoramitsuNetworkClient = - SoramitsuNetworkClient(logging = BuildConfig.DEBUG, timeout = 20000) + fun provideAppStateManager(): AppStateProvider = AppStateProviderImpl() @Singleton @Provides - fun provideSoraWalletBlockExplorerInfo( - client: SoramitsuNetworkClient, - soraRemoteConfigBuilder: SoraRemoteConfigBuilder, - ): SoraWalletBlockExplorerInfo { - return SoraWalletBlockExplorerInfo( - networkClient = client, - soraRemoteConfigBuilder = soraRemoteConfigBuilder, - ) - } + fun provideCoroutineManager(): CoroutineManager = + CoroutineManager() - @Singleton @Provides - fun provideSoraRemoteConfigBuilder( - client: SoramitsuNetworkClient, - @ApplicationContext context: Context, - ): SoraRemoteConfigBuilder { - return SoraRemoteConfigProvider( - context = context, - client = client, - commonUrl = OptionsProvider.configCommon, - mobileUrl = OptionsProvider.configMobile, - ).provide() - } + fun provideWithProgress(): WithProgress = WithProgressImpl() @Singleton @Provides - fun provideSoramitsuHttpClientProvider(): SoramitsuHttpClientProvider = - SoramitsuHttpClientProviderImpl() + fun providesPushHandler(): PushHandler = PushHandler() @Singleton @Provides - fun provideSubQueryClientForSoraWalletFactory( - @ApplicationContext context: Context - ): SubQueryClientForSoraWalletFactory = SubQueryClientForSoraWalletFactory(context) + fun provideNetworkStateListener(): NetworkStateListener = NetworkStateListener() @Singleton @Provides - fun provideSoraTokensWhitelistFetcher( - client: SoramitsuNetworkClient, - ): SoraTokensWhitelistManager = - SoraTokensWhitelistManager(networkClient = client) + fun provideQrCodeGenerator(): QrCodeGenerator { + return QrCodeGenerator(Color.BLACK) + } @Singleton @Provides diff --git a/common/src/main/java/jp/co/soramitsu/common/domain/OptionsProvider.kt b/common/src/main/java/jp/co/soramitsu/common/domain/OptionsProvider.kt index 44befe0a4..11ec9588a 100644 --- a/common/src/main/java/jp/co/soramitsu/common/domain/OptionsProvider.kt +++ b/common/src/main/java/jp/co/soramitsu/common/domain/OptionsProvider.kt @@ -40,6 +40,7 @@ object OptionsProvider { var APPLICATION_ID: String = "" const val configCommon = "https://config.polkaswap2.io/${FlavorOptionsProvider.typesFilePath}/common.json" const val configMobile = "https://config.polkaswap2.io/${FlavorOptionsProvider.typesFilePath}/mobile.json" + const val configXn = "https://config.polkaswap2.io/${FlavorOptionsProvider.typesFilePath}/xn.json" val fileProviderAuthority: String get() = "$APPLICATION_ID.soraFileProvider" val header: String by lazy { "$APPLICATION_ID/$CURRENT_VERSION_NAME/$CURRENT_VERSION_CODE/${BuildConfig.BUILD_TYPE}/${BuildConfig.FLAVOR}" @@ -49,7 +50,7 @@ object OptionsProvider { const val defaultScale = 18 const val nameByteLimit = 32 const val fiatSymbol = "$" - const val nbspace = ' ' + const val nbspace = Typography.nbsp const val euroSign = '€' const val soracard = "2.2.4" const val soracardFiatPackageTest = "com.soracard.iban.wallet.test" diff --git a/common/src/main/java/jp/co/soramitsu/common/domain/WhitelistTokensManager.kt b/common/src/main/java/jp/co/soramitsu/common/domain/WhitelistTokensManager.kt index 256fdbb83..9daba2225 100644 --- a/common/src/main/java/jp/co/soramitsu/common/domain/WhitelistTokensManager.kt +++ b/common/src/main/java/jp/co/soramitsu/common/domain/WhitelistTokensManager.kt @@ -32,16 +32,21 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.domain +import io.ktor.http.decodeURLPart +import io.ktor.util.decodeBase64Bytes import javax.inject.Inject import javax.inject.Singleton import jp.co.soramitsu.common.io.FileManager import jp.co.soramitsu.common.logger.FirebaseWrapper -import jp.co.soramitsu.xnetworking.sorawallet.tokenwhitelist.SoraTokensWhitelistManager +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient +import jp.co.soramitsu.xnetworking.lib.engines.utils.JsonGetRequest +import jp.co.soramitsu.xnetworking.lib.engines.utils.fieldOrNull import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonArray @Serializable private data class TokenDto( @@ -51,12 +56,12 @@ private data class TokenDto( @Singleton class WhitelistTokensManager @Inject constructor( - private val manager: SoraTokensWhitelistManager, + private val restClient: RestClient, private val fileManager: FileManager, ) { companion object { - private const val whitelistFileName = "whitelist_tokens.json" + private const val WHITELIST_FILE_NAME = "whitelist_tokens.json" } var whitelistIds: List = emptyList() @@ -71,7 +76,7 @@ class WhitelistTokensManager @Inject constructor( } init { - fileManager.readInternalFile(whitelistFileName)?.let { + fileManager.readInternalFile(WHITELIST_FILE_NAME)?.let { val ids = Json.decodeFromString(ListSerializer(TokenDto.serializer()), it) updateWhitelist(ids) } @@ -88,36 +93,64 @@ class WhitelistTokensManager @Inject constructor( } suspend fun updateWhitelistStorage() { - runCatching { manager.getTokens() }.onSuccess { dtoList -> - val ids = dtoList.map { TokenDto(it.address, it.type) } + runCatching { + restClient.get( + JsonGetRequest( + url = "https://whitelist.polkaswap2.io/whitelist.json", + responseDeserializer = JsonArray.serializer() + ) + ) + }.onSuccess { dtoList -> + val ids = dtoList.mapNotNull { + TokenDto( + id = it.fieldOrNull("address") + ?: return@mapNotNull null, + type = it.fieldOrNull("icon") + ?: return@mapNotNull null + ) + } updateWhitelist(ids) - fileManager.writeInternalFile(whitelistFileName, Json.encodeToString(ids)) + fileManager.writeInternalFile( + WHITELIST_FILE_NAME, + Json.encodeToString(ids) + ) + dtoList.forEach { dto -> - when (dto.rawIcon) { - is String -> { - fileManager.writeInternalCacheFile( - "${dto.address}.${dto.type}", - dto.rawIcon as String, - ) - } - is ByteArray -> { - fileManager.writeInternalCacheFile( - "${dto.address}.${dto.type}", - dto.rawIcon as ByteArray, - ) - } - else -> {} + val address = dto.fieldOrNull("address") ?: return@forEach + val iconField = dto.fieldOrNull("icon") ?: return@forEach + + val iconRaw = iconField.substringAfter( + delimiter = ",", + missingDelimiterValue = "" + ) + val iconExtension = iconField.removeSurrounding( + prefix = "data:image/", + suffix = iconRaw + ) + + when (iconExtension) { + "svg" -> fileManager.writeInternalCacheFile( + fileName = "$address.$iconExtension", + content = iconRaw.decodeURLPart() + ) + "png" -> fileManager.writeInternalCacheFile( + fileName = "$address.$iconExtension", + content = iconRaw.decodeBase64Bytes() + ) + else -> return@forEach } } }.onFailure { FirebaseWrapper.recordException(it) - if (fileManager.existsInternalFile(whitelistFileName).not()) { - updateWhitelist( - AssetHolder.getIds().map { id -> - TokenDto(id, "") - } - ) - } + + if (fileManager.existsInternalFile(WHITELIST_FILE_NAME)) + return@onFailure + + updateWhitelist( + AssetHolder.getIds().map { id -> + TokenDto(id, "") + } + ) } } } diff --git a/test_shared/src/main/java/jp/co/soramitsu/test_shared/MainCoroutineRule.kt b/common/src/main/java/jp/co/soramitsu/common/util/CachingFactory.kt similarity index 67% rename from test_shared/src/main/java/jp/co/soramitsu/test_shared/MainCoroutineRule.kt rename to common/src/main/java/jp/co/soramitsu/common/util/CachingFactory.kt index d768a3280..eef9e66dc 100644 --- a/test_shared/src/main/java/jp/co/soramitsu/test_shared/MainCoroutineRule.kt +++ b/common/src/main/java/jp/co/soramitsu/common/util/CachingFactory.kt @@ -30,28 +30,37 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package jp.co.soramitsu.test_shared - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.TestDispatcher -import kotlinx.coroutines.test.resetMain -import kotlinx.coroutines.test.setMain -import org.junit.rules.TestWatcher -import org.junit.runner.Description - -@ExperimentalCoroutinesApi -class MainCoroutineRule(private val dispatcher: TestDispatcher = StandardTestDispatcher()) : - TestWatcher() { - - override fun starting(description: Description) { - super.starting(description) - Dispatchers.setMain(dispatcher) +package jp.co.soramitsu.common.util + +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock + +class CachingFactory( + private val factory: suspend Args.() -> Value +) { + + abstract class Args + + private val cacheMutex = Mutex() + private var cachedValue = mutableMapOf() + + suspend fun nullableValue(args: Args): Value? { + initialize(args) + return cachedValue[args] + } + + suspend fun value(args: Args): Value { + initialize(args) + return checkNotNull(cachedValue[args]) } - override fun finished(description: Description) { - Dispatchers.resetMain() - super.finished(description) + private suspend fun initialize(args: Args) { + if (cachedValue[args] == null) { + cacheMutex.withLock { + if (cachedValue[args] == null) { + cachedValue[args] = factory(args) + } + } + } } } diff --git a/common/src/main/java/jp/co/soramitsu/common/util/ext/StringExt.kt b/common/src/main/java/jp/co/soramitsu/common/util/ext/StringExt.kt index 798d35c58..acefb2bfb 100644 --- a/common/src/main/java/jp/co/soramitsu/common/util/ext/StringExt.kt +++ b/common/src/main/java/jp/co/soramitsu/common/util/ext/StringExt.kt @@ -80,8 +80,6 @@ fun String.didToAccountId(): String { return this.replace(":", "_") + "@sora" } -fun String.addHexPrefix(): String = "${HEX_PREFIX}$this" - fun String.removeWebPrefix(): String = this.removePrefix("http://").removePrefix("https://").removePrefix("www.") diff --git a/common/src/test/java/jp/co/soramitsu/common/data/EncryptedPreferencesTest.kt b/common/src/test/java/jp/co/soramitsu/common/data/EncryptedPreferencesTest.kt index ec5913dff..4bf5c6a4b 100644 --- a/common/src/test/java/jp/co/soramitsu/common/data/EncryptedPreferencesTest.kt +++ b/common/src/test/java/jp/co/soramitsu/common/data/EncryptedPreferencesTest.kt @@ -32,8 +32,8 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.data +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.util.EncryptionUtil -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Before diff --git a/common/src/test/java/jp/co/soramitsu/common/date/DateFormatterTest.kt b/common/src/test/java/jp/co/soramitsu/common/date/DateFormatterTest.kt index a47c02f1b..85130e9b6 100644 --- a/common/src/test/java/jp/co/soramitsu/common/date/DateFormatterTest.kt +++ b/common/src/test/java/jp/co/soramitsu/common/date/DateFormatterTest.kt @@ -37,9 +37,9 @@ import java.util.Date import java.util.Locale import java.util.TimeZone import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.eqNonNull import jp.co.soramitsu.common.R import jp.co.soramitsu.common.resourses.LanguagesHolder -import jp.co.soramitsu.test_shared.eqNonNull import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test diff --git a/common/src/test/java/jp/co/soramitsu/common/delegate/WithProgressImplTest.kt b/common/src/test/java/jp/co/soramitsu/common/delegate/WithProgressImplTest.kt index c3f253cf2..28909b04e 100644 --- a/common/src/test/java/jp/co/soramitsu/common/delegate/WithProgressImplTest.kt +++ b/common/src/test/java/jp/co/soramitsu/common/delegate/WithProgressImplTest.kt @@ -33,7 +33,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.delegate import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import jp.co.soramitsu.test_shared.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Assert.assertFalse diff --git a/common/src/test/java/jp/co/soramitsu/common/domain/PushHandlerTest.kt b/common/src/test/java/jp/co/soramitsu/common/domain/PushHandlerTest.kt index bb9fe034b..db87b7ca5 100644 --- a/common/src/test/java/jp/co/soramitsu/common/domain/PushHandlerTest.kt +++ b/common/src/test/java/jp/co/soramitsu/common/domain/PushHandlerTest.kt @@ -32,7 +32,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.domain -import jp.co.soramitsu.test_shared.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch diff --git a/common/src/test/java/jp/co/soramitsu/common/domain/RetryStrategyTests.kt b/common/src/test/java/jp/co/soramitsu/common/domain/RetryStrategyTests.kt index be58841f0..5f46e38aa 100644 --- a/common/src/test/java/jp/co/soramitsu/common/domain/RetryStrategyTests.kt +++ b/common/src/test/java/jp/co/soramitsu/common/domain/RetryStrategyTests.kt @@ -32,7 +32,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.domain -import jp.co.soramitsu.test_shared.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Rule diff --git a/common/src/test/java/jp/co/soramitsu/common/presentation/webview/WebViewViewModelTest.kt b/common/src/test/java/jp/co/soramitsu/common/presentation/webview/WebViewViewModelTest.kt index 242329a88..6ba909fe3 100644 --- a/common/src/test/java/jp/co/soramitsu/common/presentation/webview/WebViewViewModelTest.kt +++ b/common/src/test/java/jp/co/soramitsu/common/presentation/webview/WebViewViewModelTest.kt @@ -33,8 +33,8 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.presentation.webview import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.presentation.compose.webview.WebViewViewModel -import jp.co.soramitsu.test_shared.getOrAwaitValue import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue diff --git a/common/src/test/java/jp/co/soramitsu/common/util/ext/StringExtTest.kt b/common/src/test/java/jp/co/soramitsu/common/util/ext/StringExtTest.kt index d5de015d7..d94c7a994 100644 --- a/common/src/test/java/jp/co/soramitsu/common/util/ext/StringExtTest.kt +++ b/common/src/test/java/jp/co/soramitsu/common/util/ext/StringExtTest.kt @@ -32,6 +32,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.util.ext +import jp.co.soramitsu.androidfoundation.format.addHexPrefix import jp.co.soramitsu.androidfoundation.format.removeHexPrefix import org.junit.Assert.assertEquals import org.junit.Test diff --git a/common_wallet/build.gradle.kts b/common_wallet/build.gradle.kts index 1dfd57e7b..4bbddb777 100644 --- a/common_wallet/build.gradle.kts +++ b/common_wallet/build.gradle.kts @@ -64,6 +64,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -123,6 +133,6 @@ dependencies { implementation(libs.composeToolingPreviewDep) debugImplementation(libs.composeToolingDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.junitDep) } diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/data/SoraCardNetworkClientImpl.kt b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/data/SoraCardNetworkClientImpl.kt new file mode 100644 index 000000000..53c2428a0 --- /dev/null +++ b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/data/SoraCardNetworkClientImpl.kt @@ -0,0 +1,129 @@ +/* +This file is part of the SORA network and Polkaswap app. + +Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. +SPDX-License-Identifier: BSD-4-Clause + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +All advertising materials mentioning features or use of this software must display +the following acknowledgement: This product includes software developed by Polka Biome +Ltd., SORA, and Polkaswap. + +Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used +to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package jp.co.soramitsu.common_wallet.data + +import jp.co.soramitsu.oauth.network.SoraCardNetworkClient +import jp.co.soramitsu.oauth.network.SoraCardNetworkResponse +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.models.AbstractRestServerRequest +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.models.RestClientException +import kotlinx.serialization.DeserializationStrategy + +class SoraCardNetworkClientImpl( + private val restClient: RestClient +) : SoraCardNetworkClient { + + private companion object { + const val SUCCESS_STATUS_CODE = 200 + } + + private class RestfulGetRequest( + override val userAgent: String?, + override val bearerToken: String?, + override val url: String, + override val responseDeserializer: DeserializationStrategy + ) : AbstractRestServerRequest() + + override suspend fun get( + header: String?, + bearerToken: String?, + url: String, + deserializer: DeserializationStrategy + ): SoraCardNetworkResponse { + return try { + val result = restClient.get( + RestfulGetRequest( + userAgent = header, + bearerToken = bearerToken, + url = url, + responseDeserializer = deserializer + ) + ) + + SoraCardNetworkResponse( + value = result, + statusCode = SUCCESS_STATUS_CODE + ) + } catch (exception: RestClientException) { + if (exception !is RestClientException.WithCode) + throw exception + + SoraCardNetworkResponse( + value = null, + statusCode = exception.code + ) + } + } + + private class RestfulPostRequest( + override val userAgent: String?, + override val bearerToken: String?, + override val url: String, + override val responseDeserializer: DeserializationStrategy, + override val body: Any, + override val requestContentType: RestClient.ContentType = RestClient.ContentType.JSON, + ) : AbstractRestServerRequest.WithBody() + + override suspend fun post( + header: String?, + bearerToken: String?, + url: String, + body: Any, + deserializer: DeserializationStrategy + ): SoraCardNetworkResponse { + return try { + val result = restClient.post( + RestfulPostRequest( + userAgent = header, + bearerToken = bearerToken, + url = url, + responseDeserializer = deserializer, + body = body + ) + ) + + SoraCardNetworkResponse( + value = result, + statusCode = SUCCESS_STATUS_CODE + ) + } catch (exception: RestClientException) { + if (exception !is RestClientException.WithCode) + throw exception + + SoraCardNetworkResponse( + value = null, + statusCode = exception.code + ) + } + } +} diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/di/CommonWalletModule.kt b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/di/CommonWalletModule.kt index 5f0c1ba4d..338c93a98 100644 --- a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/di/CommonWalletModule.kt +++ b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/di/CommonWalletModule.kt @@ -40,6 +40,9 @@ import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import javax.inject.Singleton import jp.co.soramitsu.common.util.QrCodeDecoder +import jp.co.soramitsu.common_wallet.data.SoraCardNetworkClientImpl +import jp.co.soramitsu.oauth.network.SoraCardNetworkClient +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient @Module @InstallIn(SingletonComponent::class) @@ -50,4 +53,14 @@ class CommonWalletModule { fun provideQrCodeDecoder(@ApplicationContext context: Context): QrCodeDecoder { return QrCodeDecoder(context.contentResolver) } + + @Singleton + @Provides + fun provideSoraCardNetworkClient( + restClient: RestClient + ): SoraCardNetworkClient { + return SoraCardNetworkClientImpl( + restClient = restClient + ) + } } diff --git a/core_db/build.gradle.kts b/core_db/build.gradle.kts index de75fcfe1..2d5d2eaea 100644 --- a/core_db/build.gradle.kts +++ b/core_db/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } class RoomSchemaArgProvider( @@ -82,9 +92,11 @@ dependencies { implementation(libs.roomKtxDep) ksp(libs.roomKaptDep) - androidTestImplementation(project(":test_shared")) androidTestImplementation(project(":test_data")) + androidTestImplementation(project(":android-foundation")) androidTestImplementation(libs.androidxTestExtJunitDep) androidTestImplementation(libs.androidxTestEspressoCoreDep) androidTestImplementation(libs.archCoreTestDep) + androidTestImplementation(libs.roomTestHelpersDep) + androidTestImplementation(libs.coroutineTestDep) } diff --git a/core_db/src/androidTest/java/jp/co/soramitsu/core_db/AssetDaoTests.kt b/core_db/src/androidTest/java/jp/co/soramitsu/core_db/AssetDaoTests.kt index 168e6c8da..f03729d4b 100644 --- a/core_db/src/androidTest/java/jp/co/soramitsu/core_db/AssetDaoTests.kt +++ b/core_db/src/androidTest/java/jp/co/soramitsu/core_db/AssetDaoTests.kt @@ -36,12 +36,12 @@ import android.content.Context import androidx.room.Room import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.core_db.dao.AssetDao import jp.co.soramitsu.core_db.model.FiatTokenPriceLocal import jp.co.soramitsu.core_db.model.TokenLocal import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.After diff --git a/demeter/build.gradle.kts b/demeter/build.gradle.kts index 7e1615eed..a31c0e04e 100644 --- a/demeter/build.gradle.kts +++ b/demeter/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -86,13 +96,11 @@ dependencies { implementation(libs.coroutineAndroidDep) implementation(libs.xsubstrateDep) - implementation(libs.xnetworkingDep) implementation(libs.composeRuntimeDep) implementation(libs.roomDep) implementation(libs.roomKtxDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) } diff --git a/feature_account_api/build.gradle.kts b/feature_account_api/build.gradle.kts index d45f68576..b5c6473f6 100644 --- a/feature_account_api/build.gradle.kts +++ b/feature_account_api/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/feature_account_impl/build.gradle.kts b/feature_account_impl/build.gradle.kts index c18dcf64e..3fdb2e59f 100644 --- a/feature_account_impl/build.gradle.kts +++ b/feature_account_impl/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -75,5 +85,9 @@ dependencies { implementation(libs.coroutineDep) implementation(libs.viewmodelKtxDep) - testImplementation(project(":test_shared")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_account_impl/src/main/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryImpl.kt b/feature_account_impl/src/main/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryImpl.kt index 1b65f8215..b05d7c2ec 100644 --- a/feature_account_impl/src/main/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryImpl.kt +++ b/feature_account_impl/src/main/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryImpl.kt @@ -207,6 +207,7 @@ class CredentialsRepositoryImpl constructor( } override suspend fun generateJson(accounts: List, password: String): String { + val localGenesis = soraConfigManager.getGenesis(true) if (accounts.size == 1) { accounts.first().let { val seed = credentialsPrefs.retrieveSeed(it.substrateAddress) @@ -222,7 +223,7 @@ class CredentialsRepositoryImpl constructor( return jsonSeedEncoder.generate( account = exportAccountData, password = password, - genesisHash = soraConfigManager.getGenesis() + genesisHash = localGenesis, ) } } else { @@ -238,7 +239,7 @@ class CredentialsRepositoryImpl constructor( ) } - return jsonSeedEncoder.generate(accountsList, password, soraConfigManager.getGenesis()) + return jsonSeedEncoder.generate(accountsList, password, localGenesis) } } diff --git a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryTest.kt b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryTest.kt index 721ec5812..481398066 100644 --- a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryTest.kt +++ b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/CredentialsRepositoryTest.kt @@ -36,6 +36,7 @@ import io.mockk.every import io.mockk.just import io.mockk.mockkObject import io.mockk.runs +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.logger.FirebaseWrapper import jp.co.soramitsu.common.util.CryptoAssistant @@ -43,7 +44,6 @@ import jp.co.soramitsu.common.util.json_decoder.JsonAccountsEncoder import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsDatasource import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager -import jp.co.soramitsu.test_shared.MainCoroutineRule import jp.co.soramitsu.xcrypto.seed.Mnemonic import jp.co.soramitsu.xcrypto.seed.MnemonicCreator import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair diff --git a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/UserRepositoryTest.kt b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/UserRepositoryTest.kt index 144d5e548..339752f46 100644 --- a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/UserRepositoryTest.kt +++ b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/UserRepositoryTest.kt @@ -41,6 +41,7 @@ import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.mockkStatic import io.mockk.slot +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.CardHubType @@ -57,7 +58,6 @@ import jp.co.soramitsu.core_db.model.SoraAccountLocal import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsDatasource import jp.co.soramitsu.feature_account_api.domain.interfaces.UserDatasource import jp.co.soramitsu.feature_account_api.domain.model.OnboardingState -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow diff --git a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsCredentialsDatasourceTest.kt b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsCredentialsDatasourceTest.kt index 525361b8f..37d9e8c08 100644 --- a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsCredentialsDatasourceTest.kt +++ b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsCredentialsDatasourceTest.kt @@ -33,9 +33,9 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_account_impl.data.repository.datasource import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.data.EncryptedPreferences import jp.co.soramitsu.common.data.SoraPreferences -import jp.co.soramitsu.test_shared.MainCoroutineRule import jp.co.soramitsu.xcrypto.util.toHexString import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsUserDatasourceTest.kt b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsUserDatasourceTest.kt index 10f6924ad..a7ed86a82 100644 --- a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsUserDatasourceTest.kt +++ b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/datasource/PrefsUserDatasourceTest.kt @@ -33,10 +33,10 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_account_impl.data.repository.datasource import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.data.EncryptedPreferences import jp.co.soramitsu.common.data.SoraPreferences import jp.co.soramitsu.feature_account_api.domain.model.OnboardingState -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Before diff --git a/feature_assets_api/build.gradle.kts b/feature_assets_api/build.gradle.kts index a2fee241c..a24d325fe 100644 --- a/feature_assets_api/build.gradle.kts +++ b/feature_assets_api/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/feature_assets_impl/build.gradle.kts b/feature_assets_impl/build.gradle.kts index 9f686b6bd..30c2f9064 100644 --- a/feature_assets_impl/build.gradle.kts +++ b/feature_assets_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -142,6 +152,10 @@ dependencies { } } - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt index 0a5912f18..2fb919e8d 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt @@ -35,6 +35,7 @@ package jp.co.soramitsu.feature_assets_impl.data import androidx.arch.core.executor.testing.InstantTaskExecutorRule import java.math.BigDecimal import java.math.BigInteger +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.domain.CoroutineManager @@ -49,13 +50,12 @@ import jp.co.soramitsu.core_db.model.AssetTokenWithFiatLocal import jp.co.soramitsu.core_db.model.TokenLocal import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager +import jp.co.soramitsu.feature_blockexplorer_api.data.models.SoraCurrency import jp.co.soramitsu.sora.substrate.models.ExtrinsicSubmitStatus import jp.co.soramitsu.sora.substrate.substrate.ExtrinsicManager import jp.co.soramitsu.sora.substrate.substrate.SubstrateCalls import jp.co.soramitsu.test_data.TestAssets import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraCurrency import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt index 88c33ffc2..d94605259 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt @@ -39,6 +39,7 @@ import io.mockk.junit4.MockKRule import io.mockk.mockkObject import io.mockk.mockkStatic import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.domain.CoroutineManager @@ -59,7 +60,6 @@ import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider import jp.co.soramitsu.sora.substrate.substrate.extrinsicHash import jp.co.soramitsu.test_data.TestAssets import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt index 380c0e62c..0106d840c 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt @@ -38,7 +38,6 @@ import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Assert import org.junit.Before @@ -49,7 +48,6 @@ import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.given @RunWith(MockitoJUnitRunner::class) -@OptIn(ExperimentalCoroutinesApi::class) class QrCodeInteractorTest { private val soraAccount = SoraAccount("address", "name") diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt index 45626700f..4def8aeaf 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt @@ -37,6 +37,8 @@ import io.mockk.every import io.mockk.mockkObject import java.math.BigDecimal import java.util.Collections +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.domain.AssetHolder import jp.co.soramitsu.common.domain.DEFAULT_ICON_URI @@ -52,8 +54,6 @@ import jp.co.soramitsu.test_data.TestTokens.valToken import jp.co.soramitsu.test_data.TestTokens.xorToken import jp.co.soramitsu.test_data.TestTokens.xstToken import jp.co.soramitsu.test_data.TestTokens.xstusdToken -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt index 631f959cd..35e12ccbd 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt @@ -47,6 +47,7 @@ import java.util.StringJoiner import jp.co.soramitsu.androidfoundation.format.Big100 import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.Asset @@ -59,7 +60,6 @@ import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor import jp.co.soramitsu.feature_assets_impl.presentation.screens.receiverequest.QRCodeFlowViewModel import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.test_data.TestAssets -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt index 2fa37351e..a3f1340dd 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt @@ -43,6 +43,7 @@ import java.math.BigDecimal import jp.co.soramitsu.androidfoundation.format.equalTo import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.util.NumbersFormatter @@ -53,7 +54,6 @@ import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.test_data.PolkaswapTestData import jp.co.soramitsu.test_data.TestAssets import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.advanceUntilIdle diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt index 9134e84db..eadbc06d7 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt @@ -40,6 +40,8 @@ import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.verify import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter @@ -48,8 +50,6 @@ import jp.co.soramitsu.feature_blockexplorer_api.domain.HistoryState import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler import jp.co.soramitsu.test_data.TestAccounts import jp.co.soramitsu.test_data.TestTokens.xorToken -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf diff --git a/feature_blockexplorer_api/build.gradle.kts b/feature_blockexplorer_api/build.gradle.kts index ed876eb0d..9e518d531 100644 --- a/feature_blockexplorer_api/build.gradle.kts +++ b/feature_blockexplorer_api/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -112,8 +122,6 @@ dependencies { implementation(libs.daggerDep) kapt(libs.daggerKaptDep) - - testImplementation(project(":test_shared")) } kapt { diff --git a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt index 82ccc68cd..9d88314c0 100644 --- a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt +++ b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt @@ -46,79 +46,93 @@ import jp.co.soramitsu.common.util.mapBalance import jp.co.soramitsu.core_db.AppDatabase import jp.co.soramitsu.core_db.model.FiatTokenPriceLocal import jp.co.soramitsu.core_db.model.ReferralLocal -import jp.co.soramitsu.xnetworking.basic.common.Utils.toDoubleNan -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuNetworkClient -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuNetworkException -import jp.co.soramitsu.xnetworking.sorawallet.blockexplorerinfo.SoraWalletBlockExplorerInfo -import jp.co.soramitsu.xnetworking.sorawallet.blockexplorerinfo.sbapy.SbApyInfo +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.api.BlockExplorerRepository +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.api.models.Apy +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.models.RestClientException +import jp.co.soramitsu.xnetworking.lib.engines.utils.JsonGetRequest import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import kotlinx.serialization.json.Json -import kotlinx.serialization.serializer + +fun String.toDoubleNan(): Double? = this.toDoubleOrNull()?.let { + if (it.isNaN()) null else it +} @Singleton class BlockExplorerManager @Inject constructor( - private val info: SoraWalletBlockExplorerInfo, + private val restClient: RestClient, + private val info: BlockExplorerRepository, private val db: AppDatabase, private val appStateProvider: AppStateProvider, - private val networkClient: SoramitsuNetworkClient, private val soraConfigManager: SoraConfigManager, ) { - private val tempApy = mutableListOf() + private val tempApy = mutableListOf() private var assetsInfo: List>? = null private val mutexFiat = Mutex() - fun getTempApy(id: String) = tempApy.find { - it.id == id - }?.sbApy?.times(100) + fun getTempApy(id: String) = tempApy.find { it.id == id }?.value?.toDoubleNan() + ?.times(100) - suspend fun getTokensLiquidity(tokenIds: List): List> = - assetsInfo ?: mutexFiat.withLock { - assetsInfo ?: getAssetsInfoInternal(tokenIds).also { - assetsInfo = it + suspend fun getTokensLiquidity(tokenIds: List): List> { + if (assetsInfo == null) { + mutexFiat.withLock { + if (assetsInfo == null) { + assetsInfo = getAssetsInfoInternal(tokenIds) + } } } - private suspend fun getAssetsInfoInternal(tokenIds: List): List> = - runCatching { + return checkNotNull(assetsInfo) + } + + private suspend fun getAssetsInfoInternal(tokenIds: List): List> { + return runCatching { val selected = soraConfigManager.getSelectedCurrency() val tokens = db.assetDao().getFiatTokenPriceLocal(selected.code) val yesterdayHour = yesterday() val resultList = mutableListOf>() val fiats = mutableListOf() + RetryStrategyBuilder.build().retryIf( retries = 3, - predicate = { t -> t is SoramitsuNetworkException }, - block = { info.getAssetsInfo(tokenIds, yesterdayHour) }, + predicate = { t -> t is RestClientException }, + block = { info.getAssetsInfo(soraConfigManager.getGenesis(), tokenIds, yesterdayHour.toInt()) }, ).forEach { assetInfo -> - val dbValue = tokens.find { it.tokenIdFiat == assetInfo.tokenId } - val delta = assetInfo.hourDelta + val dbValue = tokens.find { it.tokenIdFiat == assetInfo.id } + val delta = assetInfo.previousPrice + if (dbValue != null && delta != null) { - fiats.add( - dbValue.copy( - fiatChange = delta / 100.0, - fiatPricePrevHTime = yesterdayHour, - ) + fiats += dbValue.copy( + fiatChange = delta / 100.0, + fiatPricePrevHTime = yesterdayHour, ) } - dbValue?.tokenIdFiat?.let { tokenId -> - db.assetDao().getPrecisionOfToken(tokenId)?.let { precision -> - assetInfo.liquidity.toBigIntegerOrNull()?.let { mapBalance(it, precision) }?.let { supply -> - val tvl = supply.times(BigDecimal(dbValue.fiatPrice)) - resultList.add(assetInfo.tokenId to tvl.toDoubleInfinite()) - } - } - } + + val precision = db.assetDao().getPrecisionOfToken( + tokenId = dbValue?.tokenIdFiat ?: return@forEach + ) ?: return@forEach + + val supply = assetInfo.liquidity.toBigIntegerOrNull()?.let { + mapBalance(it, precision) + } ?: return@forEach + + resultList += Pair( + first = assetInfo.id, + second = supply.times(BigDecimal(dbValue.fiatPrice)) + .toDoubleInfinite() + ) } + db.assetDao().insertFiatPrice(fiats) resultList }.getOrElse { FirebaseWrapper.recordException(it) emptyList() } + } suspend fun updatePoolsSbApy() { updateSbApyInternal() @@ -127,41 +141,42 @@ class BlockExplorerManager @Inject constructor( suspend fun updateFiat() { if (appStateProvider.isForeground) { runCatching { - val response = info.getFiat() - updateFiatPrices(response.map { FiatInfo(it.id, it.priceUsd) }) + updateFiatPrices( + fiatData = info.getFiat(soraConfigManager.getGenesis()).map { + FiatInfo(it.id, it.priceUSD.toDoubleNan()) + } + ) } } } - suspend fun updateReferrerRewards( - address: String, - ) { + suspend fun updateReferrerRewards(address: String) { runCatching { - val response = info.getReferrerRewards(address) - response.rewards.map { + val rewards = info.getReferralReward(soraConfigManager.getGenesis(), address).map { ReferralLocal(it.referral, it.amount) } - } - .onSuccess { - db.withTransaction { - db.referralsDao().clearTable() - db.referralsDao().insertReferrals(it) - } - } - .onFailure { - FirebaseWrapper.recordException(it) + + db.withTransaction { + db.referralsDao().clearTable() + db.referralsDao().insertReferrals(rewards) } + }.onFailure { + FirebaseWrapper.recordException(it) + } } suspend fun getXorPerEurRatio(): Double? = runCatching { - val json = networkClient.get(BuildConfigWrapper.soraCardEuroRateUrl) - val soraCoin = Json.decodeFromString(serializer(), json) - soraCoin.price.toDoubleNan() + restClient.get( + request = JsonGetRequest( + url = BuildConfigWrapper.soraCardEuroRateUrl, + responseDeserializer = SoraCoin.serializer() + ) + ).price.toDoubleNan() }.getOrNull() private suspend fun updateSbApyInternal() { runCatching { - val response = info.getSpApy() + val response = info.getApy(soraConfigManager.getGenesis()) tempApy.clear() tempApy.addAll(response) } diff --git a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/SoraConfigManager.kt b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/SoraConfigManager.kt index cfa6e7fbd..3386edb6d 100644 --- a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/SoraConfigManager.kt +++ b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/SoraConfigManager.kt @@ -34,51 +34,204 @@ package jp.co.soramitsu.feature_blockexplorer_api.data import javax.inject.Inject import javax.inject.Singleton +import jp.co.soramitsu.androidfoundation.format.addHexPrefix +import jp.co.soramitsu.androidfoundation.format.removeHexPrefix import jp.co.soramitsu.common.data.SoraPreferences -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraConfig -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraConfigNode -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraCurrency -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraRemoteConfigBuilder +import jp.co.soramitsu.common.domain.OptionsProvider +import jp.co.soramitsu.common.util.CachingFactory +import jp.co.soramitsu.feature_blockexplorer_api.data.models.ConfigExplorerType +import jp.co.soramitsu.feature_blockexplorer_api.data.models.SoraConfig +import jp.co.soramitsu.feature_blockexplorer_api.data.models.SoraConfigNode +import jp.co.soramitsu.feature_blockexplorer_api.data.models.SoraCurrency +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient +import jp.co.soramitsu.xnetworking.lib.engines.utils.JsonGetRequest +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.json.Json @Singleton class SoraConfigManager @Inject constructor( - private val remoteConfigBuilder: SoraRemoteConfigBuilder, + private val json: Json, + private val restClient: RestClient, private val soraPreferences: SoraPreferences, ) { - companion object { - private const val SELECTED_CURRENCY = "selected_currency" - private val default = SoraCurrency("USD", "United States Dollar", "$") + private companion object { + const val SELECTED_CURRENCY = "selected_currency" + + val DEFAULT_SORA_CURRENCY = SoraCurrency( + code = "USD", + name = "United States Dollar", + sign = "$" + ) } - private suspend fun getConfig(): SoraConfig? = remoteConfigBuilder.getConfig() + private object EmptyArgs : CachingFactory.Args() + + private val soraConfigFactory = CachingFactory { + val commonConfig = tryLoadSaveRecoverMap( + url = { OptionsProvider.configCommon }, + nameToSaveWith = { "commonConfig" }, + deserializer = { ConfigDto.serializer() } + ) ?: return@CachingFactory null + + val mobileConfig = tryLoadSaveRecoverMap( + url = { OptionsProvider.configMobile }, + nameToSaveWith = { "mobileConfig" }, + deserializer = { MobileDto.serializer() } + ) ?: return@CachingFactory null + + val blockExplorerType = ConfigExplorerType( + fiat = mobileConfig.explorerTypeFiat, + reward = mobileConfig.explorerTypeReward, + sbapy = mobileConfig.explorerTypeSbapy, + assets = mobileConfig.explorerTypeAssets, + ) + + val nodes = commonConfig.nodes.map { nodeInfo -> + SoraConfigNode( + chain = nodeInfo.chain, + name = nodeInfo.name, + address = nodeInfo.address, + ) + } - suspend fun getNodes(): List { - return getConfig()?.nodes ?: emptyList() + val currencies = mobileConfig.currencies.map { currencyDto -> + SoraCurrency( + code = currencyDto.code, + name = currencyDto.name, + sign = currencyDto.sign, + ) + } + + return@CachingFactory SoraConfig( + blockExplorerUrl = commonConfig.subquery, + blockExplorerType = blockExplorerType, + nodes = nodes, + genesis = commonConfig.genesis, + joinUrl = mobileConfig.joinLink, + substrateTypesUrl = mobileConfig.substrateTypesAndroid, + soracard = mobileConfig.soracard, + currencies = currencies + ) } - suspend fun getSoraCard(): Boolean = - getConfig()?.soracard ?: false + private suspend inline fun tryLoadSaveRecoverMap( + url: () -> String, + nameToSaveWith: () -> String, + deserializer: () -> DeserializationStrategy + ): T? { + val result = runCatching { + restClient.getReturnString( + JsonGetRequest( + url = url(), + responseDeserializer = String.serializer() + ) + ) + }.onSuccess { configAsString -> + soraPreferences.putString( + field = nameToSaveWith(), + value = configAsString + ) + }.recoverCatching { + soraPreferences.getString( + field = nameToSaveWith() + ) + }.mapCatching { configAsString -> + json.decodeFromString( + deserializer = deserializer(), + string = configAsString + ) + }.getOrNull() - suspend fun getGenesis(): String = getConfig()?.genesis.orEmpty() + return result + } + + suspend fun getNodes(): List = + soraConfigFactory.nullableValue(EmptyArgs) + ?.nodes ?: emptyList() - suspend fun getInviteLink(): String = getConfig()?.joinUrl.orEmpty() + suspend fun getSoraCard(): Boolean = + soraConfigFactory.nullableValue(EmptyArgs) + ?.soracard ?: false - suspend fun getSubstrateTypesUrl(): String = getConfig()?.substrateTypesUrl.orEmpty() + suspend fun getGenesis(prefix: Boolean = false): String = + soraConfigFactory.nullableValue(EmptyArgs) + ?.genesis.orEmpty().removeHexPrefix().let { if (prefix) it.addHexPrefix() else it } - private suspend fun getCurrencies(): List = - getConfig()?.currencies ?: listOf(default) + suspend fun getInviteLink(): String = + soraConfigFactory.nullableValue(EmptyArgs) + ?.joinUrl.orEmpty() - private var selectedCurrency: SoraCurrency? = null + suspend fun getSubstrateTypesUrl(): String = + soraConfigFactory.nullableValue(EmptyArgs) + ?.substrateTypesUrl.orEmpty() - suspend fun getSelectedCurrency() = selectedCurrency ?: getSelectedCurrencyInternal().also { - selectedCurrency = it + private suspend fun getCurrencies(): List = + soraConfigFactory.nullableValue(EmptyArgs) + ?.currencies ?: listOf(DEFAULT_SORA_CURRENCY) + + private val selectedCurrencyFactory = CachingFactory { + val selectedCurrency = getCurrencies().find { + it.code == soraPreferences.getString(SELECTED_CURRENCY).ifEmpty { "USD" } + } + return@CachingFactory selectedCurrency ?: DEFAULT_SORA_CURRENCY } - private suspend fun getSelectedCurrencyInternal(): SoraCurrency = getCurrencies().find { - it.code == ( - soraPreferences.getString(SELECTED_CURRENCY).takeIf { pref -> pref.isNotEmpty() } - ?: "USD" - ) - } ?: default + suspend fun getSelectedCurrency() = + selectedCurrencyFactory.value(EmptyArgs) } + +@Serializable +private data class ConfigDto( + @SerialName("SUBQUERY_ENDPOINT") + val subquery: String, + @SerialName("DEFAULT_NETWORKS") + val nodes: List, + @SerialName("CHAIN_GENESIS_HASH") + val genesis: String, +) + +@Serializable +private data class NodeInfo( + @SerialName("chain") + val chain: String, + @SerialName("name") + val name: String, + @SerialName("address") + val address: String, +) + +@Serializable +private data class MobileDto( + @SerialName("explorer_type_fiat") + val explorerTypeFiat: String, + @SerialName("explorer_type_sbapy") + val explorerTypeSbapy: String, + @SerialName("explorer_type_reward") + val explorerTypeReward: String, + @SerialName("explorer_type_assets") + val explorerTypeAssets: String, + @SerialName("join_link") + val joinLink: String, + @SerialName("substrate_types_android") + val substrateTypesAndroid: String, + @SerialName("substrate_types_ios") + val substrateTypesIos: String, + @SerialName("soracard") + val soracard: Boolean = false, + @SerialName("currencies") + val currencies: List, +) + +@Serializable +private data class CurrencyDto( + @SerialName("code") + val code: String, + @SerialName("name") + val name: String, + @SerialName("sign") + val sign: String, +) diff --git a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/models/SoraConfig.kt b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/models/SoraConfig.kt new file mode 100644 index 000000000..bb16de167 --- /dev/null +++ b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/models/SoraConfig.kt @@ -0,0 +1,31 @@ +package jp.co.soramitsu.feature_blockexplorer_api.data.models + +data class SoraConfig( + val blockExplorerUrl: String, + val blockExplorerType: ConfigExplorerType, + val nodes: List, + val genesis: String, + val joinUrl: String, + val substrateTypesUrl: String, + val soracard: Boolean, + val currencies: List, +) + +data class SoraConfigNode( + val chain: String, + val name: String, + val address: String, +) + +data class SoraCurrency( + val code: String, + val name: String, + val sign: String, +) + +data class ConfigExplorerType( + val fiat: String, + val reward: String, + val sbapy: String, + val assets: String, +) diff --git a/feature_blockexplorer_impl/build.gradle.kts b/feature_blockexplorer_impl/build.gradle.kts index a07190e50..c39d27dc1 100644 --- a/feature_blockexplorer_impl/build.gradle.kts +++ b/feature_blockexplorer_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -115,6 +125,11 @@ dependencies { implementation(libs.daggerDep) kapt(libs.daggerKaptDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) + testImplementation(libs.truthDep) } diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryImpl.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryImpl.kt index 754571ebb..021151f3a 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryImpl.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryImpl.kt @@ -37,6 +37,7 @@ import javax.inject.Singleton import jp.co.soramitsu.androidfoundation.coroutine.SuspendableProperty import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.Token +import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.Transaction import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionStatus @@ -44,16 +45,19 @@ import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.Transact import jp.co.soramitsu.sora.substrate.runtime.Pallete import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider import jp.co.soramitsu.sora.substrate.substrate.ExtrinsicManager -import jp.co.soramitsu.xnetworking.basic.txhistory.TxHistoryItem -import jp.co.soramitsu.xnetworking.sorawallet.txhistory.client.SubQueryClientForSoraWallet +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.TxHistoryRepository +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.ChainInfo +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.TxFilter +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.TxHistoryItem import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.debounce @OptIn(ExperimentalCoroutinesApi::class) @Singleton class TransactionHistoryRepositoryImpl @Inject constructor( - private val subQueryClient: SubQueryClientForSoraWallet, + private val txHistoryRepository: TxHistoryRepository, extrinsicManager: ExtrinsicManager, + private val soraConfigManager: SoraConfigManager, ) : TransactionHistoryRepository { init { @@ -69,7 +73,7 @@ class TransactionHistoryRepositoryImpl @Inject constructor( } override suspend fun getContacts(query: String): Set = - subQueryClient.getTransactionPeers(query).toSet() + txHistoryRepository.getTransactionPeers(query, soraConfigManager.getGenesis()).toSet() private fun updateTransactionStatus(txHash: String, status: Boolean, block: String?) { localPendingTransactions[txHash]?.base?.status = @@ -84,14 +88,21 @@ class TransactionHistoryRepositoryImpl @Inject constructor( count: Int, filterTokenId: String?, ): List { - val tx = subQueryClient.getTransactionHistoryCached( + val tx = txHistoryRepository.getTransactionHistoryCached( + count = count, + address = soraAccount.substrateAddress, + chainId = soraConfigManager.getGenesis(), + ).filter { + if (filterTokenId != null) + return@filter isReferral(it, filterTokenId) + + return@filter true + } + val mapped = mapHistoryItemsToTransactions( + tx, soraAccount.substrateAddress, - count, - filter = if (filterTokenId == null) null else { r -> - filterHistoryItem(r, filterTokenId) - } + tokens ) - val mapped = mapHistoryItemsToTransactions(tx, soraAccount.substrateAddress, tokens) return buildList { addAll(filterLocalPendingTx(filterTokenId)) addAll(mapped) @@ -103,9 +114,10 @@ class TransactionHistoryRepositoryImpl @Inject constructor( tokens: List, soraAccount: SoraAccount ): Transaction? { - val tx = subQueryClient.getTransactionCached( + val tx = txHistoryRepository.getTransactionCached( address = soraAccount.substrateAddress, - txHash = txHash + txHash = txHash, + chainId = soraConfigManager.getGenesis(), ) val transaction = mapHistoryItemsToTransactions( @@ -124,26 +136,37 @@ class TransactionHistoryRepositoryImpl @Inject constructor( filterTokenId: String?, ): TransactionsInfo { val historyInfo = - subQueryClient.getTransactionHistoryPaged( + txHistoryRepository.getTransactionHistoryPaged( address = soraAccount.substrateAddress, page = page, - filter = if (filterTokenId == null) null else { r -> - filterHistoryItem(r, filterTokenId) - }, + chainInfo = ChainInfo.Simple("SoraChainId"), + pageCount = 100, + filters = TxFilter.entries.toSet() ) - val transactions = historyInfo?.items?.let { - mapHistoryItemsToTransactions(it, soraAccount.substrateAddress, tokens) - }.orEmpty() + val referralTransactions = historyInfo.items + .filter { item -> + if (filterTokenId != null) + return@filter isReferral(item, filterTokenId) + + return@filter true + }.let { item -> + mapHistoryItemsToTransactions( + item, + soraAccount.substrateAddress, + tokens + ) + } + val filtered = localPendingTransactions.filter { transactionLocal -> - transactions.find { transaction -> transaction.base.txHash == transactionLocal.key } == null + referralTransactions.find { transaction -> transaction.base.txHash == transactionLocal.key } == null } localPendingTransactions.clear() localPendingTransactions.putAll(filtered) return TransactionsInfo( buildList { if (page == 1L) addAll(filterLocalPendingTx(filterTokenId).sortedByDescending { it.base.timestamp }) - addAll(transactions) + addAll(referralTransactions) }, historyInfo?.endReached ?: true, historyInfo?.errorMessage, @@ -157,23 +180,22 @@ class TransactionHistoryRepositoryImpl @Inject constructor( _state.set(true) } - private fun filterHistoryItem(item: TxHistoryItem, tokenId: String): Boolean { - return ( + private fun isReferral(item: TxHistoryItem, tokenId: String): Boolean { + val hasTokenIdInMainParams = item.data?.find { it.paramValue == tokenId } != null - ) || ( + + val hasTokenIdInNestedParams = item.nestedData?.find { nested -> - nested.data.find { - it.paramValue == tokenId - } != null + nested.data.find { it.paramValue == tokenId } != null } != null - ) || ( - tokenId == SubstrateOptionsProvider.feeAssetId && item.module.equals( - Pallete.Referrals.palletName, - true - ) - ) + + val usedInReferralModule = + tokenId == SubstrateOptionsProvider.feeAssetId && + item.module.equals(Pallete.Referrals.palletName, true) + + return hasTokenIdInMainParams || hasTokenIdInNestedParams || usedInReferralModule } private fun filterLocalPendingTx(tokenId: String?): Collection = diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionMapper.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionMapper.kt index 6879db463..fae140509 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionMapper.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionMapper.kt @@ -50,8 +50,8 @@ import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.Transact import jp.co.soramitsu.sora.substrate.runtime.Method import jp.co.soramitsu.sora.substrate.runtime.Pallete import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider -import jp.co.soramitsu.xnetworking.basic.txhistory.TxHistoryItem -import jp.co.soramitsu.xnetworking.basic.txhistory.TxHistoryItemParam +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.TxHistoryItem +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.TxHistoryItemParam fun mapHistoryItemsToTransactions( txs: List, diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/di/FeatureBlockExplorerModule.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/di/FeatureBlockExplorerModule.kt index ccfec622d..afd2d7198 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/di/FeatureBlockExplorerModule.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/di/FeatureBlockExplorerModule.kt @@ -32,9 +32,11 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_blockexplorer_impl.di +import android.content.Context import dagger.Module import dagger.Provides import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import javax.inject.Singleton import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository @@ -45,11 +47,38 @@ import jp.co.soramitsu.feature_blockexplorer_impl.data.TransactionHistoryReposit import jp.co.soramitsu.feature_blockexplorer_impl.domain.TransactionBuilderImpl import jp.co.soramitsu.feature_blockexplorer_impl.domain.TransactionHistoryHandlerImpl import jp.co.soramitsu.feature_blockexplorer_impl.presentation.txhistory.TransactionMappersImpl +import jp.co.soramitsu.xnetworking.lib.datasources.chainsconfig.api.ConfigDAO +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.HistoryItemsFilter +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.TxHistoryRepository +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.TxHistoryItem +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.impl.TxHistoryRepositoryImpl +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.impl.builder.ExpectActualDBDriverFactory +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient @Module @InstallIn(SingletonComponent::class) class FeatureBlockExplorerModule { + private companion object { + const val txHistoryDBName = "historyDatabase.db" + } + + @Singleton + @Provides + fun provideTxHistoryRepository( + @ApplicationContext context: Context, + configDAO: ConfigDAO, + restClient: RestClient, + ): TxHistoryRepository = TxHistoryRepositoryImpl( + databaseDriverFactory = ExpectActualDBDriverFactory(context, txHistoryDBName), + configDAO = configDAO, + restClient = restClient, + historyItemsFilter = object : HistoryItemsFilter { + override fun List.filterCachedHistoryItems(): List = this + override fun List.filterPagedHistoryItems(): List = this + } + ) + @Singleton @Provides fun provideTransactionHistoryRepository( diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryTest.kt index 355343ec2..02e57a327 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/data/TransactionHistoryRepositoryTest.kt @@ -40,14 +40,15 @@ import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.mockkStatic import io.mockk.verify +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.Transaction import jp.co.soramitsu.feature_blockexplorer_impl.testdata.TestTransactions import jp.co.soramitsu.sora.substrate.substrate.ExtrinsicManager import jp.co.soramitsu.test_data.TestAccounts import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.xnetworking.sorawallet.txhistory.client.SubQueryClientForSoraWallet +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.TxHistoryRepository import junit.framework.TestCase.assertEquals import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest @@ -74,7 +75,10 @@ class TransactionHistoryRepositoryTest { val mockkRule = MockKRule(this) @MockK - private lateinit var subQueryClient: SubQueryClientForSoraWallet + private lateinit var txHistoryRepository: TxHistoryRepository + + @MockK + private lateinit var soraConfigManager: SoraConfigManager @MockK private lateinit var extrinsicManager: ExtrinsicManager @@ -89,15 +93,31 @@ class TransactionHistoryRepositoryTest { fun setUp() = runTest { mockkStatic(Uri::parse) every { Uri.parse(any()) } returns mockedUri - every { extrinsicManager.setWatchingExtrinsicListener(any()) } returns Unit - every { subQueryClient.getTransactionPeers("query") } returns peersList + every { + extrinsicManager.setWatchingExtrinsicListener( + listener = any() + ) + } returns Unit + coEvery { soraConfigManager.getGenesis() } returns "7e4e" + every { + txHistoryRepository.getTransactionPeers( + query = "query", + chainId = "7e4e", + ) + } returns peersList + coEvery { - subQueryClient.getTransactionHistoryCached(TestAccounts.soraAccount.substrateAddress, 1, null) + txHistoryRepository.getTransactionHistoryCached( + address = TestAccounts.soraAccount.substrateAddress, + count = 1, + chainId = "7e4e", + ) } returns listOf(TestTransactions.txHistoryItem) transactionHistoryRepository = TransactionHistoryRepositoryImpl( - subQueryClient, - extrinsicManager + txHistoryRepository, + extrinsicManager, + soraConfigManager, ) } diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt index 5a54f1c0a..f3bd94b01 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt @@ -35,6 +35,8 @@ package jp.co.soramitsu.feature_blockexplorer_impl.domain import jp.co.soramitsu.androidfoundation.format.safeCast import jp.co.soramitsu.androidfoundation.format.unsafeCast import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.test import jp.co.soramitsu.common.date.DateTimeFormatter import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.domain.DEFAULT_ICON_URI @@ -53,8 +55,6 @@ import jp.co.soramitsu.feature_blockexplorer_impl.presentation.txhistory.Transac import jp.co.soramitsu.feature_blockexplorer_impl.testdata.TestTransactions import jp.co.soramitsu.test_data.TestAccounts import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.test import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertTrue import kotlinx.coroutines.CoroutineDispatcher diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt index f64598f39..65f4982b2 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt @@ -33,6 +33,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_blockexplorer_impl.presentation.screen import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_blockexplorer_api.domain.HistoryState @@ -40,7 +41,6 @@ import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandle import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.test_data.TestAccounts -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt index 537804e37..28e171414 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt @@ -41,6 +41,8 @@ import io.mockk.verify import java.util.Date import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.date.DateTimeFormatter import jp.co.soramitsu.common.domain.DEFAULT_ICON_URI @@ -58,8 +60,6 @@ import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.test_data.TestAccounts import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import junit.framework.TestCase.assertEquals import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/testdata/TestTransactions.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/testdata/TestTransactions.kt index 4ea0e0eae..4fa54d5be 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/testdata/TestTransactions.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/testdata/TestTransactions.kt @@ -41,8 +41,8 @@ import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.Transact import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionTransferType import jp.co.soramitsu.test_data.TestAccounts import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.xnetworking.basic.txhistory.TxHistoryItem -import jp.co.soramitsu.xnetworking.basic.txhistory.TxHistoryItemParam +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.TxHistoryItem +import jp.co.soramitsu.xnetworking.lib.datasources.txhistory.api.models.TxHistoryItemParam object TestTransactions { val txHistoryItem = TxHistoryItem( diff --git a/feature_ecosystem_impl/build.gradle.kts b/feature_ecosystem_impl/build.gradle.kts index ecc6f0a2a..daf26999c 100644 --- a/feature_ecosystem_impl/build.gradle.kts +++ b/feature_ecosystem_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -124,6 +134,10 @@ dependencies { debugImplementation(libs.composeToolingDep) implementation(libs.navigationComposeDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt b/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt index 182e000ab..6d57dd38c 100644 --- a/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt +++ b/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt @@ -39,6 +39,7 @@ import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.verify import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.demeter.domain.DemeterFarmingBasicPool import jp.co.soramitsu.demeter.domain.DemeterFarmingInteractor @@ -52,7 +53,6 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.test_data.PolkaswapTestData.BASIC_POOL_DATA import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest diff --git a/feature_ethereum_api/build.gradle.kts b/feature_ethereum_api/build.gradle.kts index e23525987..d996d7ae3 100644 --- a/feature_ethereum_api/build.gradle.kts +++ b/feature_ethereum_api/build.gradle.kts @@ -61,6 +61,4 @@ dependencies { implementation(libs.coroutineAndroidDep) implementation(libs.coroutineDep) - - testImplementation(project(":test_shared")) } diff --git a/feature_main_impl/build.gradle.kts b/feature_main_impl/build.gradle.kts index 433f5a3cb..bd95d5a4d 100644 --- a/feature_main_impl/build.gradle.kts +++ b/feature_main_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -134,6 +144,10 @@ dependencies { implementation(libs.insetterDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/domain/PinCodeInteractorTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/domain/PinCodeInteractorTest.kt index e8e0a59ab..56ad8be40 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/domain/PinCodeInteractorTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/domain/PinCodeInteractorTest.kt @@ -32,12 +32,12 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_main_impl.domain +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.IrohaData import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletRepository -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt index b28aef749..6dfd2e966 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt @@ -35,6 +35,8 @@ package jp.co.soramitsu.feature_main_impl.presentation import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.every import io.mockk.mockkObject +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.domain.RepeatStrategy import jp.co.soramitsu.common.domain.RepeatStrategyBuilder @@ -46,8 +48,6 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsUpdateSubscr import jp.co.soramitsu.feature_select_node_api.NodeManager import jp.co.soramitsu.feature_sora_card_api.domain.SoraCardInteractor import jp.co.soramitsu.test_data.TestAccounts -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/language/SelectLanguageViewModelTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/language/SelectLanguageViewModelTest.kt index fcca07bbf..9bab13bb9 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/language/SelectLanguageViewModelTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/language/SelectLanguageViewModelTest.kt @@ -34,11 +34,11 @@ package jp.co.soramitsu.feature_main_impl.presentation.language import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.resourses.Language import jp.co.soramitsu.feature_main_impl.domain.MainInteractor -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/pincode/PinCodeViewModelTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/pincode/PinCodeViewModelTest.kt index 528aa04ca..6bb03ce85 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/pincode/PinCodeViewModelTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/pincode/PinCodeViewModelTest.kt @@ -34,6 +34,7 @@ package jp.co.soramitsu.feature_main_impl.presentation.pincode import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.interfaces.WithProgress @@ -44,7 +45,6 @@ import jp.co.soramitsu.feature_main_impl.domain.MainInteractor import jp.co.soramitsu.feature_main_impl.domain.PinCodeInteractor import jp.co.soramitsu.feature_select_node_api.SelectNodeRouter import jp.co.soramitsu.sora.substrate.substrate.ConnectionManager -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flowOf diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt index d878700f3..09a47e976 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt @@ -41,6 +41,8 @@ import io.mockk.just import io.mockk.runs import io.mockk.verify import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.domain.ChainNode import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager @@ -56,8 +58,6 @@ import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.oauth.base.sdk.contract.SoraCardCommonVerification import jp.co.soramitsu.oauth.base.sdk.contract.SoraCardFlow import jp.co.soramitsu.test_data.SoraCardTestData.soraCardBasicStatusTest -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertNotNull import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/feature_multiaccount_api/build.gradle.kts b/feature_multiaccount_api/build.gradle.kts index 7eb301658..eeb436ecc 100644 --- a/feature_multiaccount_api/build.gradle.kts +++ b/feature_multiaccount_api/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/feature_multiaccount_impl/build.gradle.kts b/feature_multiaccount_impl/build.gradle.kts index 6d05f2efe..c0dc4dee6 100644 --- a/feature_multiaccount_impl/build.gradle.kts +++ b/feature_multiaccount_impl/build.gradle.kts @@ -67,6 +67,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -127,5 +137,9 @@ dependencies { implementation(libs.hiltNavComposeDep) kapt(libs.daggerKaptDep) - testImplementation(project(":test_shared")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt index e8b428241..35f3f9535 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt @@ -38,12 +38,12 @@ import androidx.lifecycle.viewModelScope import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import jp.co.soramitsu.androidfoundation.format.addHexPrefix import jp.co.soramitsu.androidfoundation.fragment.trigger import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.androidfoundation.resource.ResourceManager import jp.co.soramitsu.common.presentation.compose.components.initMediumTitle2 import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.util.ext.addHexPrefix import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_multiaccount_impl.R import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/OnboardingViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/OnboardingViewModelTest.kt index 6c36cdbe5..3472aedc3 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/OnboardingViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/OnboardingViewModelTest.kt @@ -35,6 +35,7 @@ package jp.co.soramitsu.feature_multiaccount_impl import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.navigation.NavController import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.domain.CoroutineManager @@ -44,7 +45,6 @@ import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.OnboardingViewModel import jp.co.soramitsu.feature_multiaccount_impl.presentation.RecoveryState import jp.co.soramitsu.feature_multiaccount_impl.presentation.RecoveryType -import jp.co.soramitsu.test_shared.MainCoroutineRule import jp.co.soramitsu.ui_core.component.input.InputTextState import jp.co.soramitsu.xbackup.BackupService import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt index 13edd7119..4da933834 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt @@ -39,6 +39,7 @@ import io.mockk.coVerify import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.mockk +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.io.FileManager import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository @@ -46,7 +47,6 @@ import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_account_api.domain.model.OnboardingState import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletRepository import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager -import jp.co.soramitsu.test_shared.MainCoroutineRule import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt index 78ab01752..08e06ebdd 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt @@ -39,6 +39,8 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.navigation.NavController import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.CoroutineManager @@ -46,8 +48,6 @@ import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.account_details.AccountDetailsViewModel import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.model.AccountDetailsScreenState -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import jp.co.soramitsu.ui_core.component.input.InputTextState import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import jp.co.soramitsu.xbackup.BackupService diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt index df724bfbd..6dd984737 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt @@ -35,6 +35,8 @@ package jp.co.soramitsu.feature_multiaccount_impl.export.account_list import android.graphics.drawable.PictureDrawable import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.account.SoraAccount @@ -43,8 +45,6 @@ import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.account_list.AccountListViewModel import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.model.AccountListScreenState import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.model.ExportAccountData -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt index 8a923e15d..bf344973c 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt @@ -35,15 +35,14 @@ package jp.co.soramitsu.feature_multiaccount_impl.export.backup import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R as commonR -import jp.co.soramitsu.common.util.ext.addHexPrefix import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.backup.BackupViewModel import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.model.BackupScreenState import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.protection.ExportProtectionViewModel -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest @@ -134,7 +133,7 @@ class BackupViewModelTest { fun backupPressedWithSeed() { setUp(ExportProtectionViewModel.Type.SEED) viewModel.backupPressed() - verify(clipboardManager).addToClipboard(seed.addHexPrefix()) + verify(clipboardManager).addToClipboard("0x$seed") viewModel.copiedToast.getOrAwaitValue() } diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/json/BackupJsonViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/json/BackupJsonViewModelTest.kt index cf6db6158..54d9ea582 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/json/BackupJsonViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/json/BackupJsonViewModelTest.kt @@ -35,12 +35,12 @@ package jp.co.soramitsu.feature_multiaccount_impl.export.backup.json import android.net.Uri import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.compose.ui.text.input.TextFieldValue +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_multiaccount_impl.R import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.backup.json.BackupJsonViewModel import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.model.BackupJsonScreenState -import jp.co.soramitsu.test_shared.MainCoroutineRule import jp.co.soramitsu.ui_core.component.input.InputTextState import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/protection/ExportProtectionViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/protection/ExportProtectionViewModelTest.kt index 22d0bdd46..6fb2a5824 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/protection/ExportProtectionViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/protection/ExportProtectionViewModelTest.kt @@ -33,9 +33,9 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_multiaccount_impl.export.protection import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.protection.ExportProtectionViewModel -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Assert.assertFalse diff --git a/feature_polkaswap_api/build.gradle.kts b/feature_polkaswap_api/build.gradle.kts index fcd7a6446..3957a7d9c 100644 --- a/feature_polkaswap_api/build.gradle.kts +++ b/feature_polkaswap_api/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/feature_polkaswap_impl/build.gradle.kts b/feature_polkaswap_impl/build.gradle.kts index b33f6fc35..c52473545 100644 --- a/feature_polkaswap_impl/build.gradle.kts +++ b/feature_polkaswap_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -133,6 +143,10 @@ dependencies { debugImplementation(libs.composeToolingDep) implementation(libs.navigationComposeDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt index cb0baa360..bbf99e1c0 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt @@ -34,6 +34,7 @@ package jp.co.soramitsu.feature_polkaswap_impl.domain import androidx.arch.core.executor.testing.InstantTaskExecutorRule import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common_wallet.domain.model.WithDesired import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository @@ -46,7 +47,6 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapReposito import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapSubscriptionRepository import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt index 26bc94141..b502d63fa 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt @@ -33,6 +33,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_polkaswap_impl.domain import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_assets_api.data.AssetsRepository @@ -42,7 +43,6 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapExtrinsi import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapRepository import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapSubscriptionRepository import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Before diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt index 2ee14467a..efb74e042 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt @@ -35,6 +35,9 @@ package jp.co.soramitsu.feature_polkaswap_impl.presentation.polkaswap import androidx.arch.core.executor.testing.InstantTaskExecutorRule import java.math.BigDecimal import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.anyNonNull +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.domain.Market @@ -53,9 +56,6 @@ import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.test_data.PolkaswapTestData import jp.co.soramitsu.test_data.TestAssets import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.anyNonNull -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.flow diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt index f04a0a01d..ae404bede 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt @@ -37,6 +37,7 @@ import io.mockk.mockkObject import java.math.BigDecimal import jp.co.soramitsu.androidfoundation.format.equalTo import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.logger.FirebaseWrapper @@ -55,7 +56,6 @@ import jp.co.soramitsu.test_data.PolkaswapTestData.XOR_ASSET import jp.co.soramitsu.test_data.PolkaswapTestData.XSTXAU_ASSET import jp.co.soramitsu.test_data.TestAssets import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt index bda862285..6d6e8006e 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt @@ -36,6 +36,7 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import java.math.BigDecimal import jp.co.soramitsu.androidfoundation.format.equalTo import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor @@ -51,7 +52,6 @@ import jp.co.soramitsu.test_data.PolkaswapTestData.XOR_ASSET import jp.co.soramitsu.test_data.PolkaswapTestData.XOR_ASSET_ZERO_BALANCE import jp.co.soramitsu.test_data.TestAssets import jp.co.soramitsu.test_data.TestTokens -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.flowOf diff --git a/feature_referral_api/build.gradle.kts b/feature_referral_api/build.gradle.kts index 400e04147..eff44a145 100644 --- a/feature_referral_api/build.gradle.kts +++ b/feature_referral_api/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -64,7 +74,6 @@ dependencies { implementation(libs.navigationFragmentDep) implementation(libs.navigationUiDep) - implementation(libs.xnetworkingDep) implementation(libs.xsubstrateDep) implementation(libs.daggerDep) diff --git a/feature_referral_api/src/main/java/jp/co/soramitsu/feature_referral_api/data/ReferralRepository.kt b/feature_referral_api/src/main/java/jp/co/soramitsu/feature_referral_api/data/ReferralRepository.kt index 04b3548f4..8c7252dca 100644 --- a/feature_referral_api/src/main/java/jp/co/soramitsu/feature_referral_api/data/ReferralRepository.kt +++ b/feature_referral_api/src/main/java/jp/co/soramitsu/feature_referral_api/data/ReferralRepository.kt @@ -35,7 +35,7 @@ package jp.co.soramitsu.feature_referral_api.data import java.math.BigDecimal import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.Transaction -import jp.co.soramitsu.xnetworking.sorawallet.blockexplorerinfo.referral.ReferrerReward +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.api.models.ReferralReward import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair import kotlinx.coroutines.flow.Flow @@ -43,7 +43,7 @@ interface ReferralRepository { suspend fun updateReferralRewards(address: String) - fun getReferralRewards(): Flow> + fun getReferralRewards(): Flow> suspend fun getSetReferrerFee(from: String, feeToken: Token): BigDecimal? diff --git a/feature_referral_impl/build.gradle.kts b/feature_referral_impl/build.gradle.kts index 070f20b07..1dc70c514 100644 --- a/feature_referral_impl/build.gradle.kts +++ b/feature_referral_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -119,6 +129,10 @@ dependencies { implementation(libs.daggerDep) kapt(libs.daggerKaptDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryImpl.kt b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryImpl.kt index c6d4b6ed6..f8a08c2d2 100644 --- a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryImpl.kt +++ b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryImpl.kt @@ -53,7 +53,7 @@ import jp.co.soramitsu.sora.substrate.substrate.SubstrateCalls import jp.co.soramitsu.sora.substrate.substrate.referralBond import jp.co.soramitsu.sora.substrate.substrate.referralUnbond import jp.co.soramitsu.sora.substrate.substrate.setReferrer -import jp.co.soramitsu.xnetworking.sorawallet.blockexplorerinfo.referral.ReferrerReward +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.api.models.ReferralReward import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair import jp.co.soramitsu.xsubstrate.runtime.definitions.types.fromHex import jp.co.soramitsu.xsubstrate.runtime.metadata.module @@ -222,10 +222,10 @@ class ReferralRepositoryImpl @Inject constructor( } } - override fun getReferralRewards(): Flow> { + override fun getReferralRewards(): Flow> { return db.referralsDao().getReferrals().map { list -> list.map { - ReferrerReward(it.address, it.amount) + ReferralReward(it.address, it.amount) } } } diff --git a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryTest.kt b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryTest.kt index 46cb75ee7..af24b733d 100644 --- a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryTest.kt +++ b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/data/ReferralRepositoryTest.kt @@ -33,6 +33,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_referral_impl.data import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.core_db.AppDatabase import jp.co.soramitsu.core_db.dao.ReferralsDao import jp.co.soramitsu.core_db.model.ReferralLocal @@ -41,8 +42,7 @@ import jp.co.soramitsu.feature_referral_api.data.ReferralRepository import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.sora.substrate.substrate.ExtrinsicManager import jp.co.soramitsu.sora.substrate.substrate.SubstrateCalls -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.xnetworking.sorawallet.blockexplorerinfo.referral.ReferrerReward +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.api.models.ReferralReward import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.toList @@ -90,7 +90,7 @@ class ReferralRepositoryTest { private lateinit var referralRepository: ReferralRepository private val REFERRER_REWARDS = listOf( - ReferrerReward( + ReferralReward( "address", "1000000000000000000" ) diff --git a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt index 6e94d1988..73bf2c195 100644 --- a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt +++ b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt @@ -34,6 +34,7 @@ package jp.co.soramitsu.feature_referral_impl.domain import androidx.arch.core.executor.testing.InstantTaskExecutorRule import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository @@ -43,8 +44,7 @@ import jp.co.soramitsu.feature_referral_api.data.ReferralRepository import jp.co.soramitsu.feature_referral_impl.domain.model.Referral import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletRepository import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.xnetworking.sorawallet.blockexplorerinfo.referral.ReferrerReward +import jp.co.soramitsu.xnetworking.lib.datasources.blockexplorer.api.models.ReferralReward import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.toList @@ -95,7 +95,7 @@ class ReferralInteractorTest { private lateinit var interactor: ReferralInteractor private val REFERRER_REWARDS = listOf( - ReferrerReward( + ReferralReward( "address", "1000000000000000000" ) diff --git a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt index d8ab81e68..57dca3aca 100644 --- a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt +++ b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt @@ -36,6 +36,8 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.compose.ui.text.input.TextFieldValue import java.math.BigDecimal import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.util.NumbersFormatter @@ -47,8 +49,6 @@ import jp.co.soramitsu.feature_referral_impl.domain.model.Referral import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider import jp.co.soramitsu.test_data.TestAssets -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType diff --git a/feature_select_node_api/build.gradle.kts b/feature_select_node_api/build.gradle.kts index 78fa75d63..ea55d05c5 100644 --- a/feature_select_node_api/build.gradle.kts +++ b/feature_select_node_api/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/feature_select_node_impl/build.gradle.kts b/feature_select_node_impl/build.gradle.kts index f92eef8a0..c20b10f5b 100644 --- a/feature_select_node_impl/build.gradle.kts +++ b/feature_select_node_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -89,7 +99,6 @@ dependencies { implementation(libs.navigationFragmentDep) implementation(libs.navigationUiDep) - implementation(libs.xnetworkingDep) implementation(libs.xsubstrateDep) implementation(libs.roomDep) @@ -114,5 +123,9 @@ dependencies { implementation(libs.daggerDep) kapt(libs.daggerKaptDep) - testImplementation(project(":test_shared")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_select_node_impl/src/main/java/jp/co/soramitsu/feature_select_node_impl/NodeManagerImpl.kt b/feature_select_node_impl/src/main/java/jp/co/soramitsu/feature_select_node_impl/NodeManagerImpl.kt index ae855b8e9..0d9da50c3 100644 --- a/feature_select_node_impl/src/main/java/jp/co/soramitsu/feature_select_node_impl/NodeManagerImpl.kt +++ b/feature_select_node_impl/src/main/java/jp/co/soramitsu/feature_select_node_impl/NodeManagerImpl.kt @@ -203,7 +203,7 @@ internal class NodeManagerImpl( if (state.url == customNodeUrl) { blockHashCheckObserverEnabled = false try { - val newHash = selectNodeRepository.getBlockHash().removeHexPrefix() + val newHash = selectNodeRepository.getBlockHash() if (BuildUtils.isFlavors( Flavor.DEVELOP, Flavor.SORALUTION @@ -211,7 +211,7 @@ internal class NodeManagerImpl( ) { _events.emit(NodeManagerEvent.GenesisValidated(result = true)) } else { - _events.emit(NodeManagerEvent.GenesisValidated(result = soraConfigManager.getGenesis() == newHash)) + _events.emit(NodeManagerEvent.GenesisValidated(result = soraConfigManager.getGenesis().removeHexPrefix() == newHash.removeHexPrefix())) } } catch (e: Throwable) { _events.emit(NodeManagerEvent.GenesisValidated(result = false)) diff --git a/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/details/NodeDetailsViewModelTest.kt b/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/details/NodeDetailsViewModelTest.kt index 78e42667b..2d05fcb03 100644 --- a/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/details/NodeDetailsViewModelTest.kt +++ b/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/details/NodeDetailsViewModelTest.kt @@ -35,6 +35,8 @@ package jp.co.soramitsu.feature_select_node_impl.presentation.details import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.compose.ui.text.input.TextFieldValue import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.ChainNode import jp.co.soramitsu.common.util.Const @@ -50,8 +52,6 @@ import jp.co.soramitsu.feature_select_node_impl.TestData.NODE_LIST import jp.co.soramitsu.feature_select_node_impl.TestData.SELECTED_NODE import jp.co.soramitsu.feature_select_node_impl.domain.SelectNodeInteractor import jp.co.soramitsu.feature_select_node_impl.domain.ValidationEvent -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf diff --git a/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/domain/NodeValidatorTest.kt b/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/domain/NodeValidatorTest.kt index 4b2f55b85..f0f0f7c23 100644 --- a/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/domain/NodeValidatorTest.kt +++ b/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/domain/NodeValidatorTest.kt @@ -33,10 +33,10 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_select_node_impl.presentation.domain import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.feature_select_node_impl.domain.InetAddressesWrapper import jp.co.soramitsu.feature_select_node_impl.domain.NodeValidator import jp.co.soramitsu.feature_select_node_impl.domain.ValidationEvent -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals diff --git a/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/select/SelectNodeViewModelTest.kt b/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/select/SelectNodeViewModelTest.kt index 8ab12894c..a7e15558e 100644 --- a/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/select/SelectNodeViewModelTest.kt +++ b/feature_select_node_impl/src/test/java/jp/co/soramitsu/feature_select_node_impl/presentation/select/SelectNodeViewModelTest.kt @@ -34,6 +34,8 @@ package jp.co.soramitsu.feature_select_node_impl.presentation.select import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.feature_main_api.domain.model.PinCodeAction import jp.co.soramitsu.feature_main_api.launcher.MainRouter @@ -47,8 +49,6 @@ import jp.co.soramitsu.feature_select_node_impl.TestData.SELECTED_NODE import jp.co.soramitsu.feature_select_node_impl.domain.SelectNodeInteractor import jp.co.soramitsu.feature_select_node_impl.presentation.select.model.RemoveNodeAlertState import jp.co.soramitsu.feature_select_node_impl.presentation.select.model.SwitchNodeAlertState -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf diff --git a/feature_sora_card_api/build.gradle.kts b/feature_sora_card_api/build.gradle.kts index 7838f83b9..130eaed23 100644 --- a/feature_sora_card_api/build.gradle.kts +++ b/feature_sora_card_api/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/feature_sora_card_impl/build.gradle.kts b/feature_sora_card_impl/build.gradle.kts index 14a724ffc..f40ceb645 100644 --- a/feature_sora_card_impl/build.gradle.kts +++ b/feature_sora_card_impl/build.gradle.kts @@ -63,6 +63,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -116,6 +126,10 @@ dependencies { implementation(libs.daggerDep) kapt(libs.daggerKaptDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt b/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt index 9e75627d6..95026d91d 100644 --- a/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt +++ b/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt @@ -37,6 +37,8 @@ import io.mockk.every import io.mockk.mockkObject import java.math.BigDecimal import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.OptionsProvider import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter @@ -49,8 +51,6 @@ import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider import jp.co.soramitsu.sora.substrate.substrate.ConnectionManager import jp.co.soramitsu.test_data.SoraCardTestData.soraCardBasicStatusTest -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow diff --git a/feature_wallet_api/build.gradle.kts b/feature_wallet_api/build.gradle.kts index 28c22ecb4..619396621 100644 --- a/feature_wallet_api/build.gradle.kts +++ b/feature_wallet_api/build.gradle.kts @@ -52,6 +52,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/feature_wallet_impl/build.gradle.kts b/feature_wallet_impl/build.gradle.kts index 9c2fdae03..393319405 100644 --- a/feature_wallet_impl/build.gradle.kts +++ b/feature_wallet_impl/build.gradle.kts @@ -67,6 +67,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -127,7 +137,7 @@ dependencies { implementation(libs.uiCoreDep) - implementation(platform(libs.compose.bom)) +// implementation(platform(libs.compose.bom)) implementation(libs.composeUiDep) implementation(libs.composeFoundationDep) implementation(libs.composeMaterialDep) @@ -143,6 +153,10 @@ dependencies { implementation(libs.kotlinxSerializationJsonDep) - testImplementation(project(":test_shared")) testImplementation(project(":test_data")) + testImplementation(libs.coroutineTestDep) + testImplementation(libs.junitDep) + testImplementation(libs.mockkDep) + testImplementation(libs.mockitoKotlinDep) + testImplementation(libs.archCoreTestDep) } diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/BuyCryptoDataSourceImpl.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/BuyCryptoDataSourceImpl.kt index 6f915c426..61e3f264e 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/BuyCryptoDataSourceImpl.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/BuyCryptoDataSourceImpl.kt @@ -40,23 +40,15 @@ import jp.co.soramitsu.network.WebSocket import jp.co.soramitsu.network.WebSocketListener import jp.co.soramitsu.network.WebSocketRequest import jp.co.soramitsu.network.WebSocketResponse -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuHttpClientProvider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json class BuyCryptoDataSourceImpl( - clientProvider: SoramitsuHttpClientProvider + private val json: Json ) : BuyCryptoDataSource { - private val json = Json { - prettyPrint = true - isLenient = true - ignoreUnknownKeys = true - } - private val paymentOrderFlow = MutableSharedFlow() private val webSocketListener = object : WebSocketListener { @@ -77,8 +69,7 @@ class BuyCryptoDataSourceImpl( url = BuildConfigWrapper.soraCardX1StatusUrl, listener = webSocketListener, json = json, - logging = false, - provider = clientProvider, + logging = false ) override suspend fun requestPaymentOrderStatus(paymentOrder: PaymentOrder) { diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt index 00e3aff5d..dac643d4a 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt @@ -57,8 +57,8 @@ import jp.co.soramitsu.feature_wallet_impl.data.repository.datasource.PrefsWalle import jp.co.soramitsu.feature_wallet_impl.domain.PoolsFeatureStorageManager import jp.co.soramitsu.feature_wallet_impl.domain.WalletInteractorImpl import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuHttpClientProvider import kotlinx.coroutines.FlowPreview +import kotlinx.serialization.json.Json @FlowPreview @Module @@ -77,10 +77,8 @@ class WalletFeatureModule { @Provides @Singleton - fun provideBuyCryptoDataSource( - clientProvider: SoramitsuHttpClientProvider - ): BuyCryptoDataSource = - BuyCryptoDataSourceImpl(clientProvider) + fun provideBuyCryptoDataSource(json: Json): BuyCryptoDataSource = + BuyCryptoDataSourceImpl(json) @Singleton @Provides diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/WalletRepositoryTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/WalletRepositoryTest.kt index 9ab5f9dd5..fd4225e53 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/WalletRepositoryTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/WalletRepositoryTest.kt @@ -34,6 +34,7 @@ package jp.co.soramitsu.feature_wallet_impl.data.repository import androidx.arch.core.executor.testing.InstantTaskExecutorRule import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.domain.DEFAULT_ICON_URI import jp.co.soramitsu.common.domain.Token @@ -51,8 +52,6 @@ import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.sora.substrate.substrate.ExtrinsicManager import jp.co.soramitsu.sora.substrate.substrate.SubstrateCalls import jp.co.soramitsu.test_data.TestAssets -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraCurrency import jp.co.soramitsu.xsubstrate.encrypt.keypair.substrate.Sr25519Keypair import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf @@ -178,12 +177,6 @@ class WalletRepositoryTest { verify(globalCardsHubDao).updateCardVisibility(cardId = "cardId", visibility = true) } - private val usdFiat = SoraCurrency( - code = "USD", - name = "Dollar", - sign = "$", - ) - private fun assetLocalList() = listOf( AssetLocal( "0x0200000000000000000000000000000000000000000000000000000000000000", diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/PrefsWalletDatasourceTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/PrefsWalletDatasourceTest.kt index 9f92fe70a..7d432988e 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/PrefsWalletDatasourceTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/data/repository/datasource/PrefsWalletDatasourceTest.kt @@ -33,10 +33,10 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_wallet_impl.data.repository.datasource import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.data.EncryptedPreferences import jp.co.soramitsu.common.data.SoraPreferences import jp.co.soramitsu.feature_wallet_api.domain.model.MigrationStatus -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/buycrypto/BuyCryptoViewModelTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/buycrypto/BuyCryptoViewModelTest.kt index a2b7a2bad..484184a27 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/buycrypto/BuyCryptoViewModelTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/buycrypto/BuyCryptoViewModelTest.kt @@ -38,13 +38,13 @@ import io.mockk.every import io.mockk.mockkObject import io.mockk.mockkStatic import java.util.UUID +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.config.BuildConfigWrapper import jp.co.soramitsu.common.util.BuildUtils import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_wallet_api.domain.interfaces.BuyCryptoRepository -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/claim/ClaimViewModelTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/claim/ClaimViewModelTest.kt index dc8c84102..9dc50fd23 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/claim/ClaimViewModelTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/claim/ClaimViewModelTest.kt @@ -35,10 +35,10 @@ package jp.co.soramitsu.feature_wallet_impl.presentation.claim import android.content.Context import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.feature_wallet_api.domain.model.MigrationStatus import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow import kotlinx.coroutines.test.advanceUntilIdle diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/contacts/ContactsViewModelTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/contacts/ContactsViewModelTest.kt index 2122306a7..ec707393c 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/contacts/ContactsViewModelTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/contacts/ContactsViewModelTest.kt @@ -36,11 +36,11 @@ import android.graphics.drawable.PictureDrawable import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.compose.ui.text.input.TextFieldValue import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter -import jp.co.soramitsu.test_shared.MainCoroutineRule import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt index 56f87b20a..8a09e4b91 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt @@ -43,6 +43,8 @@ import io.mockk.just import io.mockk.mockkObject import io.mockk.verify import jp.co.soramitsu.androidfoundation.resource.ResourceManager +import jp.co.soramitsu.androidfoundation.testing.MainCoroutineRule +import jp.co.soramitsu.androidfoundation.testing.getOrAwaitValue import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.config.BuildConfigWrapper @@ -71,8 +73,6 @@ import jp.co.soramitsu.sora.substrate.substrate.ConnectionManager import jp.co.soramitsu.test_data.PolkaswapTestData.POOL_DATA import jp.co.soramitsu.test_data.SoraCardTestData.soraCardBasicStatusTest import jp.co.soramitsu.test_data.TestAssets -import jp.co.soramitsu.test_shared.MainCoroutineRule -import jp.co.soramitsu.test_shared.getOrAwaitValue import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5a491e592..4a02fad0c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,13 +39,12 @@ firebaseAppDistribution = "3.2.0" tripletVersion = "3.8.4" timber = "5.0.1" ktor = "2.3.1" -soracard = "1.1.11" -xnetworking = "0.2.9" -xnetworkingS = "1.0.1" -xsubstrate = "1.2.4" +soracard = "1.1.13" +xnetworkingLib = "1.0.4" +xsubstrate = "1.2.7" uicore = "0.2.32" -xbackup = "1.2.1" -xcrypto = "1.2.3" +xbackup = "1.2.2" +xcrypto = "1.2.6" ed = "2.0.1" xerces = "2.9.0" dagger = "2.49" @@ -89,15 +88,16 @@ hiltWorkManagerDep = { module = "androidx.hilt:hilt-work", version.ref = "hiltWo hiltWorkManagerKaptDep = { module = "androidx.hilt:hilt-compiler", version.ref = "hiltWorkManager" } lazySodiumDep = { module = "com.goterl:lazysodium-android", version.ref = "lazySodium" } jnaDep = { module = "net.java.dev.jna:jna", version.ref = "jna" } +ktorLoggingDep = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } +ktorContentNegotiationDep = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktorOkHttpDep = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } ktorWebSocketDep = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" } soraCardDep = { module = "jp.co.soramitsu:android-sora-card", version.ref = "soracard" } -xnetworkingSDep = { module = "jp.co.soramitsu.xnetworking:lib-android", version.ref = "xnetworkingS" } -xnetworkingDep = { module = "jp.co.soramitsu.xnetworking:basic-android", version.ref = "xnetworking" } -xnetworkingSoraWalletDep = { module = "jp.co.soramitsu.xnetworking:sorawallet-android", version.ref = "xnetworking" } +xnetworkingLibDep = { module = "jp.co.soramitsu.xnetworking:lib-android", version.ref = "xnetworkingLib" } xsubstrateDep = { module = "jp.co.soramitsu:xsubstrate", version.ref = "xsubstrate" } uiCoreDep = { module = "jp.co.soramitsu:ui-core", version.ref = "uicore" } xbackupDep = { module = "jp.co.soramitsu:xbackup", version.ref = "xbackup" } -xcryptoDep = { module = "jp.co.soramitsu:x-crypto", version.ref = "xcrypto" } +xcryptoDep = { module = "jp.co.soramitsu:xcrypto", version.ref = "xcrypto" } ed25519Dep = { module = "com.github.warchant:ed25519-sha3-java", version.ref = "ed" } xercesDep = { module = "org.eclipse.birt.runtime.3_7_1:org.apache.xerces", version.ref = "xerces" } timberDep = { module = "com.jakewharton.timber:timber", version.ref = "timber" } diff --git a/network/build.gradle.kts b/network/build.gradle.kts index 6b666caab..07d1afd40 100644 --- a/network/build.gradle.kts +++ b/network/build.gradle.kts @@ -57,9 +57,9 @@ dependencies { implementation(libs.kotlinxSerializationJsonDep) - api(libs.xnetworkingDep) - api(libs.xnetworkingSoraWalletDep) { - exclude(group = "jp.co.soramitsu.xnetworking", module = "basic") - } + api(libs.xnetworkingLibDep) + implementation(libs.ktorOkHttpDep) + implementation(libs.ktorLoggingDep) + implementation(libs.ktorContentNegotiationDep) implementation(libs.ktorWebSocketDep) } diff --git a/network/src/main/java/jp/co/soramitsu/network/WebSocket.kt b/network/src/main/java/jp/co/soramitsu/network/WebSocket.kt index 9ddfad295..7baa4eeaa 100644 --- a/network/src/main/java/jp/co/soramitsu/network/WebSocket.kt +++ b/network/src/main/java/jp/co/soramitsu/network/WebSocket.kt @@ -32,15 +32,23 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.network +import io.ktor.client.HttpClient +import io.ktor.client.engine.okhttp.OkHttp import io.ktor.client.plugins.HttpTimeout +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.plugins.logging.LogLevel +import io.ktor.client.plugins.logging.Logger +import io.ktor.client.plugins.logging.Logging +import io.ktor.client.plugins.logging.SIMPLE import io.ktor.client.plugins.websocket.DefaultClientWebSocketSession +import io.ktor.client.plugins.websocket.WebSockets import io.ktor.client.plugins.websocket.webSocket +import io.ktor.http.ContentType +import io.ktor.serialization.kotlinx.KotlinxWebsocketSerializationConverter +import io.ktor.serialization.kotlinx.json.json import io.ktor.websocket.Frame import io.ktor.websocket.close import io.ktor.websocket.readText -import jp.co.soramitsu.xnetworking.basic.networkclient.NetworkClientConfig -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuHttpClientProvider -import jp.co.soramitsu.xnetworking.basic.networkclient.WebSocketClientConfig import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.launch @@ -63,24 +71,41 @@ class WebSocket( pingInterval: Long = 20, maxFrameSize: Long = Int.MAX_VALUE.toLong(), logging: Boolean = false, - provider: SoramitsuHttpClientProvider, ) { private var socketSession: DefaultClientWebSocketSession? = null - private val networkClient = provider.provide( - NetworkClientConfig( - logging = logging, - requestTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS, - connectTimeoutMillis = connectTimeoutMillis, - socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS, - json = json, - webSocketClientConfig = WebSocketClientConfig( - pingInterval = pingInterval, - maxFrameSize = maxFrameSize - ) - ) - ) + private val networkClient = + HttpClient(OkHttp) { + expectSuccess = true + + if (logging) { + install(Logging) { + level = LogLevel.ALL + logger = Logger.SIMPLE + } + } + + install(ContentNegotiation) { + json( + json = json, + contentType = ContentType.Any + ) + } + + install(HttpTimeout) { + this.requestTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + this.connectTimeoutMillis = connectTimeoutMillis + this.socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + } + + install(WebSockets) { + this.pingInterval = pingInterval + this.maxFrameSize = maxFrameSize + this.contentConverter = + KotlinxWebsocketSerializationConverter(json) + } + } private suspend fun DefaultClientWebSocketSession.listenIncomingMessages() { try { diff --git a/settings.gradle.kts b/settings.gradle.kts index 8df4d0f74..75272dd6a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -74,4 +74,3 @@ include(":feature_wallet_impl") include(":network") include(":sorasubstrate") include(":test_data") -include(":test_shared") diff --git a/sorasubstrate/build.gradle.kts b/sorasubstrate/build.gradle.kts index 0188be39d..371349f53 100644 --- a/sorasubstrate/build.gradle.kts +++ b/sorasubstrate/build.gradle.kts @@ -51,6 +51,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { @@ -63,7 +73,7 @@ dependencies { implementation(libs.xsubstrateDep) implementation(libs.xcryptoDep) - implementation(libs.xnetworkingDep) + implementation(libs.xnetworkingLibDep) implementation(libs.gsonDep) implementation(libs.webSocketLibDep) @@ -72,6 +82,4 @@ dependencies { implementation(libs.timberDep) implementation(libs.daggerDep) kapt(libs.daggerKaptDep) - - testImplementation(project(":test_shared")) } diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/di/SubstrateModule.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/di/SubstrateModule.kt index 2297adbe5..5e31c91d0 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/di/SubstrateModule.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/di/SubstrateModule.kt @@ -44,16 +44,11 @@ import javax.inject.Singleton import jp.co.soramitsu.common.data.network.connection.NetworkStateListener import jp.co.soramitsu.common.domain.AppStateProvider import jp.co.soramitsu.common.domain.CoroutineManager -import jp.co.soramitsu.common.util.Const import jp.co.soramitsu.sora.substrate.substrate.ConnectionManager import jp.co.soramitsu.sora.substrate.substrate.SubstrateApi import jp.co.soramitsu.sora.substrate.substrate.SubstrateApiImpl import jp.co.soramitsu.sora.substrate.substrate.WsConnectionManager import jp.co.soramitsu.sora.substrate.substrate.WsLogger -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuNetworkClient -import jp.co.soramitsu.xnetworking.sorawallet.mainconfig.SoraRemoteConfigBuilder -import jp.co.soramitsu.xnetworking.sorawallet.txhistory.client.SubQueryClientForSoraWallet -import jp.co.soramitsu.xnetworking.sorawallet.txhistory.client.SubQueryClientForSoraWalletFactory import jp.co.soramitsu.xsubstrate.wsrpc.SocketService import jp.co.soramitsu.xsubstrate.wsrpc.logging.Logger import jp.co.soramitsu.xsubstrate.wsrpc.recovery.ConstantReconnectStrategy @@ -72,18 +67,6 @@ class SubstrateModule { @Singleton fun provideWsSocketLogger(): Logger = WsLogger() - @Singleton - @Provides - fun provideSubQueryClient( - client: SoramitsuNetworkClient, - factory: SubQueryClientForSoraWalletFactory, - soraRemoteConfigBuilder: SoraRemoteConfigBuilder, - ): SubQueryClientForSoraWallet = factory.create( - soramitsuNetworkClient = client, - pageSize = Const.HISTORY_PAGE_SIZE, - soraRemoteConfigBuilder = soraRemoteConfigBuilder, - ) - @Provides @Singleton fun provideReconnector(): Reconnector = diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/RuntimeManager.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/RuntimeManager.kt index 298d5aae8..e27325d85 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/RuntimeManager.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/RuntimeManager.kt @@ -41,7 +41,8 @@ import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.io.FileManager import jp.co.soramitsu.common.logger.FirebaseWrapper import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager -import jp.co.soramitsu.xnetworking.basic.networkclient.SoramitsuNetworkClient +import jp.co.soramitsu.xnetworking.lib.engines.rest.api.RestClient +import jp.co.soramitsu.xnetworking.lib.engines.utils.JsonGetRequest import jp.co.soramitsu.xsubstrate.runtime.RuntimeSnapshot import jp.co.soramitsu.xsubstrate.runtime.definitions.TypeDefinitionParser import jp.co.soramitsu.xsubstrate.runtime.definitions.TypeDefinitionsTree @@ -71,6 +72,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext +import kotlinx.serialization.builtins.serializer private const val DEFAULT_TYPES_FILE = "default_types.json" private const val SORA2_TYPES_FILE = "types_scalecodec_mobile.json" @@ -84,7 +86,7 @@ class RuntimeManager @Inject constructor( private val gson: Gson, private val soraPreferences: SoraPreferences, private val socketService: SocketService, - private val networkClient: SoramitsuNetworkClient, + private val restClient: RestClient, private val coroutineManager: CoroutineManager, private val soraConfigManager: SoraConfigManager, ) { @@ -195,7 +197,12 @@ class RuntimeManager @Inject constructor( } is MetadataSource.SoraNet -> { - val sora2Types = networkClient.get(soraConfigManager.getSubstrateTypesUrl()) + val sora2Types = restClient.getReturnString( + JsonGetRequest( + url = soraConfigManager.getSubstrateTypesUrl(), + responseDeserializer = String.serializer() + ) + ) buildTypeRegistry14(sora2Types, runtimeMetadataReader, runtimeVersion).also { saveToCache(SORA2_TYPES_FILE, sora2Types) } diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt index 2d9aacca3..2184a44be 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt @@ -33,8 +33,8 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.sora.substrate.runtime import java.math.BigInteger +import jp.co.soramitsu.androidfoundation.format.addHexPrefix import jp.co.soramitsu.common.data.network.dto.TokenInfoDto -import jp.co.soramitsu.common.util.ext.addHexPrefix import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider.syntheticTokenRegex import jp.co.soramitsu.sora.substrate.substrate.fromHex import jp.co.soramitsu.xcrypto.util.fromHex diff --git a/test_data/build.gradle.kts b/test_data/build.gradle.kts index c10e65e27..816612576 100644 --- a/test_data/build.gradle.kts +++ b/test_data/build.gradle.kts @@ -50,6 +50,16 @@ android { dimension = "default" } } + + packaging { + resources { + excludes += listOf( + "META-INF/DEPENDENCIES", + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + ) + } + } } dependencies { diff --git a/test_shared/.gitignore b/test_shared/.gitignore deleted file mode 100644 index 796b96d1c..000000000 --- a/test_shared/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/test_shared/build.gradle.kts b/test_shared/build.gradle.kts deleted file mode 100644 index a257c31ba..000000000 --- a/test_shared/build.gradle.kts +++ /dev/null @@ -1,67 +0,0 @@ -plugins { - alias(libs.plugins.androidLibrary) - alias(libs.plugins.kotlinAndroid) - alias(libs.plugins.serialization) - alias(libs.plugins.kapt) - id("kotlin-parcelize") -} - -kotlin { - jvmToolchain(11) -} - -android { - namespace = "jp.co.soramitsu.test_shared" - compileSdk = 34 - - defaultConfig { - minSdk = 26 - multiDexEnabled = true - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - - testOptions { - unitTests.isReturnDefaultValues = true - targetSdk = 34 - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - flavorDimensions += listOf("default") - - productFlavors { - create("develop") { - dimension = "default" - } - - create("soralution") { - dimension = "default" - } - - create("production") { - dimension = "default" - } - } -} - -dependencies { - api(libs.coroutineTestDep) - api(libs.xsubstrateDep) - - api(libs.junitDep) - api(libs.mockitoDep) - api(libs.mockitoKotlinDep) - api(libs.archCoreTestDep) - api(libs.archFragmentTestDep) - api(libs.truthDep) - api(libs.mockkDep) - - api(libs.roomTestHelpersDep) -} diff --git a/test_shared/src/main/AndroidManifest.xml b/test_shared/src/main/AndroidManifest.xml deleted file mode 100644 index 94cbbcfc3..000000000 --- a/test_shared/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test_shared/src/main/java/jp/co/soramitsu/test_shared/Ext.kt b/test_shared/src/main/java/jp/co/soramitsu/test_shared/Ext.kt deleted file mode 100644 index 492b6d19b..000000000 --- a/test_shared/src/main/java/jp/co/soramitsu/test_shared/Ext.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* -This file is part of the SORA network and Polkaswap app. - -Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. -SPDX-License-Identifier: BSD-4-Clause - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or other -materials provided with the distribution. - -All advertising materials mentioning features or use of this software must display -the following acknowledgement: This product includes software developed by Polka Biome -Ltd., SORA, and Polkaswap. - -Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used -to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package jp.co.soramitsu.test_shared - -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito - -fun anyNonNull(): T { - Mockito.any() - return initialized() -} - -fun eqNonNull(value: T): T = eq(value) ?: value - -private fun initialized(): T = null as T diff --git a/test_shared/src/main/java/jp/co/soramitsu/test_shared/LiveDataTestUtil.kt b/test_shared/src/main/java/jp/co/soramitsu/test_shared/LiveDataTestUtil.kt deleted file mode 100644 index 4fc690db1..000000000 --- a/test_shared/src/main/java/jp/co/soramitsu/test_shared/LiveDataTestUtil.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* -This file is part of the SORA network and Polkaswap app. - -Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. -SPDX-License-Identifier: BSD-4-Clause - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or other -materials provided with the distribution. - -All advertising materials mentioning features or use of this software must display -the following acknowledgement: This product includes software developed by Polka Biome -Ltd., SORA, and Polkaswap. - -Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used -to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package jp.co.soramitsu.test_shared - -import androidx.annotation.VisibleForTesting -import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer -import java.util.concurrent.CountDownLatch -import java.util.concurrent.TimeUnit -import java.util.concurrent.TimeoutException - -/** - * [https://medium.com/androiddevelopers/unit-testing-livedata-and-other-common-observability-problems-bb477262eb04] - */ -@VisibleForTesting(otherwise = VisibleForTesting.NONE) -fun LiveData.getOrAwaitValue( - time: Long = 2, - timeUnit: TimeUnit = TimeUnit.SECONDS, - afterObserve: () -> Unit = {} -): T { - var data: T? = null - val latch = CountDownLatch(1) - val observer = object : Observer { - override fun onChanged(o: T) { - data = o - latch.countDown() - this@getOrAwaitValue.removeObserver(this) - } - } - this.observeForever(observer) - - try { - afterObserve.invoke() - - // Don't wait indefinitely if the LiveData is not set. - if (!latch.await(time, timeUnit)) { - throw TimeoutException("LiveData value was never set.") - } - } finally { - this.removeObserver(observer) - } - - @Suppress("UNCHECKED_CAST") - return data as T -} - -suspend fun LiveData.observeForTesting(checker: (Int, T) -> Unit, block: suspend () -> Unit) { - var i = 0 - val observer = Observer { - checker(i++, it) - } - try { - observeForever(observer) - block() - } finally { - removeObserver(observer) - } -} diff --git a/test_shared/src/main/java/jp/co/soramitsu/test_shared/TestFlowCollector.kt b/test_shared/src/main/java/jp/co/soramitsu/test_shared/TestFlowCollector.kt deleted file mode 100644 index 549fa6330..000000000 --- a/test_shared/src/main/java/jp/co/soramitsu/test_shared/TestFlowCollector.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* -This file is part of the SORA network and Polkaswap app. - -Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. -SPDX-License-Identifier: BSD-4-Clause - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or other -materials provided with the distribution. - -All advertising materials mentioning features or use of this software must display -the following acknowledgement: This product includes software developed by Polka Biome -Ltd., SORA, and Polkaswap. - -Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used -to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package jp.co.soramitsu.test_shared - -import kotlin.time.Duration.Companion.milliseconds -import kotlin.time.Duration.Companion.seconds -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.TimeoutCancellationException -import kotlinx.coroutines.cancelAndJoin -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher -import kotlinx.coroutines.withTimeout - -/** - * Collect the receiving [Flow] in the given [TestScope], then run assertions on the flow's emissions in the given - * [assertionBlock] by using the available functions in [TestFlowCollector]. Usually, you can simply pass the scope - * given in the [runTest] function. - */ -@OptIn(ExperimentalCoroutinesApi::class) -suspend fun Flow.test( - scope: TestScope, - assertionBlock: suspend TestFlowCollector.() -> Unit = {}, -) { - with(TestFlowCollector(this, scope)) { - assertionBlock() - finishAssertion() - } -} - -@OptIn(ExperimentalCoroutinesApi::class) -class TestFlowCollector(private val flow: Flow, scope: TestScope) { - - private val values = mutableListOf() - - private val job = scope.launch(UnconfinedTestDispatcher(scope.testScheduler)) { - flow.collect { values.add(it) } - } - - suspend fun finishAssertion() { - job.cancelAndJoin() - } - - suspend fun awaitValue(at: Int): T { - return try { - withTimeout(1.seconds) { - while (values.getOrNull(at) == null) { - delay(50.milliseconds) - } - values[at] - } - } catch (e: TimeoutCancellationException) { - throw AssertionError("No value was emitted within 1 second at index $at") - } - } - - suspend fun ensureNoValue(at: Int) { - try { - val value = awaitValue(at) - throw UnexpectedValueException(value, at) - } catch (e: AssertionError) { - if (e is UnexpectedValueException) { - throw e - } - // all good, expected the exception to be thrown - } - } - - private class UnexpectedValueException(value: Any?, at: Int) : - AssertionError("Expected no value to be emitted at index $at but received: $value") -}