mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
Merge branch 'feature/show-dialog-with-mnemonic' into 'develop'
Feature/show dialog with mnemonic See merge request ra3orbladez/anytype.io.mobile!86
This commit is contained in:
commit
8aade7b250
19 changed files with 352 additions and 87 deletions
|
@ -64,6 +64,13 @@ class ComponentManager(private val main: MainComponent) {
|
|||
.build()
|
||||
}
|
||||
|
||||
val keychainPhraseComponent = Component {
|
||||
main
|
||||
.keychainPhraseComponentBuilder()
|
||||
.keychainPhraseModule(KeychainPhraseModule())
|
||||
.build()
|
||||
}
|
||||
|
||||
class Component<T>(private val builder: () -> T) {
|
||||
|
||||
private var instance: T? = null
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.agileburo.anytype.di.feature
|
||||
|
||||
import com.agileburo.anytype.core_utils.di.scope.PerScreen
|
||||
import com.agileburo.anytype.domain.auth.interactor.GetMnemonic
|
||||
import com.agileburo.anytype.domain.auth.repo.AuthRepository
|
||||
import com.agileburo.anytype.presentation.keychain.KeychainPhraseViewModelFactory
|
||||
import com.agileburo.anytype.ui.profile.KeychainPhraseDialog
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.Subcomponent
|
||||
|
||||
|
||||
@Subcomponent(
|
||||
modules = [KeychainPhraseModule::class]
|
||||
)
|
||||
@PerScreen
|
||||
interface KeychainPhraseSubComponent {
|
||||
|
||||
@Subcomponent.Builder
|
||||
interface Builder {
|
||||
fun keychainPhraseModule(module: KeychainPhraseModule): Builder
|
||||
fun build(): KeychainPhraseSubComponent
|
||||
}
|
||||
|
||||
fun inject(fragment: KeychainPhraseDialog)
|
||||
}
|
||||
|
||||
@Module
|
||||
class KeychainPhraseModule {
|
||||
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideKeychainPhraseViewModelFactory(
|
||||
getMnemonic: GetMnemonic
|
||||
) = KeychainPhraseViewModelFactory(
|
||||
getMnemonic = getMnemonic
|
||||
)
|
||||
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideGetMnemonicUseCase(
|
||||
repository: AuthRepository
|
||||
): GetMnemonic = GetMnemonic(
|
||||
repository = repository
|
||||
)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.agileburo.anytype.di.main
|
||||
|
||||
import com.agileburo.anytype.di.feature.AuthSubComponent
|
||||
import com.agileburo.anytype.di.feature.KeychainPhraseSubComponent
|
||||
import com.agileburo.anytype.di.feature.ProfileSubComponent
|
||||
import dagger.Component
|
||||
import javax.inject.Singleton
|
||||
|
@ -15,4 +16,5 @@ import javax.inject.Singleton
|
|||
interface MainComponent {
|
||||
fun authComponentBuilder(): AuthSubComponent.Builder
|
||||
fun profileComponentBuilder(): ProfileSubComponent.Builder
|
||||
fun keychainPhraseComponentBuilder(): KeychainPhraseSubComponent.Builder
|
||||
}
|
|
@ -46,6 +46,10 @@ class Navigator : AppNavigation {
|
|||
// TODO
|
||||
}
|
||||
|
||||
override fun openKeychainScreen() {
|
||||
navController?.navigate(R.id.action_open_keychain)
|
||||
}
|
||||
|
||||
override fun setupSelectedAccount(id: String) {
|
||||
navController?.navigate(
|
||||
R.id.action_setup_selected_account,
|
||||
|
|
|
@ -32,6 +32,7 @@ abstract class NavigationFragment(
|
|||
is Command.ConfirmPinCodeScreen -> navigation.confirmPinCode(command.code)
|
||||
is Command.OpenProfile -> navigation.openProfile()
|
||||
is Command.OpenDocument -> navigation.openDocument(command.id)
|
||||
is Command.OpenKeychainScreen -> navigation.openKeychainScreen()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,36 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.agileburo.anytype.R
|
||||
import com.agileburo.anytype.core_utils.ui.ViewState
|
||||
import com.agileburo.anytype.di.common.componentManager
|
||||
import com.agileburo.anytype.presentation.keychain.KeychainPhraseViewModel
|
||||
import com.agileburo.anytype.presentation.keychain.KeychainPhraseViewModelFactory
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.dialog_keychain_phrase.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeychainPhraseDialog : BottomSheetDialogFragment() {
|
||||
class KeychainPhraseDialog : BottomSheetDialogFragment(), Observer<ViewState<String>> {
|
||||
|
||||
companion object {
|
||||
fun newInstance(): KeychainPhraseDialog = KeychainPhraseDialog()
|
||||
private val vm by lazy {
|
||||
ViewModelProviders
|
||||
.of(this, factory)
|
||||
.get(KeychainPhraseViewModel::class.java)
|
||||
}
|
||||
|
||||
@Inject
|
||||
lateinit var factory: KeychainPhraseViewModelFactory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
injectDependencies()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
releaseDependencies()
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
|
@ -18,4 +41,40 @@ class KeychainPhraseDialog : BottomSheetDialogFragment() {
|
|||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? = inflater.inflate(R.layout.dialog_keychain_phrase, container, false)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
init()
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
vm.state.observe(this, this)
|
||||
}
|
||||
|
||||
override fun onChanged(state: ViewState<String>) {
|
||||
when (state) {
|
||||
is ViewState.Success -> {
|
||||
keychain.text = state.data
|
||||
}
|
||||
is ViewState.Error -> {
|
||||
// TODO
|
||||
}
|
||||
is ViewState.Loading -> {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun init() {
|
||||
doneButton.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
private fun injectDependencies() {
|
||||
componentManager().keychainPhraseComponent.get().inject(this)
|
||||
}
|
||||
|
||||
private fun releaseDependencies() {
|
||||
componentManager().keychainPhraseComponent.release()
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@
|
|||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||
|
||||
<TextView
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/keychain"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -57,7 +58,6 @@
|
|||
android:paddingTop="12dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/keychain_mock"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
@ -11,19 +11,19 @@
|
|||
android:label="StartLoginFragment"
|
||||
tools:layout="@layout/fragment_start_login">
|
||||
<action
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
android:id="@+id/action_open_sign_in"
|
||||
app:destination="@id/keychainLoginScreen" />
|
||||
<action
|
||||
app:destination="@id/keychainLoginScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
<action
|
||||
android:id="@+id/action_open_sign_up"
|
||||
app:destination="@id/createAccountScreen" />
|
||||
app:destination="@id/createAccountScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -32,12 +32,12 @@
|
|||
android:label="StartLoginFragment"
|
||||
tools:layout="@layout/fragment_create_account">
|
||||
<action
|
||||
android:id="@+id/action_setup_new_account"
|
||||
app:destination="@id/setupNewAccountScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
android:id="@+id/action_setup_new_account"
|
||||
app:destination="@id/setupNewAccountScreen" />
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -46,12 +46,12 @@
|
|||
android:label="SetupAccount"
|
||||
tools:layout="@layout/fragment_setup_new_account">
|
||||
<action
|
||||
android:id="@+id/action_open_congratulation_screen"
|
||||
app:destination="@id/congratulationScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
android:id="@+id/action_open_congratulation_screen"
|
||||
app:destination="@id/congratulationScreen" />
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -60,12 +60,12 @@
|
|||
android:label="KeychainLogin"
|
||||
tools:layout="@layout/fragment_keychain_login">
|
||||
<action
|
||||
android:id="@+id/action_select_account"
|
||||
app:destination="@id/selectAccountScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
android:id="@+id/action_select_account"
|
||||
app:destination="@id/selectAccountScreen" />
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -74,12 +74,12 @@
|
|||
android:label="ChooseProfileScreen"
|
||||
tools:layout="@layout/fragment_select_account">
|
||||
<action
|
||||
android:id="@+id/action_setup_selected_account"
|
||||
app:destination="@id/setupSelectedAccountScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
android:id="@+id/action_setup_selected_account"
|
||||
app:destination="@id/setupSelectedAccountScreen" />
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -88,20 +88,20 @@
|
|||
android:label="SetupAccount"
|
||||
tools:layout="@layout/fragment_setup_selected_account">
|
||||
<action
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
android:id="@+id/action_open_congratulation_screen"
|
||||
app:destination="@id/congratulationScreen" />
|
||||
<argument
|
||||
app:destination="@id/congratulationScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
<argument
|
||||
android:name="selected_account_id"
|
||||
android:defaultValue="0"
|
||||
app:argType="integer" />
|
||||
app:argType="integer"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -132,12 +132,12 @@
|
|||
android:label="DesktopFragment"
|
||||
tools:layout="@layout/fragment_desktop">
|
||||
<action
|
||||
android:id="@+id/action_open_profile"
|
||||
app:destination="@id/profileScreen"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
android:id="@+id/action_open_profile"
|
||||
app:destination="@id/profileScreen" />
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -150,6 +150,14 @@
|
|||
app:destination="@id/startLoginScreen"
|
||||
app:enterAnim="@anim/fade_in"
|
||||
app:exitAnim="@anim/fade_out" />
|
||||
<action
|
||||
android:id="@+id/action_open_keychain"
|
||||
app:destination="@id/keychainDialog" />
|
||||
</fragment>
|
||||
|
||||
<dialog
|
||||
android:id="@+id/keychainDialog"
|
||||
android:name="com.agileburo.anytype.ui.profile.KeychainPhraseDialog"
|
||||
tools:layout="@layout/dialog_keychain_phrase" />
|
||||
|
||||
</navigation>
|
|
@ -23,7 +23,7 @@ buildscript {
|
|||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.4.2'
|
||||
classpath 'com.android.tools.build:gradle:3.5.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.google.gms:google-services:4.3.2'
|
||||
classpath 'io.fabric.tools:gradle:1.31.1'
|
||||
|
|
|
@ -19,7 +19,7 @@ ext {
|
|||
|
||||
// Architecture Components
|
||||
lifecycle_version = '2.1.0'
|
||||
navigation_version = '1.0.0-beta02'
|
||||
navigation_version = '2.1.0'
|
||||
|
||||
// Third party libraries
|
||||
glide_version = '4.9.0'
|
||||
|
@ -39,6 +39,9 @@ ext {
|
|||
junit_version = '4.12'
|
||||
mockito_version = '1.4.0'
|
||||
kluent_version = '1.14'
|
||||
coroutine_testing_version = '1.3.2'
|
||||
live_data_testing_version = '1.1.0'
|
||||
mockito_kotlin_version = '2.2.0'
|
||||
|
||||
// Acceptance Testing
|
||||
runner_version = '1.1.0'
|
||||
|
@ -68,8 +71,8 @@ ext {
|
|||
kotlin: "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",
|
||||
coroutines: "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version",
|
||||
androidxCore: "androidx.core:core-ktx:$androidx_core_version",
|
||||
navigation: "android.arch.navigation:navigation-fragment-ktx:$navigation_version",
|
||||
navigationUi: "android.arch.navigation:navigation-ui-ktx:$navigation_version",
|
||||
navigation: "androidx.navigation:navigation-fragment-ktx:$navigation_version",
|
||||
navigationUi: "androidx.navigation:navigation-ui-ktx:$navigation_version",
|
||||
viewModel: "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version",
|
||||
viewModelExtensions: "androidx.lifecycle:lifecycle-extensions:$lifecycle_version",
|
||||
lifecycleCompiler: "androidx.lifecycle:lifecycle-compiler:$lifecycle_version",
|
||||
|
@ -106,7 +109,11 @@ ext {
|
|||
robolectric: "org.robolectric:robolectric:$robolectric_version",
|
||||
junit: "junit:junit:$junit_version",
|
||||
mockito: "com.nhaarman:mockito-kotlin:$mockito_version",
|
||||
mockitoKotlin: "com.nhaarman.mockitokotlin2:mockito-kotlin:$mockito_kotlin_version",
|
||||
kluent: "org.amshove.kluent:kluent:$kluent_version",
|
||||
archCoreTesting: "androidx.arch.core:core-testing:$lifecycle_version",
|
||||
liveDataTesting: "com.jraska.livedata:testing-ktx:$live_data_testing_version",
|
||||
coroutineTesting: "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutine_testing_version"
|
||||
]
|
||||
|
||||
acceptanceTesting = [
|
||||
|
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
|||
#Fri Apr 19 19:39:37 MSK 2019
|
||||
#Tue Oct 22 17:14:40 MSK 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
|
|
|
@ -34,8 +34,8 @@ dependencies {
|
|||
|
||||
testImplementation unitTestDependencies.junit
|
||||
testImplementation unitTestDependencies.kotlinTest
|
||||
//testImplementation unitTestDependencies.mockito
|
||||
|
||||
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2'
|
||||
testImplementation unitTestDependencies.mockitoKotlin
|
||||
testImplementation unitTestDependencies.coroutineTesting
|
||||
testImplementation unitTestDependencies.liveDataTesting
|
||||
testImplementation unitTestDependencies.archCoreTesting
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package com.agileburo.anytype.presentation;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
assertEquals("com.agileburo.anytype.presentation.test", appContext.getPackageName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.agileburo.anytype.presentation.keychain
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.agileburo.anytype.core_utils.ui.ViewState
|
||||
import com.agileburo.anytype.core_utils.ui.ViewStateViewModel
|
||||
import com.agileburo.anytype.domain.auth.interactor.GetMnemonic
|
||||
import timber.log.Timber
|
||||
|
||||
class KeychainPhraseViewModel(
|
||||
private val getMnemonic: GetMnemonic
|
||||
) : ViewStateViewModel<ViewState<String>>() {
|
||||
|
||||
init {
|
||||
proceedWithGettingMnemonic()
|
||||
}
|
||||
|
||||
private fun proceedWithGettingMnemonic() {
|
||||
getMnemonic.invoke(viewModelScope, Unit) { result ->
|
||||
result.either(
|
||||
fnL = { e -> Timber.e(e, "Error while getting mnemonic") },
|
||||
fnR = { stateData.postValue(ViewState.Success(it)) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KeychainPhraseViewModelFactory(
|
||||
private val getMnemonic: GetMnemonic
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return KeychainPhraseViewModel(
|
||||
getMnemonic = getMnemonic
|
||||
) as T
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ interface AppNavigation {
|
|||
fun workspace()
|
||||
fun openProfile()
|
||||
fun openDocument(id: String)
|
||||
fun openKeychainScreen()
|
||||
|
||||
sealed class Command {
|
||||
object OpenStartLoginScreen : Command()
|
||||
|
|
62
presentation/src/test/java/MockDataFactory.kt
Normal file
62
presentation/src/test/java/MockDataFactory.kt
Normal file
|
@ -0,0 +1,62 @@
|
|||
import java.util.*
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
|
||||
object MockDataFactory {
|
||||
|
||||
fun randomUuid(): String {
|
||||
return UUID.randomUUID().toString()
|
||||
}
|
||||
|
||||
fun randomString(): String {
|
||||
return randomUuid()
|
||||
}
|
||||
|
||||
|
||||
fun randomInt(): Int {
|
||||
return ThreadLocalRandom.current().nextInt(0, 1000 + 1)
|
||||
}
|
||||
|
||||
fun randomInt(max: Int): Int {
|
||||
return ThreadLocalRandom.current().nextInt(0, max)
|
||||
}
|
||||
|
||||
fun randomLong(): Long {
|
||||
return randomInt().toLong()
|
||||
}
|
||||
|
||||
fun randomFloat(): Float {
|
||||
return randomInt().toFloat()
|
||||
}
|
||||
|
||||
fun randomDouble(): Double {
|
||||
return randomInt().toDouble()
|
||||
}
|
||||
|
||||
fun randomBoolean(): Boolean {
|
||||
return Math.random() < 0.5
|
||||
}
|
||||
|
||||
fun makeIntList(count: Int): List<Int> {
|
||||
val items = mutableListOf<Int>()
|
||||
repeat(count) {
|
||||
items.add(randomInt())
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
fun makeStringList(count: Int): List<String> {
|
||||
val items = mutableListOf<String>()
|
||||
repeat(count) {
|
||||
items.add(randomUuid())
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
fun makeDoubleList(count: Int): List<Double> {
|
||||
val items = mutableListOf<Double>()
|
||||
repeat(count) {
|
||||
items.add(randomDouble())
|
||||
}
|
||||
return items
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package com.agileburo.anytype.presentation;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.agileburo.anytype.presentation.keychain
|
||||
|
||||
import MockDataFactory
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.agileburo.anytype.core_utils.ui.ViewState
|
||||
import com.agileburo.anytype.domain.auth.interactor.GetMnemonic
|
||||
import com.agileburo.anytype.domain.base.Either
|
||||
import com.jraska.livedata.test
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
|
||||
class KeychainPhraseViewModelTest {
|
||||
|
||||
@get:Rule
|
||||
val rule = InstantTaskExecutorRule()
|
||||
|
||||
@Mock
|
||||
lateinit var getMnemonic: GetMnemonic
|
||||
|
||||
lateinit var vm: KeychainPhraseViewModel
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should proceed with getting mnemonic when vm is created`() {
|
||||
vm = buildViewModel()
|
||||
verify(getMnemonic, times(1)).invoke(any(), any(), any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit mnemonic when it is received`() {
|
||||
|
||||
val mnemonic = MockDataFactory.randomString()
|
||||
|
||||
getMnemonic.stub {
|
||||
on { invoke(any(), any(), any()) } doAnswer { answer ->
|
||||
answer.getArgument<(Either<Throwable, String>) -> Unit>(2)(Either.Right(mnemonic))
|
||||
}
|
||||
}
|
||||
|
||||
vm = buildViewModel()
|
||||
|
||||
vm.state.test().assertValue(ViewState.Success(mnemonic))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit nothing when error occurs`() {
|
||||
|
||||
val exception = Exception()
|
||||
|
||||
getMnemonic.stub {
|
||||
on { invoke(any(), any(), any()) } doAnswer { answer ->
|
||||
answer.getArgument<(Either<Throwable, String>) -> Unit>(2)(Either.Left(exception))
|
||||
}
|
||||
}
|
||||
|
||||
vm = buildViewModel()
|
||||
|
||||
vm.state.test().assertNoValue()
|
||||
}
|
||||
|
||||
private fun buildViewModel() = KeychainPhraseViewModel(getMnemonic = getMnemonic)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
mock-maker-inline
|
Loading…
Add table
Add a link
Reference in a new issue