11/*
2- * Copyright 2023-2024 Google LLC
2+ * Copyright 2025 Google LLC
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1414 * limitations under the License.
1515 */
1616
17- package com.google.android.fhir.datacapture.views.factories
17+ package com.google.android.fhir.datacapture.test.views
1818
1919import android.view.View
2020import android.widget.FrameLayout
2121import android.widget.TextView
22- import androidx.appcompat.app.AppCompatActivity
22+ import androidx.compose.ui.test.junit4.createEmptyComposeRule
23+ import androidx.compose.ui.test.onRoot
24+ import androidx.compose.ui.test.printToLog
2325import androidx.core.view.get
26+ import androidx.test.ext.junit.rules.ActivityScenarioRule
27+ import androidx.test.ext.junit.runners.AndroidJUnit4
28+ import androidx.test.platform.app.InstrumentationRegistry
2429import com.google.android.fhir.datacapture.R
2530import com.google.android.fhir.datacapture.extensions.displayString
2631import com.google.android.fhir.datacapture.extensions.identifierString
32+ import com.google.android.fhir.datacapture.test.TestActivity
2733import com.google.android.fhir.datacapture.validation.Invalid
2834import com.google.android.fhir.datacapture.validation.NotValidated
2935import com.google.android.fhir.datacapture.validation.Valid
3036import com.google.android.fhir.datacapture.views.QuestionTextConfiguration
3137import com.google.android.fhir.datacapture.views.QuestionnaireViewItem
38+ import com.google.android.fhir.datacapture.views.factories.AutoCompleteViewHolderFactory
39+ import com.google.android.fhir.datacapture.views.factories.QuestionnaireItemViewHolder
3240import com.google.android.material.chip.Chip
3341import com.google.android.material.chip.ChipGroup
3442import com.google.android.material.textfield.TextInputLayout
3543import com.google.common.truth.Truth.assertThat
3644import org.hl7.fhir.r4.model.Coding
3745import org.hl7.fhir.r4.model.Questionnaire
3846import org.hl7.fhir.r4.model.QuestionnaireResponse
47+ import org.junit.Before
48+ import org.junit.Rule
3949import org.junit.Test
4050import org.junit.runner.RunWith
41- import org.robolectric.Robolectric
42- import org.robolectric.RobolectricTestRunner
4351
44- @RunWith(RobolectricTestRunner ::class )
52+ @RunWith(AndroidJUnit4 ::class )
4553class AutoCompleteViewHolderFactoryTest {
46- private val parent =
47- FrameLayout (
48- Robolectric .buildActivity(AppCompatActivity ::class .java).create().get().apply {
49- setTheme(com.google.android.material.R .style.Theme_Material3_DayNight )
50- },
51- )
52- private val viewHolder = AutoCompleteViewHolderFactory .create(parent)
54+ @get:Rule
55+ val activityScenarioRule: ActivityScenarioRule <TestActivity > =
56+ ActivityScenarioRule (TestActivity ::class .java)
57+
58+ @get:Rule val composeTestRule = createEmptyComposeRule()
59+
60+ private lateinit var viewHolder: QuestionnaireItemViewHolder
61+
62+ @Before
63+ fun setUp () {
64+ activityScenarioRule.scenario.onActivity { activity ->
65+ viewHolder = AutoCompleteViewHolderFactory .create(FrameLayout (activity))
66+ activity.setContentView(viewHolder.itemView)
67+ }
68+
69+ InstrumentationRegistry .getInstrumentation().waitForIdleSync()
70+ }
5371
5472 @Test
5573 fun shouldSetQuestionHeader () {
@@ -62,6 +80,9 @@ class AutoCompleteViewHolderFactoryTest {
6280 ),
6381 )
6482
83+ // Synchronize
84+ composeTestRule.waitForIdle()
85+
6586 assertThat(viewHolder.itemView.findViewById<TextView >(R .id.question).text.toString())
6687 .isEqualTo(" Question" )
6788 }
@@ -80,6 +101,7 @@ class AutoCompleteViewHolderFactoryTest {
80101 .setValue(Coding ().setCode(" test2-code" ).setDisplay(" Test2 Code" )),
81102 )
82103 }
104+
83105 viewHolder.bind(
84106 QuestionnaireViewItem (
85107 questionnaireItem,
@@ -88,7 +110,7 @@ class AutoCompleteViewHolderFactoryTest {
88110 QuestionnaireResponse .QuestionnaireResponseItemAnswerComponent ().apply {
89111 value =
90112 questionnaireItem.answerOption
91- .first { it.value.displayString(parent .context) == " Test1 Code" }
113+ .first { it.value.displayString(viewHolder.itemView .context) == " Test1 Code" }
92114 .valueCoding
93115 },
94116 )
@@ -98,6 +120,7 @@ class AutoCompleteViewHolderFactoryTest {
98120 ),
99121 )
100122
123+ composeTestRule.onRoot().printToLog(" shouldHaveSingleAnswerChip" )
101124 assertThat(viewHolder.itemView.findViewById<ChipGroup >(R .id.chipContainer).childCount)
102125 .isEqualTo(1 )
103126 }
@@ -132,14 +155,18 @@ class AutoCompleteViewHolderFactoryTest {
132155 addAnswer(
133156 QuestionnaireResponse .QuestionnaireResponseItemAnswerComponent ().apply {
134157 value =
135- answers.first { it.value.displayString(parent.context) == " Test1 Code" }.valueCoding
158+ answers
159+ .first { it.value.displayString(viewHolder.itemView.context) == " Test1 Code" }
160+ .valueCoding
136161 },
137162 )
138163
139164 addAnswer(
140165 QuestionnaireResponse .QuestionnaireResponseItemAnswerComponent ().apply {
141166 value =
142- answers.first { it.value.displayString(parent.context) == " Test2 Code" }.valueCoding
167+ answers
168+ .first { it.value.displayString(viewHolder.itemView.context) == " Test2 Code" }
169+ .valueCoding
143170 },
144171 )
145172 },
@@ -198,7 +225,7 @@ class AutoCompleteViewHolderFactoryTest {
198225 value =
199226 answers
200227 .first {
201- it.value.identifierString(parent .context) ==
228+ it.value.identifierString(viewHolder.itemView .context) ==
202229 " http://answers/test-codes1.0|test2-code"
203230 }
204231 .valueCoding
@@ -245,7 +272,9 @@ class AutoCompleteViewHolderFactoryTest {
245272 addAnswer(
246273 QuestionnaireResponse .QuestionnaireResponseItemAnswerComponent ().apply {
247274 value =
248- answers.first { it.value.displayString(parent.context) == " Test1 Code" }.valueCoding
275+ answers
276+ .first { it.value.displayString(viewHolder.itemView.context) == " Test1 Code" }
277+ .valueCoding
249278 },
250279 )
251280 },
@@ -338,7 +367,7 @@ class AutoCompleteViewHolderFactoryTest {
338367 }
339368
340369 @Test
341- fun `hides error textview in the header` () {
370+ fun hidesErrorTextviewInTheHeader () {
342371 viewHolder.bind(
343372 QuestionnaireViewItem (
344373 Questionnaire .QuestionnaireItemComponent (),
@@ -353,7 +382,7 @@ class AutoCompleteViewHolderFactoryTest {
353382 }
354383
355384 @Test
356- fun `show asterisk` () {
385+ fun showAsterisk () {
357386 viewHolder.bind(
358387 QuestionnaireViewItem (
359388 Questionnaire .QuestionnaireItemComponent ().apply {
@@ -372,7 +401,7 @@ class AutoCompleteViewHolderFactoryTest {
372401 }
373402
374403 @Test
375- fun `hide asterisk` () {
404+ fun hideAsterisk () {
376405 viewHolder.bind(
377406 QuestionnaireViewItem (
378407 Questionnaire .QuestionnaireItemComponent ().apply {
@@ -391,7 +420,7 @@ class AutoCompleteViewHolderFactoryTest {
391420 }
392421
393422 @Test
394- fun `shows required text` () {
423+ fun showsRequiredText () {
395424 viewHolder.bind(
396425 QuestionnaireViewItem (
397426 Questionnaire .QuestionnaireItemComponent ().apply { required = true },
@@ -409,7 +438,7 @@ class AutoCompleteViewHolderFactoryTest {
409438 }
410439
411440 @Test
412- fun `hide required text` () {
441+ fun hideRequiredText () {
413442 viewHolder.bind(
414443 QuestionnaireViewItem (
415444 Questionnaire .QuestionnaireItemComponent ().apply { required = true },
@@ -429,7 +458,7 @@ class AutoCompleteViewHolderFactoryTest {
429458 }
430459
431460 @Test
432- fun `shows optional text ` () {
461+ fun `showsOptionalText ` () {
433462 viewHolder.bind(
434463 QuestionnaireViewItem (
435464 Questionnaire .QuestionnaireItemComponent ().apply { text = " Question" },
@@ -447,7 +476,7 @@ class AutoCompleteViewHolderFactoryTest {
447476 }
448477
449478 @Test
450- fun `hide optional text ` () {
479+ fun `hideOptionalText ` () {
451480 viewHolder.bind(
452481 QuestionnaireViewItem (
453482 Questionnaire .QuestionnaireItemComponent ().apply { text = " Question" },
0 commit comments