[Refactor] increase unit test cases coverage (#359)

This commit is contained in:
Inderpal Singh Aulakh 2022-06-20 16:00:12 -07:00 коммит произвёл Mohtasim
Родитель 632a6c3fbe
Коммит 40e056fe3d
6 изменённых файлов: 854 добавлений и 23 удалений

Просмотреть файл

@ -8,13 +8,19 @@ import com.azure.android.communication.ui.calling.configuration.CallCompositeCon
import com.azure.android.communication.ui.calling.error.ErrorHandler
import com.azure.android.communication.ui.calling.handlers.RemoteParticipantHandler
import com.azure.android.communication.ui.calling.logger.DefaultLogger
import com.azure.android.communication.ui.calling.presentation.VideoStreamRendererFactory
import com.azure.android.communication.ui.calling.presentation.VideoViewManager
import com.azure.android.communication.ui.calling.presentation.manager.AccessibilityAnnouncementManager
import com.azure.android.communication.ui.calling.presentation.manager.AudioFocusManager
import com.azure.android.communication.ui.calling.presentation.manager.AudioSessionManager
import com.azure.android.communication.ui.calling.presentation.manager.AvatarViewManager
import com.azure.android.communication.ui.calling.presentation.manager.CameraStatusHook
import com.azure.android.communication.ui.calling.presentation.manager.LifecycleManagerImpl
import com.azure.android.communication.ui.calling.presentation.manager.MeetingJoinedHook
import com.azure.android.communication.ui.calling.presentation.manager.MicStatusHook
import com.azure.android.communication.ui.calling.presentation.manager.ParticipantAddedOrRemovedHook
import com.azure.android.communication.ui.calling.presentation.manager.PermissionManager
import com.azure.android.communication.ui.calling.presentation.manager.SwitchCameraStatusHook
import com.azure.android.communication.ui.calling.presentation.navigation.NavigationRouterImpl
import com.azure.android.communication.ui.calling.redux.AppStore
@ -65,7 +71,7 @@ internal class DependencyInjectionContainerImpl(
}
override val videoViewManager by lazy {
VideoViewManager(callingSDKWrapper, applicationContext)
VideoViewManager(callingSDKWrapper, applicationContext, VideoStreamRendererFactory())
}
override val permissionManager by lazy {
@ -97,7 +103,14 @@ internal class DependencyInjectionContainerImpl(
override val accessibilityManager by lazy {
AccessibilityAnnouncementManager(
appStore
appStore,
listOf(
MeetingJoinedHook(),
CameraStatusHook(),
ParticipantAddedOrRemovedHook(),
MicStatusHook(),
SwitchCameraStatusHook(),
)
)
}

Просмотреть файл

@ -7,6 +7,7 @@ import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.azure.android.communication.calling.RemoteVideoStream
import com.azure.android.communication.calling.LocalVideoStream
import com.azure.android.communication.calling.VideoStreamRenderer
import com.azure.android.communication.calling.VideoStreamRendererView
import com.azure.android.communication.calling.MediaStreamType
@ -17,6 +18,7 @@ import com.azure.android.communication.ui.calling.service.sdk.CallingSDKWrapper
internal class VideoViewManager(
private val callingSDKWrapper: CallingSDKWrapper,
private val context: Context,
private val videoStreamRendererFactory: VideoStreamRendererFactory,
) {
private val remoteParticipantVideoRendererMap: HashMap<String, VideoRenderer> = HashMap()
private val localParticipantVideoRendererMap: HashMap<String, VideoRenderer> = HashMap()
@ -60,7 +62,10 @@ internal class VideoViewManager(
if (!localParticipantVideoRendererMap.containsKey(videoStreamID)) {
val videoStream = callingSDKWrapper.getLocalVideoStream().get()
val videoStreamRenderer =
VideoStreamRenderer(videoStream, context)
videoStreamRendererFactory.getLocalParticipantVideoStreamRenderer(
videoStream,
context
)
val rendererView = videoStreamRenderer.createView()
localParticipantVideoRendererMap[videoStreamID] =
VideoRenderer(rendererView, videoStreamRenderer, videoStreamID, false)
@ -123,14 +128,19 @@ internal class VideoViewManager(
if (stream != null) {
val isScreenShare = stream!!.mediaStreamType == MediaStreamType.SCREEN_SHARING
val videoStreamRenderer = VideoStreamRenderer(stream, context)
val viewOption =
if (isScreenShare) CreateViewOptions(ScalingMode.FIT) else CreateViewOptions(
ScalingMode.CROP
val videoStreamRenderer =
videoStreamRendererFactory.getRemoteParticipantVideoStreamRenderer(
stream,
context
)
val rendererView = videoStreamRenderer.createView(viewOption)
val rendererView =
if (isScreenShare) videoStreamRenderer.createView(
CreateViewOptions(
ScalingMode.FIT
)
) else videoStreamRenderer.createView()
remoteParticipantVideoRendererMap[uniqueID] =
VideoRenderer(
rendererView,
@ -198,3 +208,15 @@ internal class VideoViewManager(
}
}
}
internal class VideoStreamRendererFactory {
fun getRemoteParticipantVideoStreamRenderer(
stream: RemoteVideoStream?,
context: Context,
) = VideoStreamRenderer(stream, context)
fun getLocalParticipantVideoStreamRenderer(
stream: LocalVideoStream?,
context: Context,
) = VideoStreamRenderer(stream, context)
}

Просмотреть файл

@ -21,8 +21,8 @@ import kotlinx.coroutines.flow.collect
// These hooks make announcements based on Redux State changes
internal class AccessibilityAnnouncementManager(
private val store: Store<ReduxState>,
private val accessibilityHooks: List<AccessibilityHook>
) {
private lateinit var lastState: ReduxState
suspend fun start(activity: Activity) {
@ -52,7 +52,6 @@ internal class AccessibilityAnnouncementManager(
}
// Accessibility Hook
//
// shouldTrigger -> detect if we should announce something
// message -> get the text tp read
internal abstract class AccessibilityHook {
@ -60,9 +59,8 @@ internal abstract class AccessibilityHook {
abstract fun message(lastState: ReduxState, newState: ReduxState, context: Context): String
}
// Hook to announce when participants join/leave a meeting
internal class ParticipantAddedOrRemovedHook : AccessibilityHook() {
var callJoinTime = System.currentTimeMillis()
private var callJoinTime = System.currentTimeMillis()
override fun shouldTrigger(lastState: ReduxState, newState: ReduxState): Boolean {
if (lastState.callState.callingStatus != CallingStatus.CONNECTED && newState.callState.callingStatus == CallingStatus.CONNECTED) {
callJoinTime = System.currentTimeMillis()
@ -94,7 +92,6 @@ internal class ParticipantAddedOrRemovedHook : AccessibilityHook() {
}
}
// Hook to announce the meeting was successfully joined
internal class MeetingJoinedHook : AccessibilityHook() {
override fun shouldTrigger(lastState: ReduxState, newState: ReduxState) =
(lastState.callState.callingStatus != CallingStatus.CONNECTED && newState.callState.callingStatus == CallingStatus.CONNECTED)
@ -141,12 +138,3 @@ internal class CameraStatusHook : AccessibilityHook() {
}
}
}
// List of all hooks
internal val accessibilityHooks = listOf(
MeetingJoinedHook(),
CameraStatusHook(),
ParticipantAddedOrRemovedHook(),
MicStatusHook(),
SwitchCameraStatusHook(),
)

Просмотреть файл

@ -0,0 +1,211 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.android.communication.ui.presentation
import android.content.Context
import com.azure.android.communication.calling.LocalVideoStream
import com.azure.android.communication.calling.RemoteParticipant
import com.azure.android.communication.calling.RemoteVideoStream
import com.azure.android.communication.calling.VideoStreamRenderer
import com.azure.android.communication.calling.VideoStreamRendererView
import com.azure.android.communication.calling.MediaStreamType
import com.azure.android.communication.ui.calling.presentation.VideoStreamRendererFactory
import com.azure.android.communication.ui.calling.presentation.VideoViewManager
import com.azure.android.communication.ui.calling.service.sdk.CallingSDKWrapper
import java9.util.concurrent.CompletableFuture
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.mock
@RunWith(MockitoJUnitRunner::class)
internal class VideoViewManagerUnitTest {
@Test
fun videoViewManager_destroy_then_clearLocalAndRemoteParticipantVideoRendererMap() {
// arrange
val mockVideoStream = mock<RemoteVideoStream> {
on { id } doAnswer { 111 }
on { mediaStreamType } doAnswer { MediaStreamType.VIDEO }
}
val mockRemoteParticipant = mock<RemoteParticipant> {
on { videoStreams } doAnswer { listOf(mockVideoStream) }
}
val remoteParticipantMap: MutableMap<String, RemoteParticipant> = mutableMapOf()
remoteParticipantMap["user"] = mockRemoteParticipant
val mockLocalVideoStream = mock<LocalVideoStream> { }
val localVideoStreamCompletableFuture =
CompletableFuture<LocalVideoStream>()
localVideoStreamCompletableFuture.complete(mockLocalVideoStream)
val mockCallingSDKWrapper = mock<CallingSDKWrapper> {
on { getRemoteParticipantsMap() } doAnswer { remoteParticipantMap }
on { getLocalVideoStream() } doAnswer { localVideoStreamCompletableFuture }
}
val mockContext = mock<Context> {}
val mockVideoStreamRendererView = mock<VideoStreamRendererView> {}
val mockVideoStreamRenderer = mock<VideoStreamRenderer> {
on { createView() } doAnswer { mockVideoStreamRendererView }
}
val mockVideoStreamRendererHelper = mock<VideoStreamRendererFactory> {
on {
getRemoteParticipantVideoStreamRenderer(
any(),
any()
)
} doAnswer { mockVideoStreamRenderer }
on {
getLocalParticipantVideoStreamRenderer(
any(),
any()
)
} doAnswer { mockVideoStreamRenderer }
}
val videoViewManager =
VideoViewManager(mockCallingSDKWrapper, mockContext, mockVideoStreamRendererHelper)
val remoteVideoView =
videoViewManager.getRemoteVideoStreamRenderer("user", "111")
videoViewManager.updateLocalVideoRenderer("345")
val localVideoView = videoViewManager.getLocalVideoRenderer("345")
// act
videoViewManager.destroy()
remoteParticipantMap.clear()
val remoteVideoViewAfterDelete =
videoViewManager.getRemoteVideoStreamRenderer("user", "111")
val localVideoViewAfterDelete = videoViewManager.getLocalVideoRenderer("345")
// assert
Assert.assertNotNull(remoteVideoView)
Assert.assertNotNull(localVideoView)
Assert.assertEquals(remoteVideoViewAfterDelete, null)
Assert.assertEquals(localVideoViewAfterDelete, null)
}
@Test
fun videoViewManager_updateLocalVideoRenderer_when_calledWithValidID_then_insertLocalVideoViewInMap() {
// arrange
val mockLocalVideoStream = mock<LocalVideoStream> { }
val localVideoStreamCompletableFuture =
CompletableFuture<LocalVideoStream>()
localVideoStreamCompletableFuture.complete(mockLocalVideoStream)
val mockCallingSDKWrapper = mock<CallingSDKWrapper> {
on { getLocalVideoStream() } doAnswer { localVideoStreamCompletableFuture }
}
val mockContext = mock<Context> {}
val mockVideoStreamRendererView = mock<VideoStreamRendererView> {}
val mockVideoStreamRenderer = mock<VideoStreamRenderer> {
on { createView() } doAnswer { mockVideoStreamRendererView }
}
val mockVideoStreamRendererHelper = mock<VideoStreamRendererFactory> {
on {
getLocalParticipantVideoStreamRenderer(
any(),
any()
)
} doAnswer { mockVideoStreamRenderer }
}
val videoViewManager =
VideoViewManager(mockCallingSDKWrapper, mockContext, mockVideoStreamRendererHelper)
// act
videoViewManager.updateLocalVideoRenderer("345")
val localVideoView = videoViewManager.getLocalVideoRenderer("345")
// assert
Assert.assertEquals(localVideoView, mockVideoStreamRendererView)
}
@Test
fun videoViewManager_getRemoteVideoStreamRenderer_when_calledWithValidIDs_then_returnView() {
// arrange
val mockVideoStream = mock<RemoteVideoStream> {
on { id } doAnswer { 111 }
on { mediaStreamType } doAnswer { MediaStreamType.VIDEO }
}
val mockRemoteParticipant = mock<RemoteParticipant> {
on { videoStreams } doAnswer { listOf(mockVideoStream) }
}
val remoteParticipantMap: MutableMap<String, RemoteParticipant> = mutableMapOf()
remoteParticipantMap["user"] = mockRemoteParticipant
val mockCallingSDKWrapper = mock<CallingSDKWrapper> {
on { getRemoteParticipantsMap() } doAnswer { remoteParticipantMap }
}
val mockContext = mock<Context> {}
val mockVideoStreamRendererView = mock<VideoStreamRendererView> {}
val mockVideoStreamRenderer = mock<VideoStreamRenderer> {
on { createView() } doAnswer { mockVideoStreamRendererView }
}
val mockVideoStreamRendererHelper = mock<VideoStreamRendererFactory> {
on {
getRemoteParticipantVideoStreamRenderer(
any(),
any()
)
} doAnswer { mockVideoStreamRenderer }
}
val videoViewManager =
VideoViewManager(mockCallingSDKWrapper, mockContext, mockVideoStreamRendererHelper)
// act
val remoteVideoView =
videoViewManager.getRemoteVideoStreamRenderer("user", "111")
// assert
Assert.assertEquals(remoteVideoView, mockVideoStreamRendererView)
}
@Test
fun videoViewManager_getRemoteVideoStreamRenderer_when_calledWithInValidIDs_then_returnNullView() {
// arrange
val mockRemoteParticipant = mock<RemoteParticipant> {}
val remoteParticipantMap: MutableMap<String, RemoteParticipant> = mutableMapOf()
remoteParticipantMap["user"] = mockRemoteParticipant
val mockCallingSDKWrapper = mock<CallingSDKWrapper> {
on { getRemoteParticipantsMap() } doAnswer { remoteParticipantMap }
}
val mockContext = mock<Context> {}
val mockVideoStreamRendererHelper = mock<VideoStreamRendererFactory> {}
val videoViewManager =
VideoViewManager(mockCallingSDKWrapper, mockContext, mockVideoStreamRendererHelper)
// act
val remoteVideoView =
videoViewManager.getRemoteVideoStreamRenderer("user1", "111")
// assert
Assert.assertEquals(remoteVideoView, null)
}
}

Просмотреть файл

@ -0,0 +1,538 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.android.communication.ui.presentation.manager
import android.content.Context
import com.azure.android.communication.ui.ACSBaseTestCoroutine
import com.azure.android.communication.ui.R
import com.azure.android.communication.ui.calling.presentation.manager.CameraStatusHook
import com.azure.android.communication.ui.calling.presentation.manager.MeetingJoinedHook
import com.azure.android.communication.ui.calling.presentation.manager.MicStatusHook
import com.azure.android.communication.ui.calling.presentation.manager.ParticipantAddedOrRemovedHook
import com.azure.android.communication.ui.calling.presentation.manager.SwitchCameraStatusHook
import com.azure.android.communication.ui.calling.redux.state.AppReduxState
import com.azure.android.communication.ui.calling.redux.state.AudioDeviceSelectionStatus
import com.azure.android.communication.ui.calling.redux.state.AudioOperationalStatus
import com.azure.android.communication.ui.calling.redux.state.AudioState
import com.azure.android.communication.ui.calling.redux.state.BluetoothState
import com.azure.android.communication.ui.calling.redux.state.CallingState
import com.azure.android.communication.ui.calling.redux.state.CallingStatus
import com.azure.android.communication.ui.calling.redux.state.CameraDeviceSelectionStatus
import com.azure.android.communication.ui.calling.redux.state.CameraOperationalStatus
import com.azure.android.communication.ui.calling.redux.state.LocalUserState
import com.azure.android.communication.ui.calling.redux.state.CameraState
import com.azure.android.communication.ui.calling.redux.state.CameraTransmissionStatus
import com.azure.android.communication.ui.calling.redux.state.RemoteParticipantsState
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.mock
@RunWith(MockitoJUnitRunner::class)
internal class AccessibilityAnnouncementManagerUnitTests : ACSBaseTestCoroutine() {
@Test
fun cameraStatusHook_message_reduxStateOn_then_returnVideoOn() {
// Arrange
val reduxState = AppReduxState("")
val cameraStatusHook = CameraStatusHook()
val mockContext = mock<Context> {
on { getString(R.string.azure_communication_ui_calling_setup_view_button_video_on) } doAnswer { "Video on" }
}
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState = LocalUserState(
CameraState(
CameraOperationalStatus.ON,
CameraDeviceSelectionStatus.BACK,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val message = cameraStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "Video on")
}
@Test
fun cameraStatusHook_message_reduxStateOff_then_returnVideoOff() {
// Arrange
val reduxState = AppReduxState("")
val cameraStatusHook = CameraStatusHook()
val mockContext = mock<Context> {
on { getString(R.string.azure_communication_ui_calling_setup_view_button_video_off) } doAnswer { "Video off" }
}
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState = LocalUserState(
CameraState(
CameraOperationalStatus.OFF,
CameraDeviceSelectionStatus.BACK,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val message = cameraStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "Video off")
}
@Test
fun cameraStatusHook_message_reduxStateOthers_then_returnEmpty() {
// Arrange
val reduxState = AppReduxState("")
val cameraStatusHook = CameraStatusHook()
val mockContext = mock<Context> { }
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState =
LocalUserState(
CameraState(
CameraOperationalStatus.PAUSED,
CameraDeviceSelectionStatus.BACK,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val message = cameraStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "")
}
@Test
fun cameraStatusHook_shouldTrigger_reduxStateDiffer_then_returnTrue() {
// Arrange
val reduxState = AppReduxState("")
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState =
LocalUserState(
CameraState(
CameraOperationalStatus.PAUSED,
CameraDeviceSelectionStatus.BACK,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
val cameraStatusHook = CameraStatusHook()
// Act
val result = cameraStatusHook.shouldTrigger(AppReduxState(""), reduxState)
// Assert
Assert.assertEquals(result, true)
}
@Test
fun cameraStatusHook_shouldTrigger_reduxStateSame_then_returnFalse() {
// Arrange
val reduxState = AppReduxState("")
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState =
LocalUserState(
CameraState(
CameraOperationalStatus.PAUSED,
CameraDeviceSelectionStatus.BACK,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
val cameraStatusHook = CameraStatusHook()
// Act
val result = cameraStatusHook.shouldTrigger(reduxState, reduxState)
// Assert
Assert.assertEquals(result, false)
}
@Test
fun micStatusHook_message_reduxStateOn_then_returnMicOn() {
// Arrange
val reduxState = AppReduxState("")
val micStatusHook = MicStatusHook()
val mockContext = mock<Context> {
on { getString(R.string.azure_communication_ui_calling_setup_view_button_mic_on) } doAnswer { "Mic on" }
}
reduxState.localParticipantState = LocalUserState(
mock {},
AudioState(
AudioOperationalStatus.ON,
AudioDeviceSelectionStatus.BLUETOOTH_SCO_REQUESTED,
BluetoothState(true, "")
),
"",
""
)
// Act
val message = micStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "Mic on")
}
@Test
fun micStatusHook_message_reduxStateOff_then_returnVideoOff() {
// Arrange
val reduxState = AppReduxState("")
val micStatusHook = MicStatusHook()
val mockContext = mock<Context> {
on { getString(R.string.azure_communication_ui_calling_setup_view_button_mic_off) } doAnswer { "Mic off" }
}
reduxState.localParticipantState = LocalUserState(
mock {},
AudioState(
AudioOperationalStatus.OFF,
AudioDeviceSelectionStatus.BLUETOOTH_SCO_REQUESTED,
BluetoothState(true, "")
),
"",
""
)
// Act
val message = micStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "Mic off")
}
@Test
fun micStatusHook_message_reduxStateOthers_then_returnEmpty() {
// Arrange
val reduxState = AppReduxState("")
val micStatusHook = MicStatusHook()
val mockContext = mock<Context> { }
reduxState.localParticipantState = LocalUserState(
mock {},
AudioState(
AudioOperationalStatus.PENDING,
AudioDeviceSelectionStatus.BLUETOOTH_SCO_REQUESTED,
BluetoothState(true, "")
),
"",
""
)
// Act
val message = micStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "")
}
@Test
fun micStatusHook_shouldTrigger_reduxStateDiffer_then_returnTrue() {
// Arrange
val reduxState = AppReduxState("")
val micStatusHook = MicStatusHook()
reduxState.localParticipantState = LocalUserState(
mock {},
AudioState(
AudioOperationalStatus.PENDING,
AudioDeviceSelectionStatus.BLUETOOTH_SCO_REQUESTED,
BluetoothState(true, "")
),
"",
""
)
// Act
val result = micStatusHook.shouldTrigger(AppReduxState(""), reduxState)
// Assert
Assert.assertEquals(result, true)
}
@Test
fun micStatusHook_shouldTrigger_reduxStateSame_then_returnFalse() {
// Arrange
val reduxState = AppReduxState("")
val micStatusHook = MicStatusHook()
reduxState.localParticipantState = LocalUserState(
mock {},
AudioState(
AudioOperationalStatus.PENDING,
AudioDeviceSelectionStatus.BLUETOOTH_SCO_REQUESTED,
BluetoothState(true, "")
),
"",
""
)
// Act
val result = micStatusHook.shouldTrigger(reduxState, reduxState)
// Assert
Assert.assertEquals(result, false)
}
@Test
fun switchCameraStatusHook_message_reduxStateFront_then_returnFrontCamera() {
// Arrange
val reduxState = AppReduxState("")
val switchCameraStatusHook = SwitchCameraStatusHook()
val mockContext = mock<Context> {
on { getString(R.string.azure_communication_ui_calling_switch_camera_button_front) } doAnswer { "Switch to Front Camera" }
}
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState = LocalUserState(
CameraState(
CameraOperationalStatus.ON,
CameraDeviceSelectionStatus.FRONT,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val message = switchCameraStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "Switch to Front Camera")
}
@Test
fun switchCameraStatusHook_message_reduxStateBack_then_returnBackCamera() {
// Arrange
val reduxState = AppReduxState("")
val switchCameraStatusHook = SwitchCameraStatusHook()
val mockContext = mock<Context> {
on { getString(R.string.azure_communication_ui_calling_switch_camera_button_back) } doAnswer { "Switch to Back Camera" }
}
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState = LocalUserState(
CameraState(
CameraOperationalStatus.ON,
CameraDeviceSelectionStatus.BACK,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val message = switchCameraStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "Switch to Back Camera")
}
@Test
fun switchCameraStatusHook_message_reduxStateOthers_then_returnEmpty() {
// Arrange
val reduxState = AppReduxState("")
val switchCameraStatusHook = SwitchCameraStatusHook()
val mockContext = mock<Context> { }
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState = LocalUserState(
CameraState(
CameraOperationalStatus.ON,
CameraDeviceSelectionStatus.SWITCHING,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val message = switchCameraStatusHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "")
}
@Test
fun switchCameraStatusHook_shouldTrigger_reduxStateSame_then_returnFalse() {
// Arrange
val reduxState = AppReduxState("")
val switchCameraStatusHook = SwitchCameraStatusHook()
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState = LocalUserState(
CameraState(
CameraOperationalStatus.ON,
CameraDeviceSelectionStatus.SWITCHING,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val result = switchCameraStatusHook.shouldTrigger(reduxState, reduxState)
// Assert
Assert.assertEquals(result, false)
}
@Test
fun switchCameraStatusHook_shouldTrigger_reduxStateDiffer_then_returnTrue() {
// Arrange
val reduxState = AppReduxState("")
val switchCameraStatusHook = SwitchCameraStatusHook()
val mockAudioState = mock<AudioState> {}
reduxState.localParticipantState = LocalUserState(
CameraState(
CameraOperationalStatus.ON,
CameraDeviceSelectionStatus.SWITCHING,
CameraTransmissionStatus.LOCAL
),
mockAudioState, "", ""
)
// Act
val result = switchCameraStatusHook.shouldTrigger(AppReduxState(""), reduxState)
// Assert
Assert.assertEquals(result, true)
}
@Test
fun meetingJoinedHook_shouldTrigger_reduxStateDiffer_then_returnTrue() {
// Arrange
val reduxState = AppReduxState("")
val meetingJoinedHook = MeetingJoinedHook()
reduxState.callState = CallingState(CallingStatus.CONNECTED)
// Act
val result = meetingJoinedHook.shouldTrigger(AppReduxState(""), reduxState)
// Assert
Assert.assertEquals(result, true)
}
@Test
fun meetingJoinedHook_shouldTrigger_reduxStateSame_then_returnFalse() {
// Arrange
val reduxState = AppReduxState("")
val meetingJoinedHook = MeetingJoinedHook()
reduxState.callState = CallingState(CallingStatus.CONNECTED)
// Act
val result = meetingJoinedHook.shouldTrigger(reduxState, reduxState)
// Assert
Assert.assertEquals(result, false)
}
@Test
fun meetingJoinedHook_message_reduxStateAny_then_returnJoined() {
// Arrange
val reduxState = AppReduxState("")
val meetingJoinedHook = MeetingJoinedHook()
val mockContext = mock<Context> {
on { getString(R.string.azure_communication_ui_calling_accessibility_meeting_connected) } doAnswer { "You have joined the call" }
}
reduxState.callState = CallingState(CallingStatus.CONNECTED)
// Act
val message = meetingJoinedHook.message(reduxState, reduxState, mockContext)
// Assert
Assert.assertEquals(message, "You have joined the call")
}
@Test
fun participantAddedOrRemovedHook_shouldTrigger_reduxStateDiffer_then_returnTrue() {
// Arrange
val reduxState = AppReduxState("")
val meetingJoinedHook = MeetingJoinedHook()
reduxState.callState = CallingState(CallingStatus.CONNECTED)
reduxState.remoteParticipantState =
RemoteParticipantsState(mapOf(Pair("a", mock { })), 5000)
// Act
val result = meetingJoinedHook.shouldTrigger(AppReduxState(""), reduxState)
// Assert
Assert.assertEquals(result, true)
}
@Test
fun participantAddedOrRemovedHook_shouldTrigger_reduxStateSame_then_returnFalse() {
// Arrange
val reduxState = AppReduxState("")
val meetingJoinedHook = MeetingJoinedHook()
reduxState.callState = CallingState(CallingStatus.CONNECTED)
reduxState.remoteParticipantState =
RemoteParticipantsState(mapOf(Pair("a", mock { })), 5000)
// Act
val result = meetingJoinedHook.shouldTrigger(reduxState, reduxState)
// Assert
Assert.assertEquals(result, false)
}
@Test
fun participantAddedOrRemovedHook_message_reduxStateHasParticipants_then_returnJoinedMessage() {
// Arrange
val reduxState = AppReduxState("")
val participantAddedOrRemovedHook = ParticipantAddedOrRemovedHook()
val mockContext = mock<Context> {
on {
getString(
R.string.azure_communication_ui_calling_accessibility_user_added,
"user"
)
} doAnswer { "user has joined the meeting" }
}
reduxState.callState = CallingState(CallingStatus.CONNECTED)
reduxState.remoteParticipantState = RemoteParticipantsState(
mapOf(
Pair(
"a",
mock {
on { displayName } doAnswer { "user" }
}
)
),
5000
)
// Act
val message =
participantAddedOrRemovedHook.message(AppReduxState(""), reduxState, mockContext)
// Assert
Assert.assertEquals(message, "user has joined the meeting")
}
@Test
fun participantAddedOrRemovedHook_message_reduxStateHasRemovedParticipants_then_returnLeftMessage() {
// Arrange
val reduxState = AppReduxState("")
val participantAddedOrRemovedHook = ParticipantAddedOrRemovedHook()
val mockContext = mock<Context> {
on {
getString(
R.string.azure_communication_ui_calling_accessibility_user_left,
"user"
)
} doAnswer { "user has left the meeting" }
}
reduxState.callState = CallingState(CallingStatus.CONNECTED)
reduxState.remoteParticipantState = RemoteParticipantsState(
mapOf(
Pair(
"a",
mock {
on { displayName } doAnswer { "user" }
}
)
),
5000
)
// Act
val message =
participantAddedOrRemovedHook.message(reduxState, AppReduxState(""), mockContext)
// Assert
Assert.assertEquals(message, "user has left the meeting")
}
}

Просмотреть файл

@ -0,0 +1,59 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.android.communication.ui.presentation.manager
import com.azure.android.communication.ui.calling.presentation.manager.LifecycleManagerImpl
import com.azure.android.communication.ui.calling.redux.AppStore
import com.azure.android.communication.ui.calling.redux.action.LifecycleAction
import com.azure.android.communication.ui.calling.redux.state.ReduxState
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.any
import org.mockito.kotlin.argThat
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@RunWith(MockitoJUnitRunner::class)
internal class LifeCycleManagerUnitTests {
@Test
fun lifecycleManager_pause_then_sendEnterBackgroundTriggered() {
// Arrange
val mockAppStore = mock<AppStore<ReduxState>> {
on { dispatch(any()) } doAnswer { }
}
val lifecycleManagerImpl = LifecycleManagerImpl(mockAppStore)
// Act
lifecycleManagerImpl.pause()
// Assert
verify(mockAppStore, times(1)).dispatch(
argThat { action ->
action is LifecycleAction.EnterBackgroundTriggered
}
)
}
@Test
fun lifecycleManager_resume_then_sendEnterForegroundTriggered() {
// Arrange
val mockAppStore = mock<AppStore<ReduxState>> {
on { dispatch(any()) } doAnswer { }
}
val lifecycleManagerImpl = LifecycleManagerImpl(mockAppStore)
// Act
lifecycleManagerImpl.resume()
// Assert
verify(mockAppStore, times(1)).dispatch(
argThat { action ->
action is LifecycleAction.EnterForegroundTriggered
}
)
}
}