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 package com.subtracks.ui.playback
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule 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.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.subtracks.R
import com.subtracks.data.model.AlbumSongItem import com.subtracks.data.model.AlbumSongItem
import com.subtracks.data.model.Song import com.subtracks.data.model.Song
import com.subtracks.ui.theme.SubtracksTheme import com.subtracks.ui.theme.SubtracksTheme
@@ -24,7 +27,7 @@ class QueueScreenTest {
@Test @Test
fun shuffledContextRowsDoNotExposeRemoval() { fun shuffledContextRowsDoNotExposeRemoval() {
render(row(upNext = false), shuffle = true) render(visible = listOf(row(upNext = false)), shuffle = true)
composeRule.onNodeWithContentDescription("Remove from queue").assertDoesNotExist() composeRule.onNodeWithContentDescription("Remove from queue").assertDoesNotExist()
composeRule.onNodeWithText("Removed from queue").assertDoesNotExist() composeRule.onNodeWithText("Removed from queue").assertDoesNotExist()
@@ -33,7 +36,14 @@ class QueueScreenTest {
@Test @Test
fun shuffledUpNextRowsStillRemoveAndShowUndo() { fun shuffledUpNextRowsStillRemoveAndShowUndo() {
var removed: Long? = null 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() composeRule.onNodeWithContentDescription("Remove from queue").performClick()
@@ -42,15 +52,43 @@ class QueueScreenTest {
composeRule.onNodeWithText("Undo").assertIsDisplayed() 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( private fun render(
row: QueueRow, visible: List<QueueRow> = rows,
shuffle: Boolean, shuffle: Boolean = false,
onRemove: (Long) -> Unit = {}, 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 { composeRule.setContent {
SubtracksTheme { SubtracksTheme {
QueueScreen( QueueScreen(
rows = listOf(row), rows = visibleRows,
ready = true, ready = true,
currentPosition = null, currentPosition = null,
currentSongId = null, currentSongId = null,
@@ -59,39 +97,61 @@ class QueueScreenTest {
onBack = {}, onBack = {},
onPlay = {}, onPlay = {},
onRemove = onRemove, onRemove = onRemove,
onReorder = { _, _ -> }, onReorder = { from, to -> visibleRows.add(to, visibleRows.removeAt(from)) },
onMove = { _, _ -> false }, onMove = onMove,
onLoadOlder = {}, onLoadOlder = {},
onLoadNewer = {}, 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) = private fun row(upNext: Boolean) =
QueueRow( QueueRow(
id = 0, id = 0,
position = 0, position = 0,
song = song = song("s1", 1),
AlbumSongItem( coverArt = null,
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,
),
upNext = upNext, 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,
),
)
} }