@@ -6,6 +6,7 @@ import android.media.AudioManager
66import android.net.Uri
77import android.util.Log
88import androidx.core.content.ContextCompat
9+ import androidx.media3.common.MediaItem
910import androidx.media3.common.Player
1011import io.mockk.every
1112import io.mockk.mockk
@@ -20,6 +21,8 @@ import kotlinx.coroutines.test.resetMain
2021import kotlinx.coroutines.test.setMain
2122import net.newpipe.newplayer.NewPlayer
2223import net.newpipe.newplayer.data.PlayMode
24+ import net.newpipe.newplayer.data.RepeatMode
25+ import net.newpipe.newplayer.ui.ContentScale
2326import org.junit.Assert.assertEquals
2427import org.junit.Assert.assertFalse
2528import org.junit.Assert.assertTrue
@@ -42,9 +45,17 @@ class NewPlayerViewModelImpltest {
4245
4346 every { Uri .parse(any()) } returns mockk<Uri >(relaxed = true )
4447 every { Log .i(any(), any()) } returns 1
48+ every { Log .d(any(), any()) } returns 1
49+ every { mockAudioManager.getStreamVolume(any()) } returns 0
50+ every { mockAudioManager.getStreamMaxVolume(any()) } returns 1
4551 every { ContextCompat .getSystemService(any(), AudioManager ::class .java) } returns mockAudioManager
4652 every { mockApp.applicationContext } returns mockk<Context >(relaxed = true )
4753 every { mockNewPlayer.playBackMode } returns MutableStateFlow (PlayMode .IDLE )
54+ every { mockNewPlayer.playlist } returns MutableStateFlow (listOf (
55+ mockk<MediaItem >(),
56+ mockk<MediaItem >(),
57+ mockk<MediaItem >()
58+ ))
4859 every { mockNewPlayer.exoPlayer } returns mockExoPlayer
4960 every { mockExoPlayer.value?.isPlaying } returns false
5061 every { mockExoPlayer.value?.isLoading } returns false
@@ -109,21 +120,57 @@ class NewPlayerViewModelImpltest {
109120 verify (exactly = 0 ) { mockNewPlayer.currentlyPlayingPlaylistItem = any() }
110121 }
111122
123+ @Test
124+ fun changeUiMode_pipFromAudioMode () {
125+ playerViewModel.changeUiMode(UIModeState .EMBEDDED_AUDIO , null )
126+ playerViewModel.changeUiMode(UIModeState .PIP , null )
127+ assertEquals(UIModeState .EMBEDDED_VIDEO , playerViewModel.uiState.value.uiMode)
128+ assertTrue(playerViewModel.uiState.value.enteringPip)
129+ }
130+
131+ @Test
132+ fun changeUiMode_pipFromVideoControllerUiVisible () {
133+ playerViewModel.changeUiMode(UIModeState .FULLSCREEN_VIDEO_CONTROLLER_UI , null )
134+ playerViewModel.changeUiMode(UIModeState .PIP , null )
135+ assertEquals(UIModeState .FULLSCREEN_VIDEO , playerViewModel.uiState.value.uiMode)
136+ assertTrue(playerViewModel.uiState.value.enteringPip)
137+ }
138+
139+ @Test
140+ fun changeUiMode_pip () {
141+ playerViewModel.changeUiMode(UIModeState .EMBEDDED_VIDEO , null )
142+ playerViewModel.changeUiMode(UIModeState .PIP , null )
143+ assertEquals(UIModeState .EMBEDDED_VIDEO , playerViewModel.uiState.value.uiMode)
144+ assertTrue(playerViewModel.uiState.value.enteringPip)
145+ }
146+
147+ @Test
148+ fun changeUiMode_notFullscreenFromFullscreen () {
149+ val embeddedUiConfig = EmbeddedUiConfig (true , 0.2f , 1 )
150+ playerViewModel.changeUiMode(UIModeState .FULLSCREEN_VIDEO , embeddedUiConfig)
151+ playerViewModel.changeUiMode(UIModeState .EMBEDDED_VIDEO , null )
152+ assertEquals(UIModeState .EMBEDDED_VIDEO , playerViewModel.uiState.value.uiMode)
153+ assertEquals(embeddedUiConfig, playerViewModel.uiState.value.embeddedUiConfig)
154+ }
155+
156+ @Test
157+ fun changeUiMode_fromPipToFullscreenVideo () {
158+ playerViewModel.changeUiMode(UIModeState .PIP , null )
159+ playerViewModel.changeUiMode(UIModeState .FULLSCREEN_VIDEO , null )
160+ assertEquals(UIModeState .FULLSCREEN_VIDEO , playerViewModel.uiState.value.uiMode)
161+ }
162+
112163 @Test
113164 fun changeUiMode_keepsSamePlayBackModeValue () {
114165 mockNewPlayer.playBackMode.value = PlayMode .EMBEDDED_VIDEO
115- val newUiModeState = UIModeState .EMBEDDED_VIDEO
116- val embeddedUiConfig = EmbeddedUiConfig (true , 0.6f , 1 )
117- playerViewModel.changeUiMode(newUiModeState, embeddedUiConfig)
166+ playerViewModel.changeUiMode(UIModeState .EMBEDDED_VIDEO , null )
118167 assertEquals(PlayMode .EMBEDDED_VIDEO , mockNewPlayer.playBackMode.value)
119168 }
120169
121170 @Test
122171 fun changeUiMode_updatesPlayBackModeValue () {
123172 mockNewPlayer.playBackMode.value = PlayMode .IDLE
124- val newUiModeState = UIModeState .FULLSCREEN_VIDEO
125- val embeddedUiConfig = EmbeddedUiConfig (true , 0.6f , 1 )
126- playerViewModel.changeUiMode(newUiModeState, embeddedUiConfig)
173+ playerViewModel.changeUiMode(UIModeState .FULLSCREEN_VIDEO , null )
127174 assertEquals(PlayMode .FULLSCREEN_VIDEO , mockNewPlayer.playBackMode.value)
128175 }
129176
@@ -152,4 +199,169 @@ class NewPlayerViewModelImpltest {
152199 verify (exactly = 1 ) { mockNewPlayer.currentPosition = 3136L }
153200 assertFalse(playerViewModel.uiState.value.seekPreviewVisible)
154201 }
202+
203+ @Test
204+ fun fastSeek () {
205+ every { mockNewPlayer.fastSeekAmountSec } returns 24
206+ every { mockNewPlayer.currentPosition } returns 10
207+
208+ playerViewModel.fastSeek(1 )
209+
210+ assertEquals(24 , playerViewModel.uiState.value.fastSeekSeconds)
211+ verify (exactly = 1 ) { mockNewPlayer.currentPosition = 24010 }
212+ }
213+
214+ @Test
215+ fun finishFastSeek () {
216+ every { mockNewPlayer.fastSeekAmountSec } returns 24
217+ // set an initial value for fastSeekSeconds
218+ playerViewModel.fastSeek(1 )
219+
220+ playerViewModel.finishFastSeek()
221+
222+ assertEquals(0 , playerViewModel.uiState.value.fastSeekSeconds)
223+ }
224+
225+ @Test
226+ fun brightnessChange_updatesBrightnessValueOnFullscreen () {
227+ playerViewModel.changeUiMode(UIModeState .FULLSCREEN_VIDEO , null )
228+ playerViewModel.brightnessChange(0.5f , 0.1f )
229+ assertEquals(0.75f , playerViewModel.uiState.value.brightness)
230+ }
231+
232+ @Test
233+ fun brightnessChange_keepsSameBrightnessValueIfNotOnFullscreen () {
234+ playerViewModel.changeUiMode(UIModeState .FULLSCREEN_VIDEO , null )
235+ playerViewModel.brightnessChange(0.3f , 0.1f )
236+ val initialBrightness = playerViewModel.uiState.value.brightness
237+ playerViewModel.changeUiMode(UIModeState .EMBEDDED_VIDEO , null )
238+
239+ playerViewModel.brightnessChange(0.1f , 0.1f )
240+
241+ assertEquals(initialBrightness, playerViewModel.uiState.value.brightness)
242+ }
243+
244+ @Test
245+ fun volumeChange () {
246+ playerViewModel.volumeChange(0.1f )
247+ assertEquals(0.13f , playerViewModel.uiState.value.soundVolume)
248+ }
249+
250+ @Test
251+ fun onBackPressed () {
252+ playerViewModel.changeUiMode(UIModeState .FULLSCREEN_VIDEO , null )
253+ playerViewModel.onBackPressed()
254+ assertEquals(UIModeState .EMBEDDED_VIDEO , playerViewModel.uiState.value.uiMode)
255+ assertEquals(PlayMode .EMBEDDED_VIDEO , mockNewPlayer.playBackMode.value)
256+ }
257+
258+ @Test
259+ fun chapterSelected () {
260+ playerViewModel.chapterSelected(12 )
261+ verify (exactly = 1 ) { mockNewPlayer.selectChapter(12 ) }
262+ }
263+
264+ @Test
265+ fun streamSelected () {
266+ playerViewModel.streamSelected(24 )
267+ verify (exactly = 1 ) { mockNewPlayer.currentlyPlayingPlaylistItem = 24 }
268+ }
269+
270+ @Test
271+ fun cycleRepeatMode_fromDoNotRepeat () {
272+ every { mockNewPlayer.repeatMode } returns RepeatMode .DO_NOT_REPEAT
273+ playerViewModel.cycleRepeatMode()
274+ verify { mockNewPlayer.repeatMode = RepeatMode .REPEAT_ALL }
275+ }
276+
277+ @Test
278+ fun cycleRepeatMode_fromRepeatAll () {
279+ every { mockNewPlayer.repeatMode } returns RepeatMode .REPEAT_ALL
280+ playerViewModel.cycleRepeatMode()
281+ verify { mockNewPlayer.repeatMode = RepeatMode .REPEAT_ONE }
282+ }
283+
284+ @Test
285+ fun cycleRepeatMode_fromRepeatOne () {
286+ every { mockNewPlayer.repeatMode } returns RepeatMode .REPEAT_ONE
287+ playerViewModel.cycleRepeatMode()
288+ verify { mockNewPlayer.repeatMode = RepeatMode .DO_NOT_REPEAT }
289+ }
290+
291+ @Test
292+ fun cycleContentFitMode () {
293+ playerViewModel.cycleContentFitMode()
294+ assertEquals(ContentScale .CROP , playerViewModel.uiState.value.contentFitMode)
295+ playerViewModel.cycleContentFitMode()
296+ assertEquals(ContentScale .STRETCHED , playerViewModel.uiState.value.contentFitMode)
297+ playerViewModel.cycleContentFitMode()
298+ assertEquals(ContentScale .FIT_INSIDE , playerViewModel.uiState.value.contentFitMode)
299+ playerViewModel.cycleContentFitMode()
300+ assertEquals(ContentScale .CROP , playerViewModel.uiState.value.contentFitMode)
301+ }
302+
303+ @Test
304+ fun toggleShuffle () {
305+ every { mockNewPlayer.shuffle } returns false
306+ playerViewModel.toggleShuffle()
307+ verify (exactly = 1 ) { mockNewPlayer.shuffle = true }
308+ every { mockNewPlayer.shuffle } returns true
309+ playerViewModel.toggleShuffle()
310+ verify (exactly = 1 ) { mockNewPlayer.shuffle = false }
311+ }
312+
313+ @Test
314+ fun movePlaylistItem () {
315+ assertEquals(3 , playerViewModel.uiState.value.playList.size)
316+ val firstPlaylistItem = playerViewModel.uiState.value.playList.get(0 )
317+ val secondPlaylistitem = playerViewModel.uiState.value.playList.get(1 )
318+ val thirdPlaylistItem = playerViewModel.uiState.value.playList.get(2 )
319+
320+ playerViewModel.movePlaylistItem(1 , 2 )
321+
322+ assertEquals(firstPlaylistItem, playerViewModel.uiState.value.playList.get(0 ))
323+ assertEquals(thirdPlaylistItem, playerViewModel.uiState.value.playList.get(1 ))
324+ assertEquals(secondPlaylistitem, playerViewModel.uiState.value.playList.get(2 ))
325+ assertEquals(3 , playerViewModel.uiState.value.playList.size)
326+ }
327+
328+ @Test
329+ fun onStreamItemDragFinished () {
330+ playerViewModel.movePlaylistItem(1 , 2 )
331+ playerViewModel.onStreamItemDragFinished()
332+ verify (exactly = 1 ) { mockNewPlayer.movePlaylistItem(1 , 2 ) }
333+ }
334+
335+ @Test
336+ fun dialogVisible_updatesUiMode () {
337+ playerViewModel.dialogVisible(true )
338+ assertEquals(UIModeState .PLACEHOLDER , playerViewModel.uiState.value.uiMode)
339+ }
340+
341+ @Test
342+ fun doneEnteringPip () {
343+ playerViewModel.changeUiMode(UIModeState .PIP , null )
344+ assertTrue(playerViewModel.uiState.value.enteringPip)
345+ playerViewModel.doneEnteringPip()
346+ assertFalse(playerViewModel.uiState.value.enteringPip)
347+ }
348+
349+ @Test
350+ fun onPictureInPictureModeChanged_pipActivated () {
351+ playerViewModel.onPictureInPictureModeChanged(true )
352+ assertEquals(UIModeState .PIP , playerViewModel.uiState.value.uiMode)
353+ }
354+
355+ @Test
356+ fun onPictureInPictureModeChanged_pipDeactivated () {
357+ playerViewModel.onPictureInPictureModeChanged(false )
358+ assertEquals(UIModeState .FULLSCREEN_VIDEO , playerViewModel.uiState.value.uiMode)
359+ }
360+
361+ @Test
362+ fun removePlaylistItem () {
363+ playerViewModel.removePlaylistItem(123L )
364+ verify (exactly = 1 ) { mockNewPlayer.removePlaylistItem(123L ) }
365+ }
366+
155367}
0 commit comments