From e32df2fb08a364daf35ad09639b10a571055d87e Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Mon, 19 Oct 2026 02:31:39 +0000 Subject: [PATCH] test: cover up-next queue drag permutations Exercise context and block drags against the queue authority: all context positions across the up-next block, a far move that crosses the window, a context move while an up-next track plays, and moving the playing up-next track. --- .../playback/PlaybackControllerTest.kt | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt b/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt index 1796f4bc..52b226fd 100644 --- a/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt +++ b/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt @@ -577,6 +577,154 @@ class PlaybackControllerTest { ) } + @Test + fun contextDragsWithAnUpNextBlockKeepPlayerAndQueueInSync() { + seedAlbum(5, sourceId = 1) + seedSong("x1", "al2") + seedSong("x2", "al2") + + val pairs = + listOf( + 0L to 3L, + 3L to 0L, + 0L to 6L, + 6L to 0L, + 3L to 4L, + 4L to 3L, + 4L to 6L, + 6L to 4L, + 1L to 2L, + 2L to 1L, + ) + + for ((from, to) in pairs) { + controller.playAlbum(1, "al1", 0) + await { handle.items.map { it.id } == listOf("s1", "s2", "s3", "s4", "s5") } + controller.addToQueue(1, QueueKind.Song, "x1") + controller.addToQueue(1, QueueKind.Song, "x2") + await { handle.items.map { it.id } == listOf("s1", "x1", "x2", "s2", "s3", "s4", "s5") } + + runBlocking { controller.move(from, to) } + + val expected = + runBlocking { + val snapshot = queues.snapshot() + (0 until snapshot.size).mapNotNull { queues.itemAt(snapshot, it)?.song?.id } + } + assertEquals(expected, handle.items.map { it.id }) + assertEquals( + "s1", + controller.state.value.item + ?.id, + ) + assertEquals(expected.indexOf("s1").toLong(), controller.state.value.position) + } + } + + @Test + fun movingThePlayingUpNextTrackInTheBlockKeepsPlayerAndQueueInSync() { + seedAlbum(5, sourceId = 1) + seedSong("x1", "al2") + seedSong("x2", "al2") + + controller.playAlbum(1, "al1", 0) + await { + controller.state.value.item + ?.id == "s1" + } + controller.addToQueue(1, QueueKind.Song, "x1") + controller.addToQueue(1, QueueKind.Song, "x2") + await { handle.items.map { it.id } == listOf("s1", "x1", "x2", "s2", "s3", "s4", "s5") } + controller.next() + await { + controller.state.value.item + ?.id == "x1" + } + + runBlocking { controller.move(1, 2) } + + val expected = + runBlocking { + val snapshot = queues.snapshot() + (0 until snapshot.size).mapNotNull { queues.itemAt(snapshot, it)?.song?.id } + } + assertEquals(expected, handle.items.map { it.id }) + assertEquals( + "x1", + controller.state.value.item + ?.id, + ) + assertEquals(expected.indexOf("x1").toLong(), controller.state.value.position) + } + + @Test + fun draggingAContextTrackWhileAnUpNextTrackPlaysKeepsPlayerAndQueueInSync() { + seedAlbum(5, sourceId = 1) + seedSong("x1", "al2") + + controller.playAlbum(1, "al1", 0) + await { + controller.state.value.item + ?.id == "s1" + } + controller.addToQueue(1, QueueKind.Song, "x1") + await { runBlocking { controller.upcomingItem()?.id } == "x1" } + + controller.next() + await { + controller.state.value.item + ?.id == "x1" + } + + runBlocking { controller.move(0, 6) } + + val expected = + runBlocking { + val snapshot = queues.snapshot() + (0 until snapshot.size).mapNotNull { queues.itemAt(snapshot, it)?.song?.id } + } + assertEquals(expected, handle.items.map { it.id }) + assertEquals( + "x1", + controller.state.value.item + ?.id, + ) + assertEquals(expected.indexOf("x1").toLong(), controller.state.value.position) + } + + @Test + fun movingAContextTrackAcrossUpNextFarFromTheWindowKeepsPlayerAndQueueInSync() { + seedAlbum(60, sourceId = 1) + seedSong("x1", "al2") + + controller.playAlbum(1, "al1", 30) + await { + controller.state.value.item + ?.id == "s31" + } + controller.addToQueue(1, QueueKind.Song, "x1") + await { handle.items.any { it.id == "x1" } } + + runBlocking { controller.move(0, 59) } + + val expected = + runBlocking { + val snapshot = queues.snapshot() + (0 until snapshot.size).mapNotNull { queues.itemAt(snapshot, it)?.song?.id } + } + val current = expected.indexOf("s31") + await { controller.state.value.position == current.toLong() } + + val first = (current - 25).coerceAtLeast(0) + val last = (current + 25).coerceAtMost(expected.lastIndex) + assertEquals(expected.subList(first, last + 1), handle.items.map { it.id }) + assertEquals( + "s31", + controller.state.value.item + ?.id, + ) + } + @Test fun tappingAContextTrackWhileAQueuedTrackPlaysKeepsTheQueue() { seedAlbum(3, sourceId = 1)