1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 01:49:09 -05:00

Fix crash on restore LoginActivity (#182)

This commit is contained in:
Rafał Borcz 2018-11-11 23:24:49 +01:00 committed by Mikołaj Pich
parent cb7e70471b
commit 24f59b45c3
15 changed files with 151 additions and 133 deletions

View File

@ -164,7 +164,6 @@
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" /> <option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" /> <option name="EXTENDS_LIST_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" /> <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<indentOptions> <indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions> </indentOptions>

View File

@ -61,8 +61,4 @@ class SessionRepository @Inject constructor(
}) })
} }
} }
fun clearCache() {
cachedStudents = Single.just(emptyList())
}
} }

View File

@ -12,7 +12,7 @@ import io.github.wulkanowy.utils.setOnSelectPageListener
import kotlinx.android.synthetic.main.activity_login.* import kotlinx.android.synthetic.main.activity_login.*
import javax.inject.Inject import javax.inject.Inject
class LoginActivity : BaseActivity(), LoginView, LoginSwitchListener { class LoginActivity : BaseActivity(), LoginView {
@Inject @Inject
lateinit var presenter: LoginPresenter lateinit var presenter: LoginPresenter
@ -35,35 +35,36 @@ class LoginActivity : BaseActivity(), LoginView, LoginSwitchListener {
presenter.onAttachView(this) presenter.onAttachView(this)
} }
override fun onBackPressed() {
presenter.onBackPressed { super.onBackPressed() }
}
override fun initAdapter() { override fun initAdapter() {
loginAdapter.fragments.putAll(mapOf( loginAdapter.fragments.putAll(mapOf(
"1" to LoginFormFragment.newInstance(), "1" to LoginFormFragment.newInstance(),
"2" to LoginOptionsFragment.newInstance() "2" to LoginOptionsFragment.newInstance()
)) ))
loginViewpager.run { loginViewpager.run {
adapter = loginAdapter adapter = loginAdapter
setOnSelectPageListener { presenter.onPageSelected(it) } setOnSelectPageListener { presenter.onPageSelected(it) }
} }
} }
override fun switchFragment(position: Int) { override fun switchView(index: Int) {
presenter.onSwitchFragment(position) loginViewpager.setCurrentItem(index, false)
} }
override fun switchView(position: Int) { override fun notifyOptionsViewLoadData() {
loginViewpager.setCurrentItem(position, false) (supportFragmentManager.fragments[1] as? LoginOptionsFragment)?.onParentLoadData()
}
fun onChildFragmentSwitchOptions() {
presenter.onChildViewSwitchOptions()
} }
override fun hideActionBar() { override fun hideActionBar() {
supportActionBar?.hide() supportActionBar?.hide()
} }
override fun loadOptionsView(index: Int) { override fun onBackPressed() {
(loginAdapter.getItem(index) as LoginOptionsFragment).loadData() presenter.onBackPressed { super.onBackPressed() }
} }
public override fun onDestroy() { public override fun onDestroy() {

View File

@ -4,8 +4,7 @@ import io.github.wulkanowy.data.ErrorHandler
import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.BasePresenter
import javax.inject.Inject import javax.inject.Inject
class LoginPresenter @Inject constructor(errorHandler: ErrorHandler) class LoginPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePresenter<LoginView>(errorHandler) {
: BasePresenter<LoginView>(errorHandler) {
override fun onAttachView(view: LoginView) { override fun onAttachView(view: LoginView) {
super.onAttachView(view) super.onAttachView(view)
@ -16,11 +15,11 @@ class LoginPresenter @Inject constructor(errorHandler: ErrorHandler)
} }
fun onPageSelected(index: Int) { fun onPageSelected(index: Int) {
if (index == 1) view?.loadOptionsView(index) if (index == 1) view?.notifyOptionsViewLoadData()
} }
fun onSwitchFragment(position: Int) { fun onChildViewSwitchOptions() {
view?.switchView(position) view?.switchView(1)
} }
fun onBackPressed(default: () -> Unit) { fun onBackPressed(default: () -> Unit) {

View File

@ -1,6 +0,0 @@
package io.github.wulkanowy.ui.modules.login
interface LoginSwitchListener {
fun switchFragment(position: Int)
}

View File

@ -8,9 +8,9 @@ interface LoginView : BaseView {
fun initAdapter() fun initAdapter()
fun loadOptionsView(index: Int)
fun switchView(position: Int)
fun hideActionBar() fun hideActionBar()
fun switchView(index: Int)
fun notifyOptionsViewLoadData()
} }

View File

@ -6,11 +6,12 @@ import android.view.View
import android.view.View.GONE import android.view.View.GONE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
import android.view.inputmethod.EditorInfo.IME_NULL
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginSwitchListener import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.hideSoftInput import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.showSoftInput import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.fragment_login_form.* import kotlinx.android.synthetic.main.fragment_login_form.*
@ -34,7 +35,7 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
presenter.onAttachView(this) presenter.onAttachView(this)
} }
override fun initInputs() { override fun initView() {
loginSignButton.setOnClickListener { loginSignButton.setOnClickListener {
presenter.attemptLogin( presenter.attemptLogin(
loginNicknameEdit.text.toString(), loginNicknameEdit.text.toString(),
@ -46,10 +47,9 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
loginPassEdit.setOnEditorActionListener { _, id, _ -> onEditAction(id) } loginPassEdit.setOnEditorActionListener { _, id, _ -> onEditAction(id) }
loginHostEdit.run { loginHostEdit.apply {
adapter = ArrayAdapter.createFromResource(context, R.array.endpoints_keys, android.R.layout.simple_spinner_item).apply { adapter = ArrayAdapter.createFromResource(context, R.array.endpoints_keys, android.R.layout.simple_spinner_item)
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) .apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) }
}
} }
loginSymbolEdit.run { loginSymbolEdit.run {
@ -58,13 +58,6 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
} }
} }
private fun onEditAction(actionId: Int): Boolean {
return when (actionId) {
EditorInfo.IME_ACTION_DONE, EditorInfo.IME_NULL -> loginSignButton.callOnClick()
else -> false
}
}
override fun showSymbolInput() { override fun showSymbolInput() {
loginHeader.text = getString(R.string.login_header_symbol) loginHeader.text = getString(R.string.login_header_symbol)
loginMainForm.visibility = GONE loginMainForm.visibility = GONE
@ -73,8 +66,8 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
showSoftKeyboard() showSoftKeyboard()
} }
override fun switchNextView() { override fun switchOptionsView() {
(activity as LoginSwitchListener?)?.switchFragment(1) (activity as? LoginActivity)?.onChildFragmentSwitchOptions()
} }
override fun setErrorNicknameRequired() { override fun setErrorNicknameRequired() {
@ -132,11 +125,21 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
activity?.hideSoftInput() activity?.hideSoftInput()
} }
override fun showLoginProgress(show: Boolean) { override fun showProgress(show: Boolean) {
loginFormContainer.visibility = if (show) GONE else VISIBLE
loginFormProgressContainer.visibility = if (show) VISIBLE else GONE loginFormProgressContainer.visibility = if (show) VISIBLE else GONE
} }
override fun showContent(show: Boolean) {
loginFormContainer.visibility = if (show) VISIBLE else GONE
}
private fun onEditAction(actionId: Int): Boolean {
return when (actionId) {
IME_ACTION_DONE, IME_NULL -> loginSignButton.callOnClick()
else -> false
}
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
presenter.onDetachView() presenter.onDetachView()

View File

@ -19,27 +19,35 @@ class LoginFormPresenter @Inject constructor(
override fun onAttachView(view: LoginFormView) { override fun onAttachView(view: LoginFormView) {
super.onAttachView(view) super.onAttachView(view)
view.initInputs() view.run {
} initView()
fun attemptLogin(email: String, password: String, symbol: String, endpoint: String) {
if (!validateCredentials(email, password, symbol)) return
disposable.add(sessionRepository.getConnectedStudents(email, password, symbol, endpoint)
.observeOn(schedulers.mainThread)
.subscribeOn(schedulers.backgroundThread)
.doOnSubscribe {
view?.run {
hideSoftKeyboard()
showLoginProgress(true)
errorHandler.doOnBadCredentials = { errorHandler.doOnBadCredentials = {
setErrorPassIncorrect() setErrorPassIncorrect()
showSoftKeyboard() showSoftKeyboard()
Timber.i("Entered wrong username or password") Timber.i("Entered wrong username or password")
} }
} }
sessionRepository.clearCache()
} }
.doFinally { view?.showLoginProgress(false) }
fun attemptLogin(email: String, password: String, symbol: String, endpoint: String) {
if (!validateCredentials(email, password, symbol)) return
disposable.add(sessionRepository.getConnectedStudents(email, password, symbol, endpoint)
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.doOnSubscribe {
view?.apply {
hideSoftKeyboard()
showProgress(true)
showContent(false)
}
}
.doFinally {
view?.apply {
showProgress(false)
showContent(true)
}
}
.subscribe({ .subscribe({
view?.run { view?.run {
if (it.isEmpty() && !wasEmpty) { if (it.isEmpty() && !wasEmpty) {
@ -50,7 +58,7 @@ class LoginFormPresenter @Inject constructor(
setErrorSymbolIncorrect() setErrorSymbolIncorrect()
logRegister("No student found", false, if (symbol.isEmpty()) "nil" else symbol, endpoint) logRegister("No student found", false, if (symbol.isEmpty()) "nil" else symbol, endpoint)
} else { } else {
switchNextView() switchOptionsView()
logEvent("Found students", mapOf("students" to it.size, "symbol" to it.joinToString { student -> student.symbol }, "endpoint" to endpoint)) logEvent("Found students", mapOf("students" to it.size, "symbol" to it.joinToString { student -> student.symbol }, "endpoint" to endpoint))
} }
} }

View File

@ -4,7 +4,9 @@ import io.github.wulkanowy.ui.base.BaseView
interface LoginFormView : BaseView { interface LoginFormView : BaseView {
fun initInputs() fun initView()
fun switchOptionsView()
fun setErrorNicknameRequired() fun setErrorNicknameRequired()
@ -24,9 +26,9 @@ interface LoginFormView : BaseView {
fun hideSoftKeyboard() fun hideSoftKeyboard()
fun showLoginProgress(show: Boolean) fun showProgress(show: Boolean)
fun showContent(show: Boolean)
fun showSymbolInput() fun showSymbolInput()
fun switchNextView()
} }

View File

@ -38,28 +38,21 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
presenter.onAttachView(this) presenter.onAttachView(this)
} }
override fun initRecycler() { override fun initView() {
loginAdapter.run { loginAdapter.apply { setOnItemClickListener { presenter.onSelectItem(getItem(it)) } }
setOnItemClickListener { position ->
(getItem(position) as? LoginOptionsItem)?.let { loginOptionsRecycler.apply {
presenter.onSelectStudent(it.student)
}
}
}
loginOptionsRecycler.run {
adapter = loginAdapter adapter = loginAdapter
layoutManager = SmoothScrollLinearLayoutManager(context) layoutManager = SmoothScrollLinearLayoutManager(context)
} }
} }
fun loadData() { fun onParentLoadData() {
presenter.refreshData() presenter.onParentViewLoadData()
} }
override fun updateData(data: List<LoginOptionsItem>) { override fun updateData(data: List<LoginOptionsItem>) {
loginAdapter.run { loginAdapter.updateDataSet(data, true)
updateDataSet(data, true)
}
} }
override fun openMainView() { override fun openMainView() {
@ -69,17 +62,20 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
} }
} }
override fun showLoginProgress(show: Boolean) { override fun showProgress(show: Boolean) {
loginOptionsProgressContainer.visibility = if (show) VISIBLE else GONE loginOptionsProgressContainer.visibility = if (show) VISIBLE else GONE
loginOptionsRecycler.visibility = if (show) GONE else VISIBLE }
override fun showContent(show: Boolean) {
loginOptionsRecycler.visibility = if (show) VISIBLE else GONE
} }
override fun showActionBar(show: Boolean) { override fun showActionBar(show: Boolean) {
(activity as AppCompatActivity?)?.supportActionBar?.run { if (show) show() else hide() } (activity as? AppCompatActivity)?.supportActionBar?.run { if (show) show() else hide() }
} }
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView() presenter.onDetachView()
super.onDestroyView()
} }
} }

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.login.options package io.github.wulkanowy.ui.modules.login.options
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import io.github.wulkanowy.data.ErrorHandler import io.github.wulkanowy.data.ErrorHandler
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.SessionRepository import io.github.wulkanowy.data.repositories.SessionRepository
@ -16,29 +17,31 @@ class LoginOptionsPresenter @Inject constructor(
override fun onAttachView(view: LoginOptionsView) { override fun onAttachView(view: LoginOptionsView) {
super.onAttachView(view) super.onAttachView(view)
view.initRecycler() view.initView()
} }
fun refreshData() { fun onParentViewLoadData() {
disposable.add(repository.cachedStudents disposable.add(repository.cachedStudents
.observeOn(schedulers.mainThread) .observeOn(schedulers.mainThread)
.subscribeOn(schedulers.backgroundThread) .subscribeOn(schedulers.backgroundThread)
.doOnSubscribe { view?.showActionBar(true) } .doOnSubscribe { view?.showActionBar(true) }
.doFinally { repository.clearCache() } .subscribe({ view?.updateData(it.map { student -> LoginOptionsItem(student) }) }, { errorHandler.proceed(it) }))
.subscribe({
view?.updateData(it.map { student ->
LoginOptionsItem(student)
})
}, { errorHandler.proceed(it) }))
} }
fun onSelectStudent(student: Student) { fun onSelectItem(item: AbstractFlexibleItem<*>?) {
if (item is LoginOptionsItem) {
registerStudent(item.student)
}
}
private fun registerStudent(student: Student) {
disposable.add(repository.saveStudent(student) disposable.add(repository.saveStudent(student)
.subscribeOn(schedulers.backgroundThread) .subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread) .observeOn(schedulers.mainThread)
.doOnSubscribe { .doOnSubscribe {
view?.run { view?.run {
showLoginProgress(true) showProgress(true)
showContent(false)
showActionBar(false) showActionBar(false)
} }
} }

View File

@ -4,13 +4,15 @@ import io.github.wulkanowy.ui.base.BaseView
interface LoginOptionsView : BaseView { interface LoginOptionsView : BaseView {
fun updateData(data: List<LoginOptionsItem>) fun initView()
fun initRecycler() fun updateData(data: List<LoginOptionsItem>)
fun openMainView() fun openMainView()
fun showLoginProgress(show: Boolean) fun showProgress(show: Boolean)
fun showContent(show: Boolean)
fun showActionBar(show: Boolean) fun showActionBar(show: Boolean)
} }

View File

@ -4,7 +4,10 @@ import org.junit.Assert.assertNotEquals
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.* import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
class LoginPresenterTest { class LoginPresenterTest {
@ -35,16 +38,19 @@ class LoginPresenterTest {
@Test @Test
fun onPageSelectedTest() { fun onPageSelectedTest() {
presenter.onPageSelected(1) presenter.onPageSelected(1)
verify(loginView).loadOptionsView(1) verify(loginView).notifyOptionsViewLoadData()
}
@Test
fun onPageSelectedNeverTest() {
presenter.onPageSelected(0) presenter.onPageSelected(0)
verify(loginView, never()).loadOptionsView(0) verify(loginView, never()).notifyOptionsViewLoadData()
} }
@Test @Test
fun onSwitchFragmentTest() { fun onSwitchFragmentTest() {
presenter.onSwitchFragment(4) presenter.onChildViewSwitchOptions()
verify(loginView).switchView(4) verify(loginView).switchView(1)
} }
@Test @Test

View File

@ -9,7 +9,11 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.ArgumentMatchers.anyString import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.* import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
class LoginFormPresenterTest { class LoginFormPresenterTest {
@ -35,7 +39,7 @@ class LoginFormPresenterTest {
@Test @Test
fun initViewTest() { fun initViewTest() {
verify(loginFormView).initInputs() verify(loginFormView).initView()
} }
@Test @Test
@ -86,10 +90,11 @@ class LoginFormPresenterTest {
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
verify(loginFormView).hideSoftKeyboard() verify(loginFormView).hideSoftKeyboard()
verify(loginFormView).showLoginProgress(true) verify(loginFormView).showProgress(true)
verify(repository).clearCache() verify(loginFormView).showProgress(false)
verify(loginFormView).showLoginProgress(false) verify(loginFormView).showContent(false)
verify(loginFormView).switchNextView() verify(loginFormView).showContent(true)
verify(loginFormView).switchOptionsView()
} }
@Test @Test
@ -99,9 +104,10 @@ class LoginFormPresenterTest {
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
verify(loginFormView).hideSoftKeyboard() verify(loginFormView).hideSoftKeyboard()
verify(loginFormView).showLoginProgress(true) verify(loginFormView).showProgress(true)
verify(repository).clearCache() verify(loginFormView).showProgress(false)
verify(loginFormView).showLoginProgress(false) verify(loginFormView).showContent(false)
verify(loginFormView).showContent(true)
verify(loginFormView).showSymbolInput() verify(loginFormView).showSymbolInput()
} }
@ -113,9 +119,10 @@ class LoginFormPresenterTest {
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
verify(loginFormView, times(2)).hideSoftKeyboard() verify(loginFormView, times(2)).hideSoftKeyboard()
verify(loginFormView, times(2)).showLoginProgress(true) verify(loginFormView, times(2)).showProgress(true)
verify(repository, times(2)).clearCache() verify(loginFormView, times(2)).showProgress(false)
verify(loginFormView, times(2)).showLoginProgress(false) verify(loginFormView, times(2)).showContent(false)
verify(loginFormView, times(2)).showContent(true)
verify(loginFormView, times(2)).showSymbolInput() verify(loginFormView, times(2)).showSymbolInput()
verify(loginFormView).setErrorSymbolIncorrect() verify(loginFormView).setErrorSymbolIncorrect()
@ -129,9 +136,10 @@ class LoginFormPresenterTest {
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf") presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
verify(loginFormView).hideSoftKeyboard() verify(loginFormView).hideSoftKeyboard()
verify(loginFormView).showLoginProgress(true) verify(loginFormView).showProgress(true)
verify(repository).clearCache() verify(loginFormView).showProgress(false)
verify(loginFormView).showLoginProgress(false) verify(loginFormView).showContent(false)
verify(loginFormView).showContent(true)
verify(errorHandler).proceed(testException) verify(errorHandler).proceed(testException)
} }
} }

View File

@ -9,7 +9,9 @@ import io.reactivex.Single
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.* import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
class LoginOptionsPresenterTest { class LoginOptionsPresenterTest {
@ -39,41 +41,40 @@ class LoginOptionsPresenterTest {
@Test @Test
fun initViewTest() { fun initViewTest() {
verify(loginOptionsView).initRecycler() verify(loginOptionsView).initView()
} }
@Test @Test
fun refreshDataTest() { fun refreshDataTest() {
doReturn(Single.just(listOf(testStudent))).`when`(repository).cachedStudents doReturn(Single.just(listOf(testStudent))).`when`(repository).cachedStudents
presenter.refreshData() presenter.onParentViewLoadData()
verify(loginOptionsView).showActionBar(true) verify(loginOptionsView).showActionBar(true)
verify(loginOptionsView).updateData(listOf(LoginOptionsItem(testStudent))) verify(loginOptionsView).updateData(listOf(LoginOptionsItem(testStudent)))
verify(repository).clearCache()
} }
@Test @Test
fun refreshDataErrorTest() { fun refreshDataErrorTest() {
doReturn(Single.error<List<Student>>(testException)).`when`(repository).cachedStudents doReturn(Single.error<List<Student>>(testException)).`when`(repository).cachedStudents
presenter.refreshData() presenter.onParentViewLoadData()
verify(loginOptionsView).showActionBar(true) verify(loginOptionsView).showActionBar(true)
verify(errorHandler).proceed(testException) verify(errorHandler).proceed(testException)
verify(repository).clearCache()
} }
@Test @Test
fun onSelectedStudentTest() { fun onSelectedStudentTest() {
doReturn(Completable.complete()).`when`(repository).saveStudent(testStudent) doReturn(Completable.complete()).`when`(repository).saveStudent(testStudent)
presenter.onSelectStudent(testStudent) presenter.onSelectItem(LoginOptionsItem(testStudent))
verify(loginOptionsView).showLoginProgress(true) verify(loginOptionsView).showContent(false)
verify(loginOptionsView).showProgress(true)
verify(loginOptionsView).openMainView() verify(loginOptionsView).openMainView()
} }
@Test @Test
fun onSelectedStudentErrorTest() { fun onSelectedStudentErrorTest() {
doReturn(Completable.error(testException)).`when`(repository).saveStudent(testStudent) doReturn(Completable.error(testException)).`when`(repository).saveStudent(testStudent)
presenter.onSelectStudent(testStudent) presenter.onSelectItem(LoginOptionsItem(testStudent))
verify(loginOptionsView).showLoginProgress(true) verify(loginOptionsView).showContent(false)
verify(loginOptionsView).showProgress(true)
verify(errorHandler).proceed(testException) verify(errorHandler).proceed(testException)
} }
} }