Skip to content

Commit 16acef9

Browse files
committed
Add accessibility test coverage
1 parent 207c199 commit 16acef9

File tree

5 files changed

+212
-13
lines changed

5 files changed

+212
-13
lines changed

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/RumConfiguration.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ data class RumConfiguration internal constructor(
6060
}
6161

6262
/**
63-
* Whether to collect accessibility attributes inside the RUM view update event.
64-
* This is disabled by default.
63+
* Whether to collect accessibility attributes - this is disabled by default.
6564
*
6665
* @param enabled whether collecting accessibility attributes is enabled or not.
6766
*/

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/RumDataWriterTest.kt

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.datadog.android.rum.model.ErrorEvent
1717
import com.datadog.android.rum.model.LongTaskEvent
1818
import com.datadog.android.rum.model.ResourceEvent
1919
import com.datadog.android.rum.model.ViewEvent
20+
import com.datadog.android.rum.model.ViewEvent.Accessibility
2021
import com.datadog.android.rum.utils.config.GlobalRumMonitorTestConfiguration
2122
import com.datadog.android.rum.utils.forge.Configurator
2223
import com.datadog.tools.unit.annotations.TestConfigurationsProvider
@@ -36,6 +37,7 @@ import org.junit.jupiter.api.extension.Extensions
3637
import org.mockito.Mock
3738
import org.mockito.junit.jupiter.MockitoExtension
3839
import org.mockito.junit.jupiter.MockitoSettings
40+
import org.mockito.kotlin.argumentCaptor
3941
import org.mockito.kotlin.doReturn
4042
import org.mockito.kotlin.doThrow
4143
import org.mockito.kotlin.verify
@@ -252,7 +254,63 @@ internal class RumDataWriterTest {
252254

253255
// endregion
254256

255-
private fun isAccessibilityPopulated(accessibility: ViewEvent.Accessibility?): Boolean {
257+
// region accessibility
258+
259+
@Test
260+
fun `M hasAccessibility false W write() { empty accessibility object }`(
261+
forge: Forge
262+
) {
263+
// Given
264+
val viewEvent = forge.getForgery<ViewEvent>()
265+
val newView = viewEvent.view.copy(
266+
accessibility = Accessibility()
267+
)
268+
val newViewEvent = viewEvent.copy(
269+
view = newView
270+
)
271+
272+
whenever(mockSerializer.serialize(newViewEvent)) doReturn fakeSerializedEvent
273+
274+
// When
275+
testedWriter.write(mockEventBatchWriter, newViewEvent, fakeEventType)
276+
277+
// Then
278+
val captor = argumentCaptor<RumEventMeta.View>()
279+
verify(mockEventMetaSerializer).serialize(captor.capture())
280+
val metaData = captor.firstValue
281+
assertThat(metaData.hasAccessibility).isFalse
282+
}
283+
284+
@Test
285+
fun `M hasAccessibility true W write() { populated accessibility object }`(
286+
forge: Forge
287+
) {
288+
// Given
289+
val viewEvent = forge.getForgery<ViewEvent>()
290+
val newView = viewEvent.view.copy(
291+
accessibility = Accessibility(
292+
textSize = "1.3"
293+
)
294+
)
295+
val newViewEvent = viewEvent.copy(
296+
view = newView
297+
)
298+
299+
whenever(mockSerializer.serialize(newViewEvent)) doReturn fakeSerializedEvent
300+
301+
// When
302+
testedWriter.write(mockEventBatchWriter, newViewEvent, fakeEventType)
303+
304+
// Then
305+
val captor = argumentCaptor<RumEventMeta.View>()
306+
verify(mockEventMetaSerializer).serialize(captor.capture())
307+
val metaData = captor.firstValue
308+
assertThat(metaData.hasAccessibility).isTrue
309+
}
310+
311+
// endregion
312+
313+
private fun isAccessibilityPopulated(accessibility: Accessibility?): Boolean {
256314
if (accessibility == null) return false
257315
return setOf<Any?>(
258316
accessibility.textSize,

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumViewEventFilterTest.kt

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,153 @@ internal class RumViewEventFilterTest {
158158
assertThat(result).containsExactlyElementsOf(expectedResult)
159159
}
160160

161+
// region accessibility
162+
163+
@Test
164+
fun `M keep only max doc version W filterOutRedundantViewEvents() { mixed batch, no accessibility }`(
165+
forge: Forge
166+
) {
167+
// Given
168+
val viewEventMetas = forge.aViewEventMetaList(hasAccessibility = false)
169+
val viewEvents = viewEventMetas.map {
170+
RawBatchEvent(
171+
data = forge.aString().toByteArray(),
172+
metadata = it.toBytes()
173+
)
174+
}
175+
val nonViewEvents = forge.aList {
176+
RawBatchEvent(
177+
data = forge.aString().toByteArray(),
178+
metadata = forge.aString().toByteArray()
179+
)
180+
}
181+
val batch = forge.shuffle(nonViewEvents + viewEvents)
182+
viewEventMetas.forEach {
183+
whenever(mockEventMetaDeserializer.deserialize(it.toBytes())) doReturn it
184+
}
185+
val expectedViewMetasToKeep = viewEventMetas.groupBy { it.viewId }
186+
.mapValues { element -> element.value.maxBy { it.documentVersion } }
187+
.values
188+
val expectedViewEventsToDrop = viewEvents
189+
.filter { viewEvent ->
190+
expectedViewMetasToKeep.none {
191+
it.toBytes().contentEquals(viewEvent.metadata)
192+
}
193+
}
194+
val expectedResult = batch.filter { !expectedViewEventsToDrop.contains(it) }
195+
196+
// When
197+
val result = testedFilter.filterOutRedundantViewEvents(batch)
198+
199+
// Then
200+
assertThat(result).containsExactlyElementsOf(expectedResult)
201+
}
202+
203+
@Test
204+
fun `M all accessibility batches W filterOutRedundantViewEvents() { mixed batch, has accessibility }`(
205+
forge: Forge
206+
) {
207+
// Given
208+
val viewEventMetas = forge.aViewEventMetaList(hasAccessibility = true)
209+
val viewEvents = viewEventMetas.map {
210+
RawBatchEvent(
211+
data = forge.aString().toByteArray(),
212+
metadata = it.toBytes()
213+
)
214+
}
215+
val nonViewEvents = forge.aList {
216+
RawBatchEvent(
217+
data = forge.aString().toByteArray(),
218+
metadata = forge.aString().toByteArray()
219+
)
220+
}
221+
val batch = forge.shuffle(nonViewEvents + viewEvents)
222+
viewEventMetas.forEach {
223+
whenever(mockEventMetaDeserializer.deserialize(it.toBytes())) doReturn it
224+
}
225+
226+
// When
227+
val result = testedFilter.filterOutRedundantViewEvents(batch)
228+
229+
// Then
230+
assertThat(result).containsExactlyElementsOf(batch)
231+
}
232+
233+
@Test
234+
fun `M keep only accessibility and maxDocVersion W filterOutRedundantViewEvents()`(
235+
forge: Forge
236+
) {
237+
// Given
238+
val viewId = forge.aString()
239+
val newMetaList = mutableListOf<RumEventMeta.View>()
240+
// max doc version
241+
val keptMaxDocEvent = RumEventMeta.View(
242+
viewId = viewId,
243+
documentVersion = Long.MAX_VALUE,
244+
hasAccessibility = false
245+
)
246+
newMetaList.add(keptMaxDocEvent)
247+
248+
// accessibility true
249+
val keptAccessibilityEvent = RumEventMeta.View(
250+
viewId = viewId,
251+
documentVersion = Long.MIN_VALUE,
252+
hasAccessibility = true
253+
)
254+
newMetaList.add(keptAccessibilityEvent)
255+
256+
// some other doc version
257+
val droppedEvent = RumEventMeta.View(
258+
viewId = viewId,
259+
documentVersion = forge.aLong(max = Long.MAX_VALUE - 1),
260+
hasAccessibility = false
261+
)
262+
newMetaList.add(droppedEvent)
263+
264+
val viewEvents = newMetaList.map {
265+
RawBatchEvent(
266+
data = forge.aString().toByteArray(),
267+
metadata = it.toBytes()
268+
)
269+
}
270+
newMetaList.forEach {
271+
whenever(mockEventMetaDeserializer.deserialize(it.toBytes())) doReturn it
272+
}
273+
274+
val keptMaxDocEventRaw = viewEvents.find { it.metadata.contentEquals(keptMaxDocEvent.toBytes()) }!!
275+
val keptAccessibilityEventRaw = viewEvents.find {
276+
it.metadata.contentEquals(
277+
keptAccessibilityEvent.toBytes()
278+
)
279+
}!!
280+
val droppedEventRaw = viewEvents.find { it.metadata.contentEquals(droppedEvent.toBytes()) }!!
281+
282+
// When
283+
val result = testedFilter.filterOutRedundantViewEvents(viewEvents)
284+
285+
// Then
286+
assertThat(result).containsExactlyInAnyOrder(keptMaxDocEventRaw, keptAccessibilityEventRaw)
287+
assertThat(result).doesNotContain(droppedEventRaw)
288+
}
289+
290+
// endregion
291+
161292
// region Internal
162293

163-
private fun Forge.aViewEventMetaList(viewIds: Set<String> = emptySet()): List<RumEventMeta.View> {
294+
private fun Forge.aViewEventMetaList(
295+
viewIds: Set<String> = emptySet(),
296+
hasAccessibility: Boolean = false,
297+
size: Int = -1
298+
): List<RumEventMeta.View> {
164299
return viewIds.ifEmpty { aList { getForgery<UUID>().toString() }.toSet() }
165-
.flatMap { aList { getForgery<RumEventMeta.View>().copy(viewId = it, hasAccessibility = false) } }
300+
.flatMap {
301+
aList(size = size) {
302+
getForgery<RumEventMeta.View>().copy(
303+
viewId = it,
304+
hasAccessibility = hasAccessibility
305+
)
306+
}
307+
}
166308
}
167309

168310
private fun RumEventMeta.View.toBytes() = toJson().toString().toByteArray()

features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/utils/forge/AccessibilityForgeryFactory.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import fr.xgouchet.elmyr.ForgeryFactory
1313
internal class AccessibilityForgeryFactory : ForgeryFactory<Accessibility> {
1414
override fun getForgery(forge: Forge): Accessibility {
1515
return Accessibility(
16-
textSize = forge.aNullable { forge.aString() },
17-
rtlEnabled = forge.aNullable { forge.aBool() },
18-
screenReaderEnabled = forge.aNullable { forge.aBool() },
19-
increaseContrastEnabled = forge.aNullable { forge.aBool() },
20-
reducedAnimationsEnabled = forge.aNullable { forge.aBool() },
21-
invertColorsEnabled = forge.aNullable { forge.aBool() },
22-
singleAppModeEnabled = forge.aNullable { forge.aBool() }
16+
textSize = forge.aNullable { aString() },
17+
rtlEnabled = forge.aNullable { aBool() },
18+
screenReaderEnabled = forge.aNullable { aBool() },
19+
increaseContrastEnabled = forge.aNullable { aBool() },
20+
reducedAnimationsEnabled = forge.aNullable { aBool() },
21+
invertColorsEnabled = forge.aNullable { aBool() },
22+
singleAppModeEnabled = forge.aNullable { aBool() }
2323
)
2424
}
2525
}

features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/utils/forge/ViewEventForgeryFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ViewEventForgeryFactory : ForgeryFactory<ViewEvent> {
6565
refreshRateAverage = forge.aNullable { aPositiveDouble() },
6666
refreshRateMin = forge.aNullable { aPositiveDouble() },
6767
frustration = forge.aNullable { ViewEvent.Frustration(aPositiveLong()) },
68-
accessibility = forge.aNullable { forge.getForgery<Accessibility>() }
68+
accessibility = forge.aNullable { getForgery<Accessibility>() }
6969
),
7070
connectivity = forge.aNullable {
7171
ViewEvent.Connectivity(

0 commit comments

Comments
 (0)