Untitled
unknown
plain_text
2 years ago
7.8 kB
12
Indexable
package ru.tensor.sbis.business.payment_draft.impl.ui.host
import android.app.Application
import android.content.pm.ActivityInfo
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import org.mockito.kotlin.*
import org.junit.After
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyString
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import org.robolectric.annotation.Config
import ru.tensor.sbis.android_ext_decl.viewprovider.OverlayFragmentHolder
import ru.tensor.sbis.base_components.fragment.ActivityOverlayFragmentHolder
import ru.tensor.sbis.business.payment.decl.data.PaymentDocType
import ru.tensor.sbis.business.payment_draft.decl.data.EditPayment
import ru.tensor.sbis.common.testing.mockStatic
import ru.tensor.sbis.common.util.ResourceProvider
import ru.tensor.sbis.design.utils.KeyboardUtils
import java.util.*
import ru.tensor.sbis.design.R as RDesign
import android.os.Bundle
import android.os.Looper
import ru.tensor.sbis.mvvm.utils.retain.FragmentAttendant
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.R])
internal class PaymentDraftHostRouterTest {
private val mockResourceProvider = mock<ResourceProvider> {
on { getString(any()) } doReturn ""
}
private lateinit var router: PaymentDraftHostRouter
private lateinit var mockFragmentManager: FragmentManager
private var mockFragmentTransaction: FragmentTransaction = mock {
on { commit() } doReturn 0
}
private lateinit var mockFragmentAttendant: FragmentAttendant
private var returnFragment = true
private var backStackCount = 1
@After
fun tearDown() {
backStackCount = 1
returnFragment = true
}
@Test
fun `On bind router to fragment verify that it has acquired lifecycle handler`() {
launchDefaultScenario()
assertFalse(router.hasLifecycleHandler)
val hostFragment = spy(Fragment())
router.bind(hostFragment)
assertTrue(router.hasLifecycleHandler)
}
@Test
fun `On goBack() if allowed to pop back stack, then pop last back stack state`() {
launchDefaultScenario()
router.goBack()
verify(mockFragmentManager).popBackStackImmediate()
}
@Test
fun `On goBack() if can't pop back stack and return confirmed then remove fragment`() {
launchDefaultScenario {
backStackCount = 0
router.isReturnConfirmed = true
router.goBack()
verify(it).removeFragment()
}
}
@Test
fun `On goBack() if can't pop back stack and return not confirmed then show interrupt dialog`() {
launchDefaultScenario()
backStackCount = 0
router.isReturnConfirmed = false
router.goBack()
shadowOf(Looper.getMainLooper()).idle()
verify(router).showInterruptDialog(argThat {
// При нажатии на кнопку "ОК", послать событие onConfirmationGoBack
invoke()
router.onConfirmationGoBackFlow.replayCache.isNotEmpty()
})
}
@Test
fun `On showPaymentDraft() show new screen with correct transaction`() {
launchDefaultScenario()
val args = EditPayment(UUID.randomUUID(), PaymentDocType.BANK)
returnFragment = false
router.showPaymentDraft(args)
verify(router).runCommandSticky(any())
verify(mockFragmentManager, atLeastOnce()).beginTransaction() // первый раз при моке, второй раз боевой
verify(mockFragmentTransaction, never()).addToBackStack(anyString()) // не добавляем документ в backstack
verify(mockFragmentTransaction, never()).setMaxLifecycle(any(), eq(Lifecycle.State.STARTED)) // currentToPause = false
verify(mockFragmentTransaction).setCustomAnimations(0, 0, 0, 0) // без анимации
}
@Test
fun `On showExpenseItems() show with animation and hide keyboard`() {
launchDefaultScenario()
var keyboardIsHidden = false
mockStatic<KeyboardUtils> {
on<Unit> { KeyboardUtils.hideKeyboard(any()) } doAnswer { keyboardIsHidden = true }
}
doNothing().whenever(router).closeDraftKeyboard()
router.showExpenseItems()
assertTrue(keyboardIsHidden)
verify(mockFragmentManager, times(2)).beginTransaction() // первый раз при моке, второй раз боевой
verify(mockFragmentTransaction).addToBackStack(anyString()) // добавляем в backstack
verify(mockFragmentTransaction).setCustomAnimations( // с анимацией справа налево
RDesign.anim.right_in,
RDesign.anim.right_out,
RDesign.anim.right_in,
RDesign.anim.right_out
)
}
private fun launchDefaultScenario(onActivityVerifier: ((TestActivity) -> Unit)? = null) {
val appContext: Application = ApplicationProvider.getApplicationContext()
val activityInfo = ActivityInfo().apply {
name = TestActivity::class.java.name
packageName = appContext.packageName
}
shadowOf(appContext.packageManager).addOrUpdateActivity(activityInfo)
ActivityScenario.launch(TestActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}.onActivity { testActivity ->
val fragment = spy(Fragment()) {
on { activity } doReturn testActivity
}
mockFragmentAttendant = mock {
on { component } doReturn fragment
}
testActivity.showFragmentWithCommit(fragment, false)
mockFragmentManager = spy(fragment.parentFragmentManager) {
on { backStackEntryCount } doAnswer { backStackCount }
//on { beginTransaction() } doReturn mockFragmentTransaction
on { findFragmentByTag(any()) } doAnswer { fragment.takeIf { returnFragment } }
}
router = spy(PaymentDraftHostRouter(mock(), mockResourceProvider, mockFragmentAttendant))
router.resume(fragment, mockFragmentManager)
onActivityVerifier?.invoke(spy(testActivity))
}
}
private fun TestActivity.showFragmentWithCommit(
fragment: Fragment, swipeable: Boolean
) {
setFragment(fragment, swipeable)
}
}
internal class TestActivity : AppCompatActivity(), OverlayFragmentHolder {
private val spyActivityOverlayFragmentHolder = ActivityOverlayFragmentHolder(this)
override fun onPostCreate(savedInstanceState: Bundle?) {
setTheme(RDesign.style.AppTheme)
super.onPostCreate(savedInstanceState)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTheme(RDesign.style.AppTheme)
setContentView(ru.tensor.sbis.business.payment_draft.impl.test.R.layout.payment_draft_activity_main)
}
override fun setFragment(fragment: Fragment, swipeable: Boolean)
= spyActivityOverlayFragmentHolder.setFragment(fragment, swipeable)
override fun hasFragment() = spyActivityOverlayFragmentHolder.hasFragment()
override fun removeFragment() = spyActivityOverlayFragmentHolder.removeFragment()
override fun handlePressed() = spyActivityOverlayFragmentHolder.handlePressed()
}Editor is loading...