| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- import { describe, expect, it } from '@ohos/hypium'
- import { PlaybackCoordinator, PlaybackRuntime } from '../../../main/ets/controller/PlaybackCoordinator'
- import { PlaybackStateBridge } from '../../../main/ets/controller/PlaybackStateBridge'
- import { VideoItem } from '../../../main/ets/viewmodel/VideoItem'
- export default function playbackCoordinatorTest() {
- describe('PlaybackCoordinatorTest', () => {
- it('playQueueCallsRuntimeAndUpdatesState', 0, async () => {
- const bridge = PlaybackStateBridge.getInstance()
- const coordinator = PlaybackCoordinator.getInstance()
- const calls: string[] = []
- const songs: VideoItem[] = [
- new VideoItem('Song A', '1', '/music/a.flac', 0, 0, '2026-04-02'),
- new VideoItem('Song B', '2', '/music/b.flac', 0, 0, '2026-04-02')
- ]
- const runtime: PlaybackRuntime = {
- playQueue: async (_queue, startIndex, source) => {
- calls.push(`playQueue:${startIndex}:${source}`)
- },
- playOrPause: async () => {
- calls.push('playOrPause')
- },
- playNext: async () => {
- calls.push('playNext')
- },
- playPrevious: async () => {
- calls.push('playPrevious')
- },
- seekTo: async (value, source) => {
- calls.push(`seekTo:${value}:${source ?? ''}`)
- }
- }
- bridge.reset()
- coordinator.clearRuntime()
- coordinator.setRuntime(runtime)
- await coordinator.playQueue(songs, 1, 'charts-count')
- const snapshot = bridge.getSnapshot()
- expect(snapshot.currentIndex).assertEqual(1)
- expect(snapshot.currentSong?.filePath ?? '').assertEqual('/music/b.flac')
- expect(calls.join(',')).assertEqual('playQueue:1:charts-count')
- coordinator.clearRuntime()
- })
- it('playSongPropagatesStartIndexAndSourceAndUpdatesBridge', 0, async () => {
- const coordinator = PlaybackCoordinator.getInstance()
- const bridge = PlaybackStateBridge.getInstance()
- const song = new VideoItem('Song C', '3', '/music/c.flac', 0, 0, '2026-04-02')
- const runtimeCalls: string[] = []
- bridge.reset()
- coordinator.clearRuntime()
- coordinator.setRuntime({
- playQueue: async (_queue, startIndex, source) => {
- runtimeCalls.push(`${startIndex}:${source}`)
- },
- playOrPause: async () => {},
- playNext: async () => {},
- playPrevious: async () => {},
- seekTo: async () => {}
- })
- await coordinator.playSong(song, 'playlist-detail')
- const snapshot = bridge.getSnapshot()
- expect(runtimeCalls.join(',')).assertEqual('0:playlist-detail')
- expect(snapshot.currentIndex).assertEqual(0)
- expect(snapshot.currentSong?.filePath ?? '').assertEqual('/music/c.flac')
- coordinator.clearRuntime()
- })
- it('clearRuntimeOnlyRemovesMatchingInstance', 0, async () => {
- const coordinator = PlaybackCoordinator.getInstance()
- let playOrPauseCount = 0
- const runtimeA: PlaybackRuntime = {
- playQueue: async () => {},
- playOrPause: async () => {
- playOrPauseCount++
- },
- playNext: async () => {},
- playPrevious: async () => {},
- seekTo: async () => {}
- }
- const runtimeB: PlaybackRuntime = {
- playQueue: async () => {},
- playOrPause: async () => {},
- playNext: async () => {},
- playPrevious: async () => {},
- seekTo: async () => {}
- }
- coordinator.clearRuntime()
- coordinator.setRuntime(runtimeA)
- coordinator.clearRuntime(runtimeB)
- await coordinator.playOrPause()
- expect(playOrPauseCount).assertEqual(1)
- coordinator.clearRuntime(runtimeA)
- await coordinator.playOrPause()
- expect(playOrPauseCount).assertEqual(1)
- })
- it('coordinatorTransportControlsUseRegisteredRuntimeOnly', 0, async () => {
- const coordinator = PlaybackCoordinator.getInstance()
- const calls: string[] = []
- coordinator.clearRuntime()
- coordinator.setRuntime({
- playQueue: async () => {},
- playOrPause: async () => {
- calls.push('playOrPause')
- },
- playNext: async () => {
- calls.push('playNext')
- },
- playPrevious: async () => {
- calls.push('playPrevious')
- },
- seekTo: async (value, source) => {
- calls.push(`seekTo:${value}:${source ?? ''}`)
- }
- })
- await coordinator.playOrPause()
- await coordinator.playNext()
- await coordinator.playPrevious()
- await coordinator.seekTo('1200', 'slider')
- expect(calls.join(',')).assertEqual('playOrPause,playNext,playPrevious,seekTo:1200:slider')
- coordinator.clearRuntime()
- })
- it('playQueueWithoutRuntimeKeepsBridgeState', 0, async () => {
- const coordinator = PlaybackCoordinator.getInstance()
- const bridge = PlaybackStateBridge.getInstance()
- const initialSong = new VideoItem('Initial', 'init', '/music/initial.flac', 0, 0, '2026-04-02')
- bridge.reset()
- bridge.replaceQueue([initialSong], 0)
- const before = bridge.getSnapshot()
- coordinator.clearRuntime()
- await coordinator.playQueue(
- [new VideoItem('Song D', '4', '/music/d.flac', 0, 0, '2026-04-02')],
- 0,
- 'charts'
- )
- const after = bridge.getSnapshot()
- expect(after.currentIndex).assertEqual(before.currentIndex)
- expect(after.currentSong?.filePath ?? '').assertEqual(before.currentSong?.filePath ?? '')
- expect(after.queue.length).assertEqual(before.queue.length)
- })
- it('playQueueRollsBackOnRuntimeError', 0, async () => {
- const coordinator = PlaybackCoordinator.getInstance()
- const bridge = PlaybackStateBridge.getInstance()
- const previousSong = new VideoItem('Previous', 'prev', '/music/prev.flac', 0, 0, '2026-04-02')
- bridge.reset()
- bridge.replaceQueue([previousSong], 0)
- const snapshotBefore = bridge.getSnapshot()
- let threwError = false
- coordinator.clearRuntime()
- coordinator.setRuntime({
- playQueue: async () => {
- throw new Error('boom')
- },
- playOrPause: async () => {},
- playNext: async () => {},
- playPrevious: async () => {},
- seekTo: async () => {}
- })
- try {
- await coordinator.playQueue(
- [
- new VideoItem('Song E', '5', '/music/e.flac', 0, 0, '2026-04-02'),
- new VideoItem('Song F', '6', '/music/f.flac', 0, 0, '2026-04-02')
- ],
- 0,
- 'playlist'
- )
- } catch (error) {
- threwError = true
- }
- expect(threwError).assertEqual(true)
- const snapshotAfter = bridge.getSnapshot()
- expect(snapshotAfter.queue.length).assertEqual(snapshotBefore.queue.length)
- expect(snapshotAfter.currentIndex).assertEqual(snapshotBefore.currentIndex)
- expect(snapshotAfter.currentSong?.filePath ?? '').assertEqual(snapshotBefore.currentSong?.filePath ?? '')
- coordinator.clearRuntime()
- })
- it('playSongWrapsSingleSongQueue', 0, async () => {
- const coordinator = PlaybackCoordinator.getInstance()
- let queueLength = 0
- coordinator.clearRuntime()
- coordinator.setRuntime({
- playQueue: async (queue) => {
- queueLength = queue.length
- },
- playOrPause: async () => {},
- playNext: async () => {},
- playPrevious: async () => {},
- seekTo: async () => {}
- })
- await coordinator.playSong(new VideoItem('Song A', '1', '/music/a.flac', 0, 0, '2026-04-02'), 'playlist-detail')
- expect(queueLength).assertEqual(1)
- coordinator.clearRuntime()
- })
- })
- }
|