From 53283ecb529515185e79105d3a78009efd29aec9 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Thu, 7 Nov 2019 16:27:39 +0000 Subject: [PATCH] Add CastPlayer tests for repeatMode masking PiperOrigin-RevId: 279091742 --- .../exoplayer2/ext/cast/CastPlayerTest.java | 79 +++++++++++++++++-- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java b/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java index b2aa0b7b16..ae081b1248 100644 --- a/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java +++ b/extensions/cast/src/test/java/com/google/android/exoplayer2/ext/cast/CastPlayerTest.java @@ -16,15 +16,20 @@ package com.google.android.exoplayer2.ext.cast; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.Player; +import com.google.android.gms.cast.MediaStatus; import com.google.android.gms.cast.framework.CastContext; import com.google.android.gms.cast.framework.CastSession; import com.google.android.gms.cast.framework.SessionManager; +import com.google.android.gms.cast.framework.media.MediaQueue; import com.google.android.gms.cast.framework.media.RemoteMediaClient; import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.ResultCallback; @@ -43,6 +48,8 @@ public class CastPlayerTest { private CastPlayer castPlayer; private RemoteMediaClient.Listener remoteMediaClientListener; @Mock private RemoteMediaClient mockRemoteMediaClient; + @Mock private MediaStatus mockMediaStatus; + @Mock private MediaQueue mockMediaQueue; @Mock private CastContext mockCastContext; @Mock private SessionManager mockSessionManager; @Mock private CastSession mockCastSession; @@ -61,8 +68,12 @@ public class CastPlayerTest { when(mockCastContext.getSessionManager()).thenReturn(mockSessionManager); when(mockSessionManager.getCurrentCastSession()).thenReturn(mockCastSession); when(mockCastSession.getRemoteMediaClient()).thenReturn(mockRemoteMediaClient); - // Make the remote media client be initially paused (most common scenario). + when(mockRemoteMediaClient.getMediaStatus()).thenReturn(mockMediaStatus); + when(mockRemoteMediaClient.getMediaQueue()).thenReturn(mockMediaQueue); + when(mockMediaQueue.getItemIds()).thenReturn(new int[0]); + // Make the remote media client present the same default values as ExoPlayer: when(mockRemoteMediaClient.isPaused()).thenReturn(true); + when(mockMediaStatus.getQueueRepeatMode()).thenReturn(MediaStatus.REPEAT_MODE_REPEAT_OFF); castPlayer = new CastPlayer(mockCastContext); castPlayer.addListener(mockListener); verify(mockRemoteMediaClient).addListener(listenerArgumentCaptor.capture()); @@ -70,9 +81,8 @@ public class CastPlayerTest { } @Test - public void testSetPlayWhenReady_masksLocalState() { + public void testSetPlayWhenReady_masksRemoteState() { when(mockRemoteMediaClient.play()).thenReturn(mockPendingResult); - // Initially paused. assertThat(castPlayer.getPlayWhenReady()).isFalse(); castPlayer.setPlayWhenReady(true); @@ -82,20 +92,19 @@ public class CastPlayerTest { // There is a status update in the middle, which should be hidden by masking. remoteMediaClientListener.onStatusUpdated(); - Mockito.verifyNoMoreInteractions(mockListener); + verifyNoMoreInteractions(mockListener); - // Upon result, the remoteMediaClient has updated it's state according to the play() call. + // Upon result, the remoteMediaClient has updated its state according to the play() call. when(mockRemoteMediaClient.isPaused()).thenReturn(false); setResultCallbackArgumentCaptor .getValue() .onResult(Mockito.mock(RemoteMediaClient.MediaChannelResult.class)); - Mockito.verifyNoMoreInteractions(mockListener); + verifyNoMoreInteractions(mockListener); } @Test public void testSetPlayWhenReadyMasking_updatesUponResultChange() { when(mockRemoteMediaClient.play()).thenReturn(mockPendingResult); - // Initially paused. assertThat(castPlayer.getPlayWhenReady()).isFalse(); castPlayer.setPlayWhenReady(true); @@ -103,7 +112,7 @@ public class CastPlayerTest { assertThat(castPlayer.getPlayWhenReady()).isTrue(); verify(mockListener).onPlayerStateChanged(true, Player.STATE_IDLE); - // Upon result, the remote media client is still paused. So the state should update. + // Upon result, the remote media client is still paused. The state should reflect that. setResultCallbackArgumentCaptor .getValue() .onResult(Mockito.mock(RemoteMediaClient.MediaChannelResult.class)); @@ -119,4 +128,58 @@ public class CastPlayerTest { verify(mockListener).onPlayerStateChanged(true, Player.STATE_IDLE); assertThat(castPlayer.getPlayWhenReady()).isTrue(); } + + @Test + public void testSetRepeatMode_masksRemoteState() { + when(mockRemoteMediaClient.queueSetRepeatMode(anyInt(), any())).thenReturn(mockPendingResult); + assertThat(castPlayer.getRepeatMode()).isEqualTo(Player.REPEAT_MODE_OFF); + + castPlayer.setRepeatMode(Player.REPEAT_MODE_ONE); + verify(mockPendingResult).setResultCallback(setResultCallbackArgumentCaptor.capture()); + assertThat(castPlayer.getRepeatMode()).isEqualTo(Player.REPEAT_MODE_ONE); + verify(mockListener).onRepeatModeChanged(Player.REPEAT_MODE_ONE); + + // There is a status update in the middle, which should be hidden by masking. + when(mockMediaStatus.getQueueRepeatMode()).thenReturn(MediaStatus.REPEAT_MODE_REPEAT_ALL); + remoteMediaClientListener.onStatusUpdated(); + verifyNoMoreInteractions(mockListener); + + // Upon result, the mediaStatus now exposes the new repeat mode. + when(mockMediaStatus.getQueueRepeatMode()).thenReturn(MediaStatus.REPEAT_MODE_REPEAT_SINGLE); + setResultCallbackArgumentCaptor + .getValue() + .onResult(Mockito.mock(RemoteMediaClient.MediaChannelResult.class)); + verifyNoMoreInteractions(mockListener); + } + + @Test + public void testSetRepeatMode_updatesUponResultChange() { + when(mockRemoteMediaClient.queueSetRepeatMode(anyInt(), any())).thenReturn(mockPendingResult); + + castPlayer.setRepeatMode(Player.REPEAT_MODE_ONE); + verify(mockPendingResult).setResultCallback(setResultCallbackArgumentCaptor.capture()); + assertThat(castPlayer.getRepeatMode()).isEqualTo(Player.REPEAT_MODE_ONE); + verify(mockListener).onRepeatModeChanged(Player.REPEAT_MODE_ONE); + + // There is a status update in the middle, which should be hidden by masking. + when(mockMediaStatus.getQueueRepeatMode()).thenReturn(MediaStatus.REPEAT_MODE_REPEAT_ALL); + remoteMediaClientListener.onStatusUpdated(); + verifyNoMoreInteractions(mockListener); + + // Upon result, the repeat mode is ALL. The state should reflect that. + setResultCallbackArgumentCaptor + .getValue() + .onResult(Mockito.mock(RemoteMediaClient.MediaChannelResult.class)); + verify(mockListener).onRepeatModeChanged(Player.REPEAT_MODE_ALL); + assertThat(castPlayer.getRepeatMode()).isEqualTo(Player.REPEAT_MODE_ALL); + } + + @Test + public void testRepeatMode_changesOnStatusUpdates() { + assertThat(castPlayer.getRepeatMode()).isEqualTo(Player.REPEAT_MODE_OFF); + when(mockMediaStatus.getQueueRepeatMode()).thenReturn(MediaStatus.REPEAT_MODE_REPEAT_SINGLE); + remoteMediaClientListener.onStatusUpdated(); + verify(mockListener).onRepeatModeChanged(Player.REPEAT_MODE_ONE); + assertThat(castPlayer.getRepeatMode()).isEqualTo(Player.REPEAT_MODE_ONE); + } }