Skip to content

Commit 4b9b344

Browse files
committed
Migrate AttachmentViewHolderFactory to compose (wip)
1 parent ab0e1e6 commit 4b9b344

File tree

6 files changed

+977
-101
lines changed

6 files changed

+977
-101
lines changed

datacapture/src/androidTest/java/com/google/android/fhir/datacapture/test/views/AttachmentViewHolderFactoryEspressoTest.kt

Lines changed: 59 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 Google LLC
2+
* Copyright 2023-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.
@@ -18,9 +18,14 @@ package com.google.android.fhir.datacapture.test.views
1818

1919
import android.util.Base64
2020
import android.view.View
21-
import android.widget.Button
2221
import android.widget.FrameLayout
2322
import android.widget.TextView
23+
import androidx.compose.ui.test.assertIsDisplayed
24+
import androidx.compose.ui.test.assertIsNotDisplayed
25+
import androidx.compose.ui.test.assertTextEquals
26+
import androidx.compose.ui.test.junit4.createEmptyComposeRule
27+
import androidx.compose.ui.test.onNodeWithTag
28+
import androidx.compose.ui.test.onNodeWithText
2429
import androidx.constraintlayout.widget.ConstraintLayout
2530
import androidx.test.ext.junit.rules.ActivityScenarioRule
2631
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -30,7 +35,10 @@ import com.google.android.fhir.datacapture.test.TestActivity
3035
import com.google.android.fhir.datacapture.validation.NotValidated
3136
import com.google.android.fhir.datacapture.views.QuestionnaireViewItem
3237
import com.google.android.fhir.datacapture.views.factories.AttachmentViewHolderFactory
38+
import com.google.android.fhir.datacapture.views.factories.ATTACHMENT_MEDIA_PREVIEW_TAG
3339
import com.google.android.fhir.datacapture.views.factories.QuestionnaireItemViewHolder
40+
import com.google.android.fhir.datacapture.views.factories.TAKE_PHOTO_BUTTON_TAG
41+
import com.google.android.fhir.datacapture.views.factories.UPLOAD_FILE_BUTTON_TAG
3442
import com.google.common.truth.Truth.assertThat
3543
import org.hl7.fhir.r4.model.Attachment
3644
import org.hl7.fhir.r4.model.CodeType
@@ -44,19 +52,22 @@ import org.junit.runner.RunWith
4452
@RunWith(AndroidJUnit4::class)
4553
class AttachmentViewHolderFactoryEspressoTest {
4654

47-
@Rule
48-
@JvmField
55+
@get:Rule
4956
var activityScenarioRule: ActivityScenarioRule<TestActivity> =
5057
ActivityScenarioRule(TestActivity::class.java)
5158

52-
private lateinit var parent: FrameLayout
59+
@get:Rule val composeTestRule = createEmptyComposeRule()
60+
5361
private lateinit var viewHolder: QuestionnaireItemViewHolder
5462

5563
@Before
5664
fun setup() {
57-
activityScenarioRule.getScenario().onActivity { activity -> parent = FrameLayout(activity) }
58-
viewHolder = AttachmentViewHolderFactory.create(parent)
59-
setTestLayout(viewHolder.itemView)
65+
activityScenarioRule.scenario.onActivity { activity ->
66+
viewHolder = AttachmentViewHolderFactory.create(FrameLayout(activity))
67+
activity.setContentView(viewHolder.itemView)
68+
}
69+
70+
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
6071
}
6172

6273
@Test
@@ -74,16 +85,12 @@ class AttachmentViewHolderFactoryEspressoTest {
7485
answersChangedCallback = { _, _, _, _ -> },
7586
)
7687

77-
runOnUI { viewHolder.bind(questionnaireItemView) }
78-
79-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.take_photo).visibility)
80-
.isEqualTo(View.VISIBLE)
81-
82-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_photo).visibility)
83-
.isEqualTo(View.VISIBLE)
88+
viewHolder.bind(questionnaireItemView)
8489

85-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_photo).text)
86-
.isEqualTo(parent.context.getString(R.string.upload_photo))
90+
val context = viewHolder.itemView.context
91+
composeTestRule.onNodeWithTag(TAKE_PHOTO_BUTTON_TAG).assertIsDisplayed()
92+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertIsDisplayed()
93+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertTextEquals(context.getString(R.string.upload_photo))
8794
}
8895

8996
@Test
@@ -101,13 +108,11 @@ class AttachmentViewHolderFactoryEspressoTest {
101108
answersChangedCallback = { _, _, _, _ -> },
102109
)
103110

104-
runOnUI { viewHolder.bind(questionnaireItemView) }
111+
viewHolder.bind(questionnaireItemView)
105112

106-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_audio).visibility)
107-
.isEqualTo(View.VISIBLE)
108-
109-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_audio).text)
110-
.isEqualTo(parent.context.getString(R.string.upload_audio))
113+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertIsDisplayed()
114+
val context = viewHolder.itemView.context
115+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertTextEquals(context.getString(R.string.upload_audio))
111116
}
112117

113118
@Test
@@ -125,13 +130,11 @@ class AttachmentViewHolderFactoryEspressoTest {
125130
answersChangedCallback = { _, _, _, _ -> },
126131
)
127132

128-
runOnUI { viewHolder.bind(questionnaireItemView) }
129-
130-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_video).visibility)
131-
.isEqualTo(View.VISIBLE)
133+
viewHolder.bind(questionnaireItemView)
132134

133-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_video).text)
134-
.isEqualTo(parent.context.getString(R.string.upload_video))
135+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertIsDisplayed()
136+
val context = viewHolder.itemView.context
137+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertTextEquals(context.getString(R.string.upload_video))
135138
}
136139

137140
@Test
@@ -149,13 +152,11 @@ class AttachmentViewHolderFactoryEspressoTest {
149152
answersChangedCallback = { _, _, _, _ -> },
150153
)
151154

152-
runOnUI { viewHolder.bind(questionnaireItemView) }
153-
154-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_document).visibility)
155-
.isEqualTo(View.VISIBLE)
155+
viewHolder.bind(questionnaireItemView)
156156

157-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_document).text)
158-
.isEqualTo(parent.context.getString(R.string.upload_document))
157+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertIsDisplayed()
158+
val context = viewHolder.itemView.context
159+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertTextEquals(context.getString(R.string.upload_document))
159160
}
160161

161162
@Test
@@ -177,16 +178,12 @@ class AttachmentViewHolderFactoryEspressoTest {
177178
answersChangedCallback = { _, _, _, _ -> },
178179
)
179180

180-
runOnUI { viewHolder.bind(questionnaireItemView) }
181-
182-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.take_photo).visibility)
183-
.isEqualTo(View.VISIBLE)
184-
185-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_file).visibility)
186-
.isEqualTo(View.VISIBLE)
181+
viewHolder.bind(questionnaireItemView)
187182

188-
assertThat(viewHolder.itemView.findViewById<Button>(R.id.upload_file).text)
189-
.isEqualTo(parent.context.getString(R.string.upload_file))
183+
val context = viewHolder.itemView.context
184+
composeTestRule.onNodeWithTag(TAKE_PHOTO_BUTTON_TAG).assertIsDisplayed()
185+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertIsDisplayed()
186+
composeTestRule.onNodeWithTag(UPLOAD_FILE_BUTTON_TAG).assertTextEquals(context.getString(R.string.upload_file))
190187
}
191188

192189
@Test
@@ -219,12 +216,10 @@ class AttachmentViewHolderFactoryEspressoTest {
219216
answersChangedCallback = { _, _, _, _ -> },
220217
)
221218

222-
runOnUI { viewHolder.bind(questionnaireItemView) }
219+
viewHolder.bind(questionnaireItemView)
223220

224-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.photo_preview).visibility)
225-
.isEqualTo(View.VISIBLE)
226-
227-
assertThat(viewHolder.itemView.findViewById<TextView>(R.id.photo_title).text).isEqualTo("IMG_1")
221+
composeTestRule.onNodeWithTag(ATTACHMENT_MEDIA_PREVIEW_TAG).assertIsDisplayed()
222+
composeTestRule.onNodeWithText("IMG_1").assertIsDisplayed()
228223
}
229224

230225
@Test
@@ -257,13 +252,10 @@ class AttachmentViewHolderFactoryEspressoTest {
257252
answersChangedCallback = { _, _, _, _ -> },
258253
)
259254

260-
runOnUI { viewHolder.bind(questionnaireItemView) }
261-
262-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.file_preview).visibility)
263-
.isEqualTo(View.VISIBLE)
255+
viewHolder.bind(questionnaireItemView)
264256

265-
assertThat(viewHolder.itemView.findViewById<TextView>(R.id.file_title).text)
266-
.isEqualTo("Audio File")
257+
composeTestRule.onNodeWithTag(ATTACHMENT_MEDIA_PREVIEW_TAG).assertIsDisplayed()
258+
composeTestRule.onNodeWithText("Audio File").assertIsDisplayed()
267259
}
268260

269261
@Test
@@ -296,13 +288,10 @@ class AttachmentViewHolderFactoryEspressoTest {
296288
answersChangedCallback = { _, _, _, _ -> },
297289
)
298290

299-
runOnUI { viewHolder.bind(questionnaireItemView) }
300-
301-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.file_preview).visibility)
302-
.isEqualTo(View.VISIBLE)
291+
viewHolder.bind(questionnaireItemView)
303292

304-
assertThat(viewHolder.itemView.findViewById<TextView>(R.id.file_title).text)
305-
.isEqualTo("Video File")
293+
composeTestRule.onNodeWithTag(ATTACHMENT_MEDIA_PREVIEW_TAG).assertIsDisplayed()
294+
composeTestRule.onNodeWithText("Video File").assertIsDisplayed()
306295
}
307296

308297
@Test
@@ -335,13 +324,10 @@ class AttachmentViewHolderFactoryEspressoTest {
335324
answersChangedCallback = { _, _, _, _ -> },
336325
)
337326

338-
runOnUI { viewHolder.bind(questionnaireItemView) }
327+
viewHolder.bind(questionnaireItemView)
339328

340-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.file_preview).visibility)
341-
.isEqualTo(View.VISIBLE)
342-
343-
assertThat(viewHolder.itemView.findViewById<TextView>(R.id.file_title).text)
344-
.isEqualTo("Document File")
329+
composeTestRule.onNodeWithTag(ATTACHMENT_MEDIA_PREVIEW_TAG).assertIsDisplayed()
330+
composeTestRule.onNodeWithText("Document File").assertIsDisplayed()
345331
}
346332

347333
@Test
@@ -363,13 +349,9 @@ class AttachmentViewHolderFactoryEspressoTest {
363349
answersChangedCallback = { _, _, _, _ -> },
364350
)
365351

366-
runOnUI { viewHolder.bind(questionnaireItemView) }
367-
368-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.photo_preview).visibility)
369-
.isEqualTo(View.GONE)
352+
viewHolder.bind(questionnaireItemView)
370353

371-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.file_preview).visibility)
372-
.isEqualTo(View.GONE)
354+
composeTestRule.onNodeWithTag(ATTACHMENT_MEDIA_PREVIEW_TAG).assertIsNotDisplayed().assertDoesNotExist()
373355
}
374356

375357
@Test
@@ -406,10 +388,9 @@ class AttachmentViewHolderFactoryEspressoTest {
406388
answersChangedCallback = { _, _, _, _ -> },
407389
)
408390

409-
runOnUI { viewHolder.bind(questionnaireItem) }
391+
viewHolder.bind(questionnaireItem)
410392

411-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.photo_preview).visibility)
412-
.isEqualTo(View.VISIBLE)
393+
composeTestRule.onNodeWithTag(ATTACHMENT_MEDIA_PREVIEW_TAG).assertIsDisplayed()
413394

414395
val questionnaireItemWithNullAnswer =
415396
QuestionnaireViewItem(
@@ -428,20 +409,8 @@ class AttachmentViewHolderFactoryEspressoTest {
428409
answersChangedCallback = { _, _, _, _ -> },
429410
)
430411

431-
runOnUI { viewHolder.bind(questionnaireItemWithNullAnswer) }
412+
viewHolder.bind(questionnaireItemWithNullAnswer)
432413

433-
assertThat(viewHolder.itemView.findViewById<ConstraintLayout>(R.id.photo_preview).visibility)
434-
.isEqualTo(View.GONE)
435-
}
436-
437-
/** Method to run code snippet on UI/main thread */
438-
private fun runOnUI(action: () -> Unit) {
439-
activityScenarioRule.scenario.onActivity { activity -> action() }
440-
}
441-
442-
/** Method to set content view for test activity */
443-
private fun setTestLayout(view: View) {
444-
activityScenarioRule.scenario.onActivity { activity -> activity.setContentView(view) }
445-
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
414+
composeTestRule.onNodeWithTag(ATTACHMENT_MEDIA_PREVIEW_TAG).assertIsNotDisplayed().assertDoesNotExist()
446415
}
447416
}

datacapture/src/main/java/com/google/android/fhir/datacapture/extensions/MoreQuestionnaireItemComponents.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ internal val QuestionnaireItemComponent.maxSizeInMiBs: BigDecimal?
579579
get() = maxSizeInBytes?.div(BYTES_PER_MIB)
580580

581581
/** The default maximum size of an attachment is 1 Mebibytes. */
582-
private val DEFAULT_SIZE = BigDecimal(1048576)
582+
internal val DEFAULT_SIZE = BigDecimal(1048576)
583583

584584
/** Returns true if given size is above maximum size allowed. */
585585
internal fun QuestionnaireItemComponent.isGivenSizeOverLimit(

datacapture/src/main/java/com/google/android/fhir/datacapture/views/attachment/CameraLauncherFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 Google LLC
2+
* Copyright 2022-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.

0 commit comments

Comments
 (0)