mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-04-22 02:07:58 +00:00
Initial commit: Pezkuwi Wallet Android
Security hardened release: - Code obfuscation enabled (minifyEnabled=true, shrinkResources=true) - Sensitive files excluded (google-services.json, keystores) - Branch.io key moved to BuildConfig placeholder - Updated dependencies: OkHttp 4.12.0, Gson 2.10.1, BouncyCastle 1.77 - Comprehensive ProGuard rules for crypto wallet - Navigation 2.7.7, Lifecycle 2.7.0, ConstraintLayout 2.1.4
This commit is contained in:
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
android {
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
namespace 'io.novafoundation.nova.test_shared'
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation kotlinDep
|
||||
|
||||
implementation project(':common')
|
||||
|
||||
api jUnitDep
|
||||
api mockitoDep
|
||||
|
||||
api wsDep
|
||||
|
||||
api gsonDep
|
||||
api substrateSdkDep
|
||||
|
||||
api coroutinesTestDep
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<manifest />
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.novafoundation.nova.test_shared
|
||||
|
||||
import io.novasama.substrate_sdk_android.extensions.toHexString
|
||||
import org.junit.Assert.assertEquals
|
||||
|
||||
fun <T> assertListEquals(expected: List<T>, actual: List<T>, compare: (T, T) -> Boolean = { a, b -> a == b }) {
|
||||
if (expected.size != actual.size) {
|
||||
throw AssertionError("Lists are not equal. Expected: $expected, actual: $actual")
|
||||
}
|
||||
for (i in expected.indices) {
|
||||
if (!compare(expected[i], actual[i])) {
|
||||
throw AssertionError("Lists are not equal. Expected: $expected, actual: $actual")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun assertHexEquals(expected: ByteArray, actual: ByteArray) {
|
||||
assertEquals(expected.toHexString(), actual.toHexString())
|
||||
}
|
||||
|
||||
fun <T> assertSetEquals(expected: Set<T>, actual: Set<T>) {
|
||||
if (expected != actual) {
|
||||
throw AssertionError("Sets are not equal. Expected: $expected, actual: $actual")
|
||||
}
|
||||
}
|
||||
|
||||
fun <K, V> assertMapEquals(expected: Map<K, V>, actual: Map<K, V>) {
|
||||
if (expected != actual) {
|
||||
throw AssertionError("Maps are not equal. Expected: $expected, actual: $actual")
|
||||
}
|
||||
}
|
||||
|
||||
fun <V> assertAllItemsEquals(items: List<V>) {
|
||||
items.forEach {
|
||||
if (it != items[0]) {
|
||||
throw AssertionError("Items in list are not equal:\n$it\n${items[0]}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.test_shared
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||
import kotlinx.coroutines.test.TestCoroutineScope
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
abstract class CoroutineTest {
|
||||
|
||||
private val testDispatcher = TestCoroutineDispatcher()
|
||||
private val testScope = TestCoroutineScope(testDispatcher)
|
||||
|
||||
fun runCoroutineTest(test: suspend CoroutineScope.() -> Unit) = testScope.runBlockingTest {
|
||||
test(testScope)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.novafoundation.nova.test_shared
|
||||
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
|
||||
fun <T> removesElement(elementCheck: (T) -> Boolean) = argThat<CollectionDiffer.Diff<T>> {
|
||||
it.newOrUpdated.isEmpty() && elementCheck(it.removed.single())
|
||||
}
|
||||
|
||||
fun <T> insertsElement(elementCheck: (T) -> Boolean) = argThat<CollectionDiffer.Diff<T>> {
|
||||
it.removed.isEmpty() && elementCheck(it.newOrUpdated.single())
|
||||
}
|
||||
|
||||
fun <T> emptyDiff() = argThat<CollectionDiffer.Diff<T>> {
|
||||
it.newOrUpdated.isEmpty() && it.removed.isEmpty()
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.test_shared
|
||||
|
||||
import io.novafoundation.nova.common.data.storage.encrypt.EncryptedPreferences
|
||||
|
||||
class HashMapEncryptedPreferences : EncryptedPreferences {
|
||||
private val delegate = mutableMapOf<String, String>()
|
||||
|
||||
override fun putEncryptedString(field: String, value: String) {
|
||||
delegate[field] = value
|
||||
}
|
||||
|
||||
override fun getDecryptedString(field: String): String? = delegate[field]
|
||||
|
||||
override fun hasKey(field: String): Boolean = field in delegate
|
||||
|
||||
override fun removeKey(field: String) {
|
||||
delegate.remove(field)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.novafoundation.nova.test_shared
|
||||
|
||||
import io.novasama.substrate_sdk_android.wsrpc.logging.Logger
|
||||
|
||||
object StdoutLogger : Logger {
|
||||
override fun log(message: String?) {
|
||||
println(message)
|
||||
}
|
||||
|
||||
override fun log(throwable: Throwable?) {
|
||||
throwable?.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
object NoOpLogger : Logger {
|
||||
override fun log(message: String?) {
|
||||
// pass
|
||||
}
|
||||
|
||||
override fun log(throwable: Throwable?) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.novafoundation.nova.test_shared
|
||||
|
||||
import org.mockito.ArgumentMatcher
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.stubbing.OngoingStubbing
|
||||
|
||||
/**
|
||||
* Returns Mockito.eq() as nullable type to avoid java.lang.IllegalStateException when
|
||||
* null is returned.
|
||||
*
|
||||
* Generic T is nullable because implicitly bounded by Any?.
|
||||
*/
|
||||
fun <T> eq(obj: T): T = Mockito.eq<T>(obj)
|
||||
|
||||
/**
|
||||
* Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when
|
||||
* null is returned.
|
||||
*/
|
||||
fun <T> any(): T = Mockito.any<T>()
|
||||
|
||||
/**
|
||||
* Returns Mockito.isA() as nullable type to avoid java.lang.IllegalStateException when
|
||||
* null is returned.
|
||||
*/
|
||||
fun <T> isA(classRef: Class<T>): T = Mockito.isA<T>(classRef)
|
||||
|
||||
fun <T> argThat(argumentMatcher: ArgumentMatcher<T>): T = Mockito.argThat<T>(argumentMatcher)
|
||||
|
||||
fun <T> whenever(methodCall: T): OngoingStubbing<T> =
|
||||
Mockito.`when`(methodCall)
|
||||
|
||||
fun <T> OngoingStubbing<T>.thenThrowUnsafe(exception: Exception) = thenAnswer {
|
||||
throw exception
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package io.novafoundation.nova.test_shared
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.neovisionaries.ws.client.WebSocketFactory
|
||||
import io.novasama.substrate_sdk_android.wsrpc.SocketService
|
||||
import io.novasama.substrate_sdk_android.wsrpc.recovery.Reconnector
|
||||
import io.novasama.substrate_sdk_android.wsrpc.request.RequestExecutor
|
||||
|
||||
fun createTestSocket() = SocketService(Gson(), NoOpLogger, WebSocketFactory(), Reconnector(), RequestExecutor())
|
||||
Reference in New Issue
Block a user