2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-09 19:10:42 +00:00

For #25446: Ensure for every message shown we have recordExposure

This commit is contained in:
Arturo Mejia 2022-06-14 20:24:18 -04:00 committed by mergify[bot]
parent 8b04752122
commit 34b31f8b11
10 changed files with 19 additions and 75 deletions

View File

@ -136,11 +136,6 @@ sealed class AppAction : Action {
*/ */
data class MessageClicked(val message: Message) : MessagingAction() data class MessageClicked(val message: Message) : MessagingAction()
/**
* Indicates the given [message] was shown.
*/
data class MessageDisplayed(val message: Message) : MessagingAction()
/** /**
* Indicates the given [message] was dismissed. * Indicates the given [message] was dismissed.
*/ */

View File

@ -14,7 +14,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDismissed import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDismissed
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDisplayed
/** /**
* Handles default interactions with the ui of GleanPlumb messages. * Handles default interactions with the ui of GleanPlumb messages.
@ -44,14 +43,6 @@ class DefaultMessageController(
appStore.dispatch(MessageDismissed(message)) appStore.dispatch(MessageDismissed(message))
} }
override fun onMessageDisplayed(message: Message) {
if (message.maxDisplayCount <= message.metadata.displayCount + 1) {
Messaging.messageExpired.record(Messaging.MessageExpiredExtra(message.id))
}
Messaging.messageShown.record(Messaging.MessageShownExtra(message.id))
appStore.dispatch(MessageDisplayed(message))
}
@VisibleForTesting @VisibleForTesting
internal fun handleAction(action: String): Intent { internal fun handleAction(action: String): Intent {
val partialAction = if (action.startsWith("http", ignoreCase = true)) { val partialAction = if (action.startsWith("http", ignoreCase = true)) {

View File

@ -17,9 +17,4 @@ interface MessageController {
* Indicates the provided [message] was dismissed by a user. * Indicates the provided [message] was dismissed by a user.
*/ */
fun onMessageDismissed(message: Message) fun onMessageDismissed(message: Message)
/**
* Indicates the provided [message] was displayed to a user.
*/
fun onMessageDisplayed(message: Message)
} }

View File

@ -10,12 +10,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.components.lib.state.Middleware import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext import mozilla.components.lib.state.MiddlewareContext
import org.mozilla.fenix.GleanMetrics.Messaging
import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.ConsumeMessageToShow import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.ConsumeMessageToShow
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Evaluate import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Evaluate
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDismissed import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDismissed
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDisplayed
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Restore import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Restore
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessageToShow import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessageToShow
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessages import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessages
@ -47,6 +47,7 @@ class MessagingMiddleware(
val message = messagingStorage.getNextMessage(context.state.messaging.messages) val message = messagingStorage.getNextMessage(context.state.messaging.messages)
if (message != null) { if (message != null) {
context.dispatch(UpdateMessageToShow(message)) context.dispatch(UpdateMessageToShow(message))
onMessagedDisplayed(message, context)
} else { } else {
context.dispatch(ConsumeMessageToShow) context.dispatch(ConsumeMessageToShow)
} }
@ -56,8 +57,6 @@ class MessagingMiddleware(
is MessageDismissed -> onMessageDismissed(context, action.message) is MessageDismissed -> onMessageDismissed(context, action.message)
is MessageDisplayed -> onMessagedDisplayed(action.message, context)
else -> { else -> {
// no-op // no-op
} }
@ -70,6 +69,7 @@ class MessagingMiddleware(
oldMessage: Message, oldMessage: Message,
context: AppStoreMiddlewareContext context: AppStoreMiddlewareContext
) { ) {
sendShownMessageTelemetry(oldMessage.id)
val newMetadata = oldMessage.metadata.copy( val newMetadata = oldMessage.metadata.copy(
displayCount = oldMessage.metadata.displayCount + 1, displayCount = oldMessage.metadata.displayCount + 1,
lastTimeShown = now() lastTimeShown = now()
@ -80,6 +80,7 @@ class MessagingMiddleware(
val newMessages = if (newMetadata.displayCount < oldMessage.maxDisplayCount) { val newMessages = if (newMetadata.displayCount < oldMessage.maxDisplayCount) {
updateMessage(context, oldMessage, newMessage) updateMessage(context, oldMessage, newMessage)
} else { } else {
sendExpiredMessageTelemetry(newMessage.id)
consumeMessageToShowIfNeeded(context, oldMessage) consumeMessageToShowIfNeeded(context, oldMessage)
removeMessage(context, oldMessage) removeMessage(context, oldMessage)
} }
@ -89,6 +90,16 @@ class MessagingMiddleware(
} }
} }
@VisibleForTesting
internal fun sendShownMessageTelemetry(messageId: String) {
Messaging.messageShown.record(Messaging.MessageShownExtra(messageId))
}
@VisibleForTesting
internal fun sendExpiredMessageTelemetry(messageId: String) {
Messaging.messageExpired.record(Messaging.MessageExpiredExtra(messageId))
}
@VisibleForTesting @VisibleForTesting
internal fun onMessageDismissed( internal fun onMessageDismissed(
context: AppStoreMiddlewareContext, context: AppStoreMiddlewareContext,

View File

@ -188,11 +188,6 @@ interface SessionControlController {
*/ */
fun handleMessageClosed(message: Message) fun handleMessageClosed(message: Message)
/**
* @see [MessageCardInteractor.onMessageDisplayed]
*/
fun handleMessageDisplayed(message: Message)
/** /**
* @see [TabSessionInteractor.onPrivateModeButtonClicked] * @see [TabSessionInteractor.onPrivateModeButtonClicked]
*/ */
@ -619,10 +614,6 @@ class DefaultSessionControlController(
messageController.onMessageDismissed(message) messageController.onMessageDismissed(message)
} }
override fun handleMessageDisplayed(message: Message) {
messageController.onMessageDisplayed(message)
}
override fun handlePrivateModeButtonClicked( override fun handlePrivateModeButtonClicked(
newMode: BrowsingMode, newMode: BrowsingMode,
userHasBeenOnboarded: Boolean userHasBeenOnboarded: Boolean

View File

@ -239,11 +239,6 @@ interface MessageCardInteractor {
* Called when close button on a [Message] card. * Called when close button on a [Message] card.
*/ */
fun onMessageClosedClicked(message: Message) fun onMessageClosedClicked(message: Message)
/**
* Called when close button on a [Message] card.
*/
fun onMessageDisplayed(message: Message)
} }
/** /**
@ -470,8 +465,4 @@ class SessionControlInteractor(
override fun onMessageClosedClicked(message: Message) { override fun onMessageClosedClicked(message: Message) {
controller.handleMessageClosed(message) controller.handleMessageClosed(message)
} }
override fun onMessageDisplayed(message: Message) {
controller.handleMessageDisplayed(message)
}
} }

View File

@ -47,7 +47,6 @@ class MessageCardViewHolder(
interactor.onMessageClosedClicked(message) interactor.onMessageClosedClicked(message)
} }
} }
interactor.onMessageDisplayed(message)
} }
companion object { companion object {

View File

@ -24,7 +24,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDisplayed
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.nimbus.MessageData import org.mozilla.fenix.nimbus.MessageData
@ -103,28 +102,6 @@ class DefaultMessageControllerTest {
verify { store.dispatch(AppAction.MessagingAction.MessageDismissed(message)) } verify { store.dispatch(AppAction.MessagingAction.MessageDismissed(message)) }
} }
@Test
fun `WHEN calling onMessageDisplayed THEN report to the messageManager`() {
val data = MessageData()
val message = mockMessage(data)
assertNull(Messaging.messageExpired.testGetValue())
assertNull(Messaging.messageShown.testGetValue())
controller.onMessageDisplayed(message)
assertNotNull(Messaging.messageExpired.testGetValue())
val messageExpiredEvent = Messaging.messageExpired.testGetValue()!!
assertEquals(1, messageExpiredEvent.size)
assertEquals(message.id, messageExpiredEvent.single().extra!!["message_key"])
assertNotNull(Messaging.messageShown.testGetValue())
val event = Messaging.messageShown.testGetValue()!!
assertEquals(1, event.size)
assertEquals(message.id, event.single().extra!!["message_key"])
verify { store.dispatch(MessageDisplayed(message)) }
}
private fun mockMessage(data: MessageData = MessageData()) = Message( private fun mockMessage(data: MessageData = MessageData()) = Message(
id = "id", id = "id",
data = data, data = data,

View File

@ -28,7 +28,6 @@ import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.ConsumeMe
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Evaluate import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Evaluate
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageClicked
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDismissed import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDismissed
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.MessageDisplayed
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Restore import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.Restore
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessageToShow import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessageToShow
import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessages import org.mozilla.fenix.components.appstate.AppAction.MessagingAction.UpdateMessages
@ -143,7 +142,7 @@ class MessagingMiddlewareTest {
} }
@Test @Test
fun `WHEN MessageDisplayed THEN update storage`() = runTestOnMain { fun `GIEN a expiring message WHEN MessageDisplayed THEN update storage`() = runTestOnMain {
val message = Message( val message = Message(
"control-id", "control-id",
mockk(relaxed = true), mockk(relaxed = true),
@ -161,13 +160,11 @@ class MessagingMiddlewareTest {
every { appState.messaging } returns messagingState every { appState.messaging } returns messagingState
every { middlewareContext.state } returns appState every { middlewareContext.state } returns appState
spiedMiddleware.invoke( spiedMiddleware.onMessagedDisplayed(message, middlewareContext)
middlewareContext, {},
MessageDisplayed(message)
)
coVerify { messagingStorage.updateMetadata(message.metadata.copy(displayCount = 1)) } coVerify { messagingStorage.updateMetadata(message.metadata.copy(displayCount = 1)) }
verify { middlewareContext.dispatch(UpdateMessages(emptyList())) } verify { middlewareContext.dispatch(UpdateMessages(emptyList())) }
verify { spiedMiddleware.sendExpiredMessageTelemetry(message.id) }
} }
@Test @Test
@ -340,5 +337,6 @@ class MessagingMiddlewareTest {
verify { spiedMiddleware.removeMessage(middlewareContext, oldMessage) } verify { spiedMiddleware.removeMessage(middlewareContext, oldMessage) }
verify { middlewareContext.dispatch(UpdateMessages(emptyList())) } verify { middlewareContext.dispatch(UpdateMessages(emptyList())) }
coVerify { messagingStorage.updateMetadata(updatedMessage.metadata) } coVerify { messagingStorage.updateMetadata(updatedMessage.metadata) }
verify { spiedMiddleware.sendShownMessageTelemetry(oldMessage.id) }
} }
} }

View File

@ -1228,13 +1228,12 @@ class DefaultSessionControlControllerTest {
} }
@Test @Test
fun `WHEN handleMessageClicked,handleMessageClosed and handleMessageDisplayed are called THEN delegate to messageController`() { fun `WHEN handleMessageClicked and handleMessageClosed are called THEN delegate to messageController`() {
val controller = createController() val controller = createController()
val message = mockk<Message>() val message = mockk<Message>()
controller.handleMessageClicked(message) controller.handleMessageClicked(message)
controller.handleMessageClosed(message) controller.handleMessageClosed(message)
controller.handleMessageDisplayed(message)
verify { verify {
messageController.onMessagePressed(message) messageController.onMessagePressed(message)
@ -1242,9 +1241,6 @@ class DefaultSessionControlControllerTest {
verify { verify {
messageController.onMessageDismissed(message) messageController.onMessageDismissed(message)
} }
verify {
messageController.onMessageDisplayed(message)
}
} }
private fun createController( private fun createController(