Skip to content

Commit 8a62db2

Browse files
committed
Rewrite ImportDialog with Kotlin + Compose
1 parent def5430 commit 8a62db2

43 files changed

Lines changed: 1568 additions & 374 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,11 @@
520520
android:name=".vcard.ShareVCardActivity"
521521
android:theme="@style/BackgroundOnlyTheme"/>
522522

523+
<activity
524+
android:name=".ui.interactions.importing.ImportActivity"
525+
android:label="@string/dialog_import"
526+
android:theme="@style/Theme.Compose.Dialog"/>
527+
523528
<activity
524529
android:name=".ui.simimport.SimImportActivity"
525530
android:label="@string/sim_import_title"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.android.contacts.tests
2+
3+
import android.content.Context
4+
import android.content.res.Resources
5+
import androidx.test.platform.app.InstrumentationRegistry
6+
7+
private val context: Context get() = InstrumentationRegistry.getInstrumentation().context
8+
internal val resources: Resources get() = context.resources

app/src/test/kotlin/com/android/contacts/tests/AccountDisplayModelFactory.kt renamed to app/src/test/kotlin/com/android/contacts/tests/factory/AccountDisplayModelFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.android.contacts.tests
1+
package com.android.contacts.tests.factory
22

33
import android.graphics.drawable.Drawable
44
import com.android.contacts.domain.accounts.model.AccountDisplayModel
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.android.contacts.tests.factory
2+
3+
import com.android.contacts.domain.accounts.model.AccountModel
4+
import kotlin.random.Random
5+
6+
internal object AccountModelFactory {
7+
fun build(
8+
name: String = "Account ${Random.nextInt().toString().take(4)}",
9+
type: String? = null,
10+
dataSet: String? = null,
11+
) = AccountModel(
12+
name = name,
13+
type = type,
14+
dataSet = dataSet,
15+
)
16+
}

app/src/test/kotlin/com/android/contacts/tests/AccountUiModelFactory.kt renamed to app/src/test/kotlin/com/android/contacts/tests/factory/AccountUiModelFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.android.contacts.tests
1+
package com.android.contacts.tests.factory
22

33
import android.graphics.drawable.Drawable
44
import com.android.contacts.ui.simimport.screen.model.AccountUiModel
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.android.contacts.tests.factory
2+
3+
import com.android.contacts.model.SimCard
4+
import kotlin.random.Random
5+
6+
object SimCardFactory {
7+
fun build(
8+
subscriptionId: Int = Random.nextInt(),
9+
simId: String = subscriptionId.toString(),
10+
carrierName: String? = null,
11+
displayName: String? = null,
12+
phoneNumber: String? = null,
13+
countryCode: String? = null,
14+
) = SimCard(
15+
simId,
16+
subscriptionId,
17+
carrierName,
18+
displayName,
19+
phoneNumber,
20+
countryCode,
21+
)
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.android.contacts.tests
2+
3+
import com.android.contacts.ui.interactions.importing.screen.model.SimCardOption
4+
import kotlin.random.Random
5+
6+
object SimCardOptionFactory {
7+
fun build(
8+
subscriptionId: Int = Random.nextInt(),
9+
name: String? = null,
10+
contactsCount: Int? = null,
11+
phone: String? = null,
12+
) = SimCardOption(
13+
subscriptionId = subscriptionId,
14+
name = name,
15+
contactsCount = contactsCount,
16+
phone = phone,
17+
)
18+
}

app/src/test/kotlin/com/android/contacts/tests/SimContactFactory.kt renamed to app/src/test/kotlin/com/android/contacts/tests/factory/SimContactFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.android.contacts.tests
1+
package com.android.contacts.tests.factory
22

33
import com.android.contacts.model.SimContact
44
import kotlin.random.Random

app/src/test/kotlin/com/android/contacts/tests/SimContactUiModelFactory.kt renamed to app/src/test/kotlin/com/android/contacts/tests/factory/SimContactUiModelFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.android.contacts.tests
1+
package com.android.contacts.tests.factory
22

33
import com.android.contacts.ui.simimport.screen.model.SimContactUiModel
44
import kotlin.random.Random
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package com.android.contacts.ui.interactions.importing
2+
3+
import androidx.compose.ui.test.ComposeUiTest
4+
import androidx.compose.ui.test.ExperimentalTestApi
5+
import androidx.compose.ui.test.assertIsDisplayed
6+
import androidx.compose.ui.test.assertIsNotDisplayed
7+
import androidx.compose.ui.test.onNodeWithTag
8+
import androidx.compose.ui.test.onNodeWithText
9+
import androidx.compose.ui.test.v2.runComposeUiTest
10+
import com.android.contacts.R
11+
import com.android.contacts.domain.accounts.model.AccountModel
12+
import com.android.contacts.tests.SimCardOptionFactory
13+
import com.android.contacts.tests.factory.AccountModelFactory
14+
import com.android.contacts.tests.resources
15+
import com.android.contacts.ui.interactions.importing.screen.ImportDialog
16+
import com.android.contacts.ui.interactions.importing.screen.ImportEffectHandler
17+
import com.android.contacts.ui.interactions.importing.screen.ImportScreenModel
18+
import com.android.contacts.ui.interactions.importing.screen.model.IMPORT_EMPTY_MESSAGE_TEST_TAG
19+
import com.android.contacts.ui.interactions.importing.screen.model.IMPORT_PROGRESS_TEST_TAG
20+
import com.android.contacts.ui.interactions.importing.screen.model.IMPORT_VCARD_BUTTON_TEST_TAG
21+
import com.android.contacts.ui.interactions.importing.screen.model.ImportAction as Action
22+
import com.android.contacts.ui.interactions.importing.screen.model.ImportUiState as State
23+
import io.mockk.every
24+
import io.mockk.mockk
25+
import io.mockk.verify
26+
import kotlinx.collections.immutable.persistentListOf
27+
import kotlinx.coroutines.flow.MutableStateFlow
28+
import org.junit.Before
29+
import org.junit.Test
30+
import org.junit.runner.RunWith
31+
import org.robolectric.RobolectricTestRunner
32+
33+
@OptIn(ExperimentalTestApi::class)
34+
@RunWith(RobolectricTestRunner::class)
35+
class ImportDialogTest {
36+
37+
private val fakeUiStateFlow = MutableStateFlow(State())
38+
private lateinit var screenModel: ImportScreenModel
39+
private lateinit var effectHandler: ImportEffectHandler
40+
private var accountChosen: AccountModel? = null
41+
42+
@Before
43+
fun setup() {
44+
screenModel = mockk(relaxed = true)
45+
effectHandler = mockk(relaxed = true)
46+
every { screenModel.uiState } returns fakeUiStateFlow
47+
}
48+
49+
@Test
50+
fun showsOrHidesProgressIndicator() = runComposeUiTest {
51+
setScreenContent()
52+
53+
fakeUiStateFlow.value = State(
54+
isVCardImportAvailable = null,
55+
simCardOptions = null,
56+
)
57+
onNodeWithTag(IMPORT_PROGRESS_TEST_TAG).assertIsDisplayed()
58+
59+
fakeUiStateFlow.value = State(
60+
isVCardImportAvailable = true,
61+
simCardOptions = persistentListOf(),
62+
)
63+
onNodeWithTag(IMPORT_PROGRESS_TEST_TAG).assertIsNotDisplayed()
64+
}
65+
66+
@Test
67+
fun showsEmptyState() = runComposeUiTest {
68+
setScreenContent()
69+
70+
fakeUiStateFlow.value = State(
71+
isVCardImportAvailable = false,
72+
simCardOptions = persistentListOf(),
73+
)
74+
onNodeWithTag(IMPORT_EMPTY_MESSAGE_TEST_TAG).assertIsDisplayed()
75+
}
76+
77+
@Test
78+
fun showsOrHidesVCardOption() = runComposeUiTest {
79+
setScreenContent()
80+
81+
fakeUiStateFlow.value = State(
82+
isVCardImportAvailable = true,
83+
simCardOptions = persistentListOf(),
84+
)
85+
onNodeWithTag(IMPORT_VCARD_BUTTON_TEST_TAG).assertIsDisplayed()
86+
87+
fakeUiStateFlow.value = State(
88+
isVCardImportAvailable = false,
89+
simCardOptions = persistentListOf(),
90+
)
91+
onNodeWithTag(IMPORT_VCARD_BUTTON_TEST_TAG).assertIsNotDisplayed()
92+
}
93+
94+
@Test
95+
fun showsSimCardOptions() = runComposeUiTest {
96+
setScreenContent()
97+
98+
fakeUiStateFlow.value = State(
99+
isVCardImportAvailable = false,
100+
simCardOptions = persistentListOf(
101+
SimCardOptionFactory.build(),
102+
SimCardOptionFactory.build(name = "Test")
103+
),
104+
)
105+
106+
onNodeWithText(
107+
resources.getString(R.string.import_from_sim_summary_fmt, 1)
108+
).assertIsDisplayed()
109+
onNodeWithText(
110+
resources.getString(R.string.import_from_sim_summary_fmt, "Test")
111+
).assertIsDisplayed()
112+
}
113+
114+
@Test
115+
fun whenAccountChosenIsProvided_callOnAction() = runComposeUiTest {
116+
accountChosen = AccountModelFactory.build()
117+
118+
setScreenContent()
119+
120+
verify { screenModel.onAction(Action.AccountChosen(accountChosen!!)) }
121+
}
122+
123+
private fun ComposeUiTest.setScreenContent() {
124+
setContent {
125+
ImportDialog(
126+
effectHandler = effectHandler,
127+
screenModel = screenModel,
128+
accountChosen = accountChosen,
129+
)
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)