play an offline context by reference and filter its window

This commit is contained in:
austinried
2026-10-04 00:30:04 +00:00
parent 3e042cb380
commit 554b7ef25d
11 changed files with 110 additions and 116 deletions
@@ -375,8 +375,6 @@ class LibraryDaoTest {
db.downloadDao().upsert(SongDownload(sourceId, "s3", DownloadStatus.Completed))
assertEquals(listOf("s1", "s3"), dao.songsByAlbumDownloaded(sourceId, "al-1").first().map { it.id })
assertEquals(listOf("s1", "s3"), dao.downloadedAlbumSongIds(sourceId, "al-1"))
assertEquals(listOf("s1", "s3"), dao.downloadedPlaylistSongIds(sourceId, "pl-1"))
assertEquals(
listOf("s1", "s3"),
dao.playlistSongsDownloaded(sourceId, "pl-1").page().map { it.song.id },
@@ -130,6 +130,22 @@ class LibraryRepositoryTest {
}
}
@Test
fun albumSongOrdinalFollowsTheAlbumOrder() =
runBlocking {
val sourceId = sourceRepository.addSource("nav", "http://localhost/", "u", "p", false)
db.libraryDao().upsertSongs(
listOf(
seedSong(sourceId).copy(id = "s3", track = 3),
seedSong(sourceId).copy(id = "s1", track = 1),
seedSong(sourceId).copy(id = "s2", track = 2),
),
)
assertEquals(0L, repository.albumSongOrdinal(sourceId, "al1", "s1"))
assertEquals(2L, repository.albumSongOrdinal(sourceId, "al1", "s3"))
}
private suspend fun withSource(block: suspend (MockWebServer) -> Unit) {
val server = MockWebServer()
server.start()
@@ -11,6 +11,8 @@ import com.subtracks.data.download.ArtworkStore
import com.subtracks.data.download.FakeDownloadEngine
import com.subtracks.data.model.Album
import com.subtracks.data.model.DownloadStatus
import com.subtracks.data.model.Playlist
import com.subtracks.data.model.PlaylistSong
import com.subtracks.data.model.QueueEntry
import com.subtracks.data.model.QueueKind
import com.subtracks.data.model.Song
@@ -2495,6 +2497,68 @@ class PlaybackControllerTest {
)
}
@Test
fun offlinePlayAlbumFiltersTheWindowToDownloadedSongs() {
seedAlbum(4, sourceId = 1)
markDownloaded(1, "s1")
markDownloaded(1, "s3")
setOffline()
controller.playAlbum(1, "al1", 0)
await { handle.items.map { it.id } == listOf("s1", "s3") }
assertEquals(listOf("s1", "s3"), handle.items.map { it.id })
assertEquals(listOf(QueueKind.Album), runBlocking { queues.snapshot().entries }.map { it.entry.kind })
assertEquals(1, runBlocking { queues.snapshot().entries }.size)
}
@Test
fun offlinePlaylistPlayKeepsASingleReferenceQueue() {
seedAlbum(3, sourceId = 1)
runBlocking {
db.libraryDao().upsertPlaylists(
listOf(Playlist(1, "pl1", "Playlist", comment = null, coverArt = null, songCount = 3, created = 0)),
)
db.libraryDao().upsertPlaylistSongs(
listOf(
PlaylistSong(1, "pl1", "s1", 0),
PlaylistSong(1, "pl1", "s2", 1),
PlaylistSong(1, "pl1", "s3", 2),
),
)
}
markDownloaded(1, "s1")
markDownloaded(1, "s2")
markDownloaded(1, "s3")
setOffline()
controller.playPlaylist(1, "pl1", 0)
await { handle.items.map { it.id } == listOf("s1", "s2", "s3") }
assertEquals(listOf(QueueKind.Playlist), runBlocking { queues.snapshot().entries }.map { it.entry.kind })
assertEquals(1, runBlocking { queues.snapshot().entries }.size)
}
@Test
fun offlinePlayAlbumStartsAtTheOrdinalItIsGiven() {
seedAlbum(4, sourceId = 1)
markDownloaded(1, "s2")
markDownloaded(1, "s3")
setOffline()
controller.playAlbum(1, "al1", 2)
await {
controller.state.value.item
?.id == "s3"
}
assertEquals(
"s3",
controller.state.value.item
?.id,
)
}
@Test
fun offlinePlayAlbumKeepsTheAlbumAsThePlayingContext() {
seedAlbum(4, sourceId = 1)
@@ -2558,19 +2622,6 @@ class PlaybackControllerTest {
)
}
@Test
fun offlinePlayAlbumBuildsADownloadedOnlyQueue() {
seedAlbum(4, sourceId = 1)
markDownloaded(1, "s1")
markDownloaded(1, "s3")
setOffline()
controller.playAlbum(1, "al1", 0)
await { handle.items.map { it.id } == listOf("s1", "s3") }
assertEquals(listOf("s1", "s3"), handle.items.map { it.id })
}
@Test
fun togglingOfflineKeepsADownloadedCurrentTrack() {
seedAlbum(4, sourceId = 1)
@@ -2682,17 +2733,14 @@ class PlaybackControllerTest {
songId: String,
) {
val file = File(downloadsDir, "$sourceId/$songId")
val deadline = System.nanoTime() + 5_000_000_000L
while (System.nanoTime() < deadline) {
runBlocking {
db.downloadDao().upsert(SongDownload(sourceId, songId, DownloadStatus.Completed))
file.parentFile?.mkdirs()
file.writeBytes(byteArrayOf(1))
}
if (downloads.localUri(songId) != null) return
Thread.sleep(10)
runBlocking {
downloads.reconcile()
db.downloadDao().upsert(SongDownload(sourceId, songId, DownloadStatus.Completed))
file.parentFile?.mkdirs()
file.writeBytes(byteArrayOf(1))
downloads.reconcile()
}
assertTrue("Timed out marking $songId downloaded", downloads.localUri(songId) != null)
await { downloads.localUri(songId) != null }
}
private fun setOffline() {