Untitled
unknown
plain_text
5 months ago
7.8 kB
2
Indexable
Never
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() }