test: cover rejected queue edit snackbars

This commit is contained in:
austinried
2026-11-14 12:05:29 +00:00
parent 5fadc21455
commit 97e700a1ab
@@ -1,12 +1,15 @@
package com.subtracks.ui.playback
import androidx.activity.ComponentActivity
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
import androidx.compose.ui.test.onAllNodesWithContentDescription
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.subtracks.R
import com.subtracks.data.model.AlbumSongItem
import com.subtracks.data.model.Song
import com.subtracks.ui.theme.SubtracksTheme
@@ -24,7 +27,7 @@ class QueueScreenTest {
@Test
fun shuffledContextRowsDoNotExposeRemoval() {
render(row(upNext = false), shuffle = true)
render(visible = listOf(row(upNext = false)), shuffle = true)
composeRule.onNodeWithContentDescription("Remove from queue").assertDoesNotExist()
composeRule.onNodeWithText("Removed from queue").assertDoesNotExist()
@@ -33,7 +36,14 @@ class QueueScreenTest {
@Test
fun shuffledUpNextRowsStillRemoveAndShowUndo() {
var removed: Long? = null
render(row(upNext = true), shuffle = true, onRemove = { removed = it })
render(
visible = listOf(row(upNext = true)),
shuffle = true,
onRemove = { position, onComplete ->
removed = position
onComplete(true)
},
)
composeRule.onNodeWithContentDescription("Remove from queue").performClick()
@@ -42,15 +52,43 @@ class QueueScreenTest {
composeRule.onNodeWithText("Undo").assertIsDisplayed()
}
@Test
fun rejectedRemovalDoesNotShowSuccessOrUndo() {
render(onRemove = { _, onComplete -> onComplete(false) })
removeFirstRow()
composeRule.waitForIdle()
assertNoSnackbar(R.string.queue_removed)
}
@Test
fun appliedRemovalShowsUndoAndRunsItOnlyFromTheAction() {
var undos = 0
render(onRemove = { _, onComplete -> onComplete(true) }, onUndo = { undos++ })
removeFirstRow()
composeRule.onNodeWithText(composeRule.activity.getString(R.string.queue_removed)).assertIsDisplayed()
composeRule.onNodeWithText(composeRule.activity.getString(R.string.undo)).performClick()
composeRule.runOnIdle { assertEquals(1, undos) }
}
private fun render(
row: QueueRow,
shuffle: Boolean,
onRemove: (Long) -> Unit = {},
visible: List<QueueRow> = rows,
shuffle: Boolean = false,
onRemove: (Long, (Boolean) -> Unit) -> Unit = { _, onComplete -> onComplete(false) },
onMove: (QueueMove, (Boolean) -> Unit) -> Boolean = { _, onComplete ->
onComplete(false)
true
},
onUndo: () -> Unit = {},
) {
val visibleRows = mutableStateListOf<QueueRow>().also { it.addAll(visible) }
composeRule.setContent {
SubtracksTheme {
QueueScreen(
rows = listOf(row),
rows = visibleRows,
ready = true,
currentPosition = null,
currentSongId = null,
@@ -59,39 +97,61 @@ class QueueScreenTest {
onBack = {},
onPlay = {},
onRemove = onRemove,
onReorder = { _, _ -> },
onMove = { _, _ -> false },
onReorder = { from, to -> visibleRows.add(to, visibleRows.removeAt(from)) },
onMove = onMove,
onLoadOlder = {},
onLoadNewer = {},
onUndo = {},
onUndo = onUndo,
)
}
}
}
private fun removeFirstRow() {
composeRule.onAllNodesWithContentDescription(composeRule.activity.getString(R.string.queue_remove))[0].performClick()
}
private fun assertNoSnackbar(message: Int) {
composeRule.onNodeWithText(composeRule.activity.getString(message)).assertDoesNotExist()
composeRule.onNodeWithText(composeRule.activity.getString(R.string.undo)).assertDoesNotExist()
}
private fun row(upNext: Boolean) =
QueueRow(
id = 0,
position = 0,
song =
AlbumSongItem(
song =
Song(
sourceId = 1,
id = "s1",
albumId = "al1",
artistId = "ar1",
title = "Song",
album = "Album",
artist = "Artist",
duration = 100,
track = 1,
disc = 1,
starred = null,
genre = null,
),
coverArt = null,
),
song = song("s1", 1),
coverArt = null,
upNext = upNext,
)
private val rows =
(0..2).map { index ->
QueueRow(
id = index.toLong(),
position = index.toLong(),
song = song("s$index", index.toLong()),
coverArt = null,
)
}
private fun song(
id: String,
track: Long,
) = AlbumSongItem(
Song(
sourceId = 1,
id = id,
albumId = "al1",
artistId = "ar1",
title = "Song $id",
album = "Album",
artist = "Artist",
duration = 100,
track = track,
disc = 1,
starred = null,
genre = null,
),
)
}