aboutsummaryrefslogtreecommitdiff
path: root/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt
blob: 0acdadaca7603f9b2c2aaea67b53c4e18453fde1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.navigation.fragment

import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.FragmentManager
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.test.annotation.UiThreadTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@LargeTest
@RunWith(AndroidJUnit4::class)
class DialogFragmentNavigatorTest {

    companion object {
        private const val INITIAL_FRAGMENT = 1
    }

    @get:Rule
    var activityRule = ActivityTestRule(EmptyActivity::class.java)

    private lateinit var emptyActivity: EmptyActivity
    private lateinit var fragmentManager: FragmentManager

    @Before
    fun setup() {
        emptyActivity = activityRule.activity
        fragmentManager = emptyActivity.supportFragmentManager
    }

    @UiThreadTest
    @Test
    fun testNavigate() {
        lateinit var dialogFragment: DialogFragment
        fragmentManager.fragmentFactory = object : FragmentFactory() {
            override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
                return super.instantiate(classLoader, className).also { fragment ->
                    if (fragment is DialogFragment) {
                        dialogFragment = fragment
                    }
                }
            }
        }
        val dialogNavigator = DialogFragmentNavigator(emptyActivity, fragmentManager)
        val destination = dialogNavigator.createDestination().apply {
            id = INITIAL_FRAGMENT
            className = EmptyDialogFragment::class.java.name
        }

        assertThat(dialogNavigator.navigate(destination, null, null, null))
            .isEqualTo(destination)
        fragmentManager.executePendingTransactions()
        assertWithMessage("Dialog should be shown")
            .that(dialogFragment.requireDialog().isShowing)
            .isTrue()
    }

    @UiThreadTest
    @Test
    fun testFindNavController() {
        val dialogFragment = EmptyDialogFragment()
        // Fake using a NavHostFragment and instead just manually show the DialogFragment
        dialogFragment.showNow(fragmentManager, null)
        assertWithMessage("Dialog should be shown")
            .that(dialogFragment.requireDialog().isShowing)
            .isTrue()

        // And set a NavController on the root view
        val navController = NavController(emptyActivity)
        Navigation.setViewNavController(
            dialogFragment.requireDialog().window!!.decorView,
            navController
        )

        val returnedNavController = NavHostFragment.findNavController(dialogFragment)
        assertThat(returnedNavController)
            .isEqualTo(navController)
    }

    @UiThreadTest
    @Test
    fun testPop() {
        lateinit var dialogFragment: DialogFragment
        fragmentManager.fragmentFactory = object : FragmentFactory() {
            override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
                return super.instantiate(classLoader, className).also { fragment ->
                    if (fragment is DialogFragment) {
                        dialogFragment = fragment
                    }
                }
            }
        }
        val dialogNavigator = DialogFragmentNavigator(emptyActivity, fragmentManager)
        val destination = dialogNavigator.createDestination().apply {
            id = INITIAL_FRAGMENT
            className = EmptyDialogFragment::class.java.name
        }

        assertThat(dialogNavigator.navigate(destination, null, null, null))
            .isEqualTo(destination)
        fragmentManager.executePendingTransactions()
        assertWithMessage("Dialog should be shown")
            .that(dialogFragment.requireDialog().isShowing)
            .isTrue()
        assertWithMessage("DialogNavigator should pop dialog off the back stack")
            .that(dialogNavigator.popBackStack())
            .isTrue()
        assertWithMessage("Pop should dismiss the DialogFragment")
            .that(dialogFragment.requireDialog().isShowing)
            .isFalse()
    }
}

class EmptyDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
        AlertDialog.Builder(requireContext()).create()
}