From 15189e9e7c8f45523e0f7eb2e684d3fcb2098b03 Mon Sep 17 00:00:00 2001 From: Xavier Gouchet Date: Fri, 4 Dec 2020 15:33:43 +0100 Subject: [PATCH] :bug: (RUMM-910): Always send custom actions --- .../internal/domain/scope/RumActionScope.kt | 10 +++-- .../domain/scope/RumActionScopeTest.kt | 42 ++++++++++++++++++- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScope.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScope.kt index 4104af56bd..20a5361d05 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScope.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScope.kt @@ -31,7 +31,7 @@ internal class RumActionScope( private val eventTimestamp = eventTime.timestamp internal val actionId: String = UUID.randomUUID().toString() - private var type: RumActionType = initialType + internal var type: RumActionType = initialType internal var name: String = initialName private val startedNanos: Long = eventTime.nanoTime private var lastInteractionNanos: Long = startedNanos @@ -156,7 +156,9 @@ internal class RumActionScope( ) { if (sent) return - if (resourceCount > 0 || errorCount > 0 || viewTreeChangeCount > 0) { + val actualType = type + val sideEffectsCount = resourceCount + errorCount + viewTreeChangeCount + if (sideEffectsCount > 0 || actualType == RumActionType.CUSTOM) { attributes.putAll(GlobalRum.globalAttributes) val context = getRumContext() @@ -165,7 +167,7 @@ internal class RumActionScope( val actionEvent = ActionEvent( date = eventTimestamp, action = ActionEvent.Action( - type = type.toSchemaType(), + type = actualType.toSchemaType(), id = actionId, target = ActionEvent.Target(name), error = ActionEvent.Error(errorCount), @@ -198,7 +200,7 @@ internal class RumActionScope( parentScope.handleEvent(RumRawEvent.SentAction(), writer) } else { devLogger.i( - "RUM Action $actionId ($type on $name) was dropped " + + "RUM Action $actionId ($actualType on $name) was dropped " + "(no side effect was registered during its scope)" ) } diff --git a/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScopeTest.kt b/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScopeTest.kt index 6399cac460..e1179b2996 100644 --- a/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScopeTest.kt +++ b/dd-sdk-android/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumActionScopeTest.kt @@ -71,7 +71,6 @@ internal class RumActionScopeTest { @Mock lateinit var mockWriter: Writer - @Forgery lateinit var fakeType: RumActionType @StringForgery @@ -94,6 +93,11 @@ internal class RumActionScopeTest { fun `set up`(forge: Forge) { fakeEventTime = Time() + fakeType = forge.aValueFrom( + RumActionType::class.java, + exclude = listOf(RumActionType.CUSTOM) + ) + RumFeature::class.java.setStaticValue("userInfoProvider", mockUserInfoProvider) fakeAttributes = forge.exhaustiveAttributes() @@ -1044,6 +1048,42 @@ internal class RumActionScopeTest { assertThat(result).isNull() } + @Test + fun `M send custom Action after timeout W handleEvent(any) and no side effect`() { + // When + Thread.sleep(RumActionScope.ACTION_INACTIVITY_MS) + testedScope.type = RumActionType.CUSTOM + val result = testedScope.handleEvent(mockEvent(), mockWriter) + + // Then + argumentCaptor { + verify(mockWriter).write(capture()) + assertThat(lastValue) + .hasAttributes(fakeAttributes) + .hasUserExtraAttributes(fakeUserInfo.extraInfo) + .hasActionData { + hasId(testedScope.actionId) + hasTimestamp(fakeEventTime.timestamp) + hasType(RumActionType.CUSTOM) + hasTargetName(fakeName) + hasDuration(1) + hasResourceCount(0) + hasErrorCount(0) + hasCrashCount(0) + hasView(fakeParentContext.viewId, fakeParentContext.viewUrl) + hasUserInfo(fakeUserInfo) + hasApplicationId(fakeParentContext.applicationId) + hasSessionId(fakeParentContext.sessionId) + } + } + verify(mockParentScope).handleEvent( + isA(), + same(mockWriter) + ) + verifyNoMoreInteractions(mockWriter) + assertThat(result).isNull() + } + @Test fun `𝕄 send Action after threshold 𝕎 handleEvent(ViewTreeChanged+any)`() { // When