Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
869060c56f |
@@ -12,8 +12,8 @@ android {
|
|||||||
applicationId = "dev.castarr.tv"
|
applicationId = "dev.castarr.tv"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 26
|
versionCode = 27
|
||||||
versionName = "0.10.0"
|
versionName = "0.10.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release signing from environment (see ~/.keys/castarr-release.env on the
|
// Release signing from environment (see ~/.keys/castarr-release.env on the
|
||||||
|
|||||||
@@ -54,14 +54,21 @@ class AppState(
|
|||||||
private fun loadEnabledTeams(): Set<String> {
|
private fun loadEnabledTeams(): Set<String> {
|
||||||
val stored = prefs.getStringSet("teams", null)
|
val stored = prefs.getStringSet("teams", null)
|
||||||
if (stored != null) return stored.toSet()
|
if (stored != null) return stored.toSet()
|
||||||
return setOfNotNull(dev.castarr.tv.data.TeamFilters.defaultKeyFor(auth.username))
|
return dev.castarr.tv.data.TeamFilters.defaultKeysFor(auth.username).toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleTeam(key: String) {
|
/** Returns false when the cap of [TeamFilters.MAX_ACTIVE] is reached. */
|
||||||
|
fun toggleTeam(key: String): Boolean {
|
||||||
|
if (key !in enabledTeams &&
|
||||||
|
enabledTeams.size >= dev.castarr.tv.data.TeamFilters.MAX_ACTIVE
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
enabledTeams =
|
enabledTeams =
|
||||||
if (key in enabledTeams) enabledTeams - key else enabledTeams + key
|
if (key in enabledTeams) enabledTeams - key else enabledTeams + key
|
||||||
prefs.edit().putStringSet("teams", enabledTeams).apply()
|
prefs.edit().putStringSet("teams", enabledTeams).apply()
|
||||||
if (activeTeam == key && key !in enabledTeams) activeTeam = null
|
if (activeTeam == key && key !in enabledTeams) activeTeam = null
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
var audioTracks by mutableStateOf<List<PlayerController.AudioTrack>>(emptyList())
|
var audioTracks by mutableStateOf<List<PlayerController.AudioTrack>>(emptyList())
|
||||||
private set
|
private set
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ data class TeamFilter(
|
|||||||
val key: String,
|
val key: String,
|
||||||
/** Short caption next to the crest in the rail. */
|
/** Short caption next to the crest in the rail. */
|
||||||
val label: String,
|
val label: String,
|
||||||
/** How the club is named in a sentence. */
|
/** Full club name, shown in the settings and in messages. */
|
||||||
val name: String,
|
|
||||||
/** Full club name, used in the settings. */
|
|
||||||
val fullName: String,
|
val fullName: String,
|
||||||
/** Lowercase needles matched against programme titles. */
|
/** Lowercase needles matched against programme titles. */
|
||||||
val needles: List<String>,
|
val needles: List<String>,
|
||||||
@@ -32,31 +30,88 @@ object TeamFilters {
|
|||||||
/** Window scanned ahead of now. */
|
/** Window scanned ahead of now. */
|
||||||
const val WINDOW_MS = 3 * 60 * 60 * 1000L
|
const val WINDOW_MS = 3 * 60 * 60 * 1000L
|
||||||
|
|
||||||
val all = listOf(
|
/** At most this many club groups sit in the rail at once. */
|
||||||
TeamFilter(
|
const val MAX_ACTIVE = 3
|
||||||
key = "hansa",
|
|
||||||
label = "FCH",
|
private const val WHITE = 0xFFF2F3F5
|
||||||
name = "Hansa",
|
private const val BLACK = 0xFF15171B
|
||||||
fullName = "Hansa Rostock",
|
|
||||||
needles = listOf("hansa"),
|
private fun club(
|
||||||
primary = Color(0xFF0B4EA2),
|
key: String,
|
||||||
secondary = Color(0xFFF2F3F5),
|
label: String,
|
||||||
),
|
fullName: String,
|
||||||
TeamFilter(
|
needles: List<String>,
|
||||||
key = "vfb",
|
primary: Long,
|
||||||
label = "1893",
|
secondary: Long,
|
||||||
name = "dem VfB",
|
) = TeamFilter(key, label, fullName, needles, Color(primary), Color(secondary))
|
||||||
fullName = "VfB Stuttgart",
|
|
||||||
needles = listOf("vfb stuttgart", "vfb"),
|
/** Clubs of the top three German divisions. */
|
||||||
primary = Color(0xFFE32219),
|
val all: List<TeamFilter> = listOf(
|
||||||
secondary = Color(0xFFF2F3F5),
|
// --- Bundesliga ---
|
||||||
),
|
club("bayern", "FCB", "FC Bayern München", listOf("bayern münchen", "fc bayern"), 0xFFDC052D, WHITE),
|
||||||
|
club("bvb", "BVB", "Borussia Dortmund", listOf("borussia dortmund", "bvb"), 0xFFFDE100, BLACK),
|
||||||
|
club("leipzig", "RBL", "RB Leipzig", listOf("rb leipzig"), 0xFFDD0741, WHITE),
|
||||||
|
club("leverkusen", "B04", "Bayer 04 Leverkusen", listOf("leverkusen"), 0xFFE32219, BLACK),
|
||||||
|
club("frankfurt", "SGE", "Eintracht Frankfurt", listOf("eintracht frankfurt"), 0xFF1A1A1A, 0xFFE1000F),
|
||||||
|
club("stuttgart", "1893", "VfB Stuttgart", listOf("vfb stuttgart"), 0xFFE32219, WHITE),
|
||||||
|
club("gladbach", "BMG", "Borussia Mönchengladbach", listOf("mönchengladbach", "gladbach"), 0xFF1A1A1A, 0xFF00A94F),
|
||||||
|
club("wolfsburg", "WOB", "VfL Wolfsburg", listOf("wolfsburg"), 0xFF65B32E, WHITE),
|
||||||
|
club("bremen", "SVW", "SV Werder Bremen", listOf("werder bremen", "werder"), 0xFF1D9053, WHITE),
|
||||||
|
club("freiburg", "SCF", "SC Freiburg", listOf("sc freiburg", "freiburg"), 0xFFE2001A, WHITE),
|
||||||
|
club("hoffenheim", "TSG", "TSG Hoffenheim", listOf("hoffenheim"), 0xFF1C63B7, WHITE),
|
||||||
|
club("mainz", "M05", "1. FSV Mainz 05", listOf("mainz 05", "mainz"), 0xFFE1000F, WHITE),
|
||||||
|
club("augsburg", "FCA", "FC Augsburg", listOf("augsburg"), 0xFF00693F, 0xFFE1000F),
|
||||||
|
club("union", "FCU", "1. FC Union Berlin", listOf("union berlin"), 0xFFE1000F, 0xFFFDE100),
|
||||||
|
club("koeln", "EFC", "1. FC Köln", listOf("1. fc köln", "fc köln"), 0xFFE1000F, WHITE),
|
||||||
|
club("hsv", "HSV", "Hamburger SV", listOf("hamburger sv", "hsv"), 0xFF0E5EA6, BLACK),
|
||||||
|
club("heidenheim", "FCH1", "1. FC Heidenheim", listOf("heidenheim"), 0xFFE1000F, 0xFF1656A4),
|
||||||
|
club("st-pauli", "FCSP", "FC St. Pauli", listOf("st. pauli", "st pauli"), 0xFF6B4423, WHITE),
|
||||||
|
// --- 2. Bundesliga ---
|
||||||
|
club("schalke", "S04", "FC Schalke 04", listOf("schalke"), 0xFF004D9D, WHITE),
|
||||||
|
club("hertha", "BSC", "Hertha BSC", listOf("hertha"), 0xFF004D9D, WHITE),
|
||||||
|
club("duesseldorf", "F95", "Fortuna Düsseldorf", listOf("fortuna düsseldorf"), 0xFFE1000F, WHITE),
|
||||||
|
club("nuernberg", "FCN", "1. FC Nürnberg", listOf("nürnberg"), 0xFF8B1A1A, WHITE),
|
||||||
|
club("kaiserslautern", "FCK", "1. FC Kaiserslautern", listOf("kaiserslautern"), 0xFFE1000F, WHITE),
|
||||||
|
club("karlsruhe", "KSC", "Karlsruher SC", listOf("karlsruher sc", "ksc"), 0xFF0055A5, WHITE),
|
||||||
|
club("hannover", "H96", "Hannover 96", listOf("hannover 96"), 0xFF00A94F, WHITE),
|
||||||
|
club("paderborn", "SCP", "SC Paderborn 07", listOf("paderborn"), 0xFF004D9D, WHITE),
|
||||||
|
club("magdeburg", "FCM", "1. FC Magdeburg", listOf("magdeburg"), 0xFF0B7A3E, WHITE),
|
||||||
|
club("elversberg", "SVE", "SV Elversberg", listOf("elversberg"), 0xFF1A1A1A, 0xFFE1000F),
|
||||||
|
club("darmstadt", "SV98", "SV Darmstadt 98", listOf("darmstadt"), 0xFF004E9E, WHITE),
|
||||||
|
club("braunschweig", "BTSV", "Eintracht Braunschweig", listOf("braunschweig"), 0xFFFDE100, 0xFF004E9E),
|
||||||
|
club("bochum", "BOC", "VfL Bochum", listOf("bochum"), 0xFF005CA9, WHITE),
|
||||||
|
club("muenster", "SCPM", "Preußen Münster", listOf("preußen münster", "münster"), 0xFF00703C, WHITE),
|
||||||
|
club("fuerth", "SGF", "SpVgg Greuther Fürth", listOf("greuther fürth", "fürth"), 0xFF00A94F, WHITE),
|
||||||
|
club("holstein", "KSV", "Holstein Kiel", listOf("holstein kiel"), 0xFF004E9E, 0xFFE1000F),
|
||||||
|
club("dresden", "SGD", "Dynamo Dresden", listOf("dynamo dresden"), 0xFFFDE100, BLACK),
|
||||||
|
club("bielefeld", "DSC", "Arminia Bielefeld", listOf("arminia bielefeld", "bielefeld"), 0xFF00539F, WHITE),
|
||||||
|
// --- 3. Liga ---
|
||||||
|
club("hansa", "FCH", "FC Hansa Rostock", listOf("hansa"), 0xFF0B4EA2, WHITE),
|
||||||
|
club("saarbruecken", "FCS", "1. FC Saarbrücken", listOf("saarbrücken"), 0xFF0B4EA2, BLACK),
|
||||||
|
club("aue", "FCE", "Erzgebirge Aue", listOf("erzgebirge aue"), 0xFF7C0A02, WHITE),
|
||||||
|
club("cottbus", "FCEC", "Energie Cottbus", listOf("energie cottbus", "cottbus"), 0xFFE1000F, WHITE),
|
||||||
|
club("essen", "RWE", "Rot-Weiss Essen", listOf("rot-weiss essen", "rot weiss essen"), 0xFFE1000F, WHITE),
|
||||||
|
club("duisburg", "MSV", "MSV Duisburg", listOf("msv duisburg", "duisburg"), 0xFF004E9E, WHITE),
|
||||||
|
club("mannheim", "SVWM", "SV Waldhof Mannheim", listOf("waldhof mannheim", "waldhof"), 0xFF0B4EA2, WHITE),
|
||||||
|
club("wehen", "SVWW", "SV Wehen Wiesbaden", listOf("wehen wiesbaden", "wehen"), 0xFFE1000F, BLACK),
|
||||||
|
club("ulm", "SSV", "SSV Ulm 1846", listOf("ssv ulm"), 0xFFE1000F, WHITE),
|
||||||
|
club("regensburg", "SSVJ", "SSV Jahn Regensburg", listOf("jahn regensburg", "regensburg"), 0xFFE1000F, WHITE),
|
||||||
|
club("verl", "SCV", "SC Verl", listOf("sc verl"), 0xFF00703C, WHITE),
|
||||||
|
club("viktoria", "VKÖ", "Viktoria Köln", listOf("viktoria köln"), 0xFFE1000F, WHITE),
|
||||||
|
club("havelse", "TSVH", "TSV Havelse", listOf("havelse"), 0xFF004E9E, WHITE),
|
||||||
|
club("schweinfurt", "FC05", "1. FC Schweinfurt 05", listOf("schweinfurt"), 0xFF00A94F, WHITE),
|
||||||
|
club("osnabrueck", "VfLO", "VfL Osnabrück", listOf("osnabrück"), 0xFF6A2C8F, WHITE),
|
||||||
|
club("aachen", "ALE", "Alemannia Aachen", listOf("alemannia aachen", "aachen"), 0xFFFDE100, BLACK),
|
||||||
|
club("ingolstadt", "FCI", "FC Ingolstadt 04", listOf("ingolstadt"), 0xFFE1000F, BLACK),
|
||||||
|
club("wuppertal", "WSV", "Wuppertaler SV", listOf("wuppertaler sv"), 0xFFE1000F, 0xFF0B4EA2),
|
||||||
|
club("stuttgart-ii", "VfB2", "VfB Stuttgart II", listOf("vfb stuttgart ii"), 0xFFE32219, BLACK),
|
||||||
|
club("hoffenheim-ii", "TSG2", "TSG Hoffenheim II", listOf("hoffenheim ii"), 0xFF1C63B7, BLACK),
|
||||||
)
|
)
|
||||||
|
|
||||||
/** The club a viewer gets switched on by default. */
|
/** Clubs switched on for a viewer before they touch the settings. */
|
||||||
private val defaultForUser = mapOf(
|
private val defaultForUser = mapOf(
|
||||||
"benjamin" to "hansa",
|
"benjamin" to listOf("hansa"),
|
||||||
"tobiasb" to "vfb",
|
"tobiasb" to listOf("stuttgart"),
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,6 +135,6 @@ object TeamFilters {
|
|||||||
|
|
||||||
fun byKey(key: String): TeamFilter? = all.firstOrNull { it.key == key }
|
fun byKey(key: String): TeamFilter? = all.firstOrNull { it.key == key }
|
||||||
|
|
||||||
fun defaultKeyFor(username: String): String? =
|
fun defaultKeysFor(username: String): List<String> =
|
||||||
defaultForUser[username.trim().lowercase()]
|
defaultForUser[username.trim().lowercase()].orEmpty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,12 @@ import androidx.compose.ui.geometry.Offset
|
|||||||
import androidx.compose.ui.graphics.Path
|
import androidx.compose.ui.graphics.Path
|
||||||
import androidx.compose.ui.graphics.drawscope.clipPath
|
import androidx.compose.ui.graphics.drawscope.clipPath
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusProperties
|
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.input.key.Key
|
||||||
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
|
import androidx.compose.ui.input.key.key
|
||||||
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
|
import androidx.compose.ui.input.key.type
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -130,11 +134,18 @@ fun LiveScreen(state: AppState) {
|
|||||||
state.restorePending = false
|
state.restorePending = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val intoList = if (channels.isEmpty()) Modifier
|
// A FocusRequester that is not currently attached throws when used, and
|
||||||
else Modifier.focusProperties { right = listFocus }
|
// in a LazyColumn the selected row may well be scrolled out of
|
||||||
|
// composition — so jumps are attempted, not declared.
|
||||||
|
val intoList = if (channels.isEmpty()) Modifier else Modifier.onPreviewKeyEvent { event ->
|
||||||
|
event.type == KeyEventType.KeyDown && event.key == Key.DirectionRight &&
|
||||||
|
runCatching { listFocus.requestFocus() }.isSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
val railState = rememberLazyListState()
|
||||||
Row(Modifier.fillMaxSize()) {
|
Row(Modifier.fillMaxSize()) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
state = railState,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(264.dp)
|
.width(264.dp)
|
||||||
.fillMaxHeight(),
|
.fillMaxHeight(),
|
||||||
@@ -235,7 +246,7 @@ fun LiveScreen(state: AppState) {
|
|||||||
Text(
|
Text(
|
||||||
when {
|
when {
|
||||||
activeTeam != null ->
|
activeTeam != null ->
|
||||||
"In den nächsten 3 Stunden läuft nichts mit ${activeTeam.name}."
|
"In den nächsten 3 Stunden läuft nichts mit ${activeTeam.fullName}."
|
||||||
state.favoritesOnly ->
|
state.favoritesOnly ->
|
||||||
"Noch keine Favoriten — halte OK auf einem Sender gedrückt."
|
"Noch keine Favoriten — halte OK auf einem Sender gedrückt."
|
||||||
else -> "Diese Gruppe ist leer."
|
else -> "Diese Gruppe ist leer."
|
||||||
@@ -254,7 +265,11 @@ fun LiveScreen(state: AppState) {
|
|||||||
// matching the remote's number pad in every view.
|
// matching the remote's number pad in every view.
|
||||||
number = allChannels.indexOf(channel) + 1,
|
number = allChannels.indexOf(channel) + 1,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.focusProperties { left = railFocus }
|
.onPreviewKeyEvent { event ->
|
||||||
|
event.type == KeyEventType.KeyDown &&
|
||||||
|
event.key == Key.DirectionLeft &&
|
||||||
|
runCatching { railFocus.requestFocus() }.isSuccess
|
||||||
|
}
|
||||||
.then(if (listIndex == 0) Modifier.focusRequester(listFocus) else Modifier)
|
.then(if (listIndex == 0) Modifier.focusRequester(listFocus) else Modifier)
|
||||||
.then(
|
.then(
|
||||||
if (listIndex == restoreIndex) Modifier.focusRequester(restoreFocus)
|
if (listIndex == restoreIndex) Modifier.focusRequester(restoreFocus)
|
||||||
|
|||||||
@@ -165,36 +165,37 @@ fun SettingsScreen(state: AppState) {
|
|||||||
|
|
||||||
SettingsCard("Vereinsmenüs") {
|
SettingsCard("Vereinsmenüs") {
|
||||||
Text(
|
Text(
|
||||||
"Zeigt eine eigene Gruppe mit allen Sendern, auf denen der " +
|
"Eigene Gruppe mit allen Sendern, auf denen der Verein in den " +
|
||||||
"Verein in den nächsten 3 Stunden läuft.",
|
"nächsten 3 Stunden läuft. Bis zu " +
|
||||||
|
"${dev.castarr.tv.data.TeamFilters.MAX_ACTIVE} Vereine.",
|
||||||
color = CastarrColors.faint, fontFamily = AppFont, fontSize = 11.sp,
|
color = CastarrColors.faint, fontFamily = AppFont, fontSize = 11.sp,
|
||||||
modifier = Modifier.padding(start = 14.dp, end = 14.dp, bottom = 6.dp),
|
modifier = Modifier.padding(start = 14.dp, end = 14.dp, bottom = 6.dp),
|
||||||
)
|
)
|
||||||
dev.castarr.tv.data.TeamFilters.all.forEach { club ->
|
val active = dev.castarr.tv.data.TeamFilters.all
|
||||||
val on = club.key in state.enabledTeams
|
.filter { it.key in state.enabledTeams }
|
||||||
|
active.forEach { club ->
|
||||||
SettingRow(
|
SettingRow(
|
||||||
club.fullName,
|
club.fullName,
|
||||||
subtitle = "Erscheint als ${club.label} in der Senderliste",
|
subtitle = "Erscheint als ${club.label} in der Senderliste",
|
||||||
trailing = {
|
trailing = { TogglePill(on = true) },
|
||||||
Box(
|
|
||||||
Modifier
|
|
||||||
.clip(RoundedCornerShape(999.dp))
|
|
||||||
.background(
|
|
||||||
if (on) CastarrColors.accent else CastarrColors.bg
|
|
||||||
)
|
|
||||||
.padding(horizontal = 12.dp, vertical = 5.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
if (on) "An" else "Aus",
|
|
||||||
color = if (on) CastarrColors.onAccent else CastarrColors.muted,
|
|
||||||
fontFamily = AppFont,
|
|
||||||
fontSize = 12.sp,
|
|
||||||
fontWeight = if (on) FontWeight.SemiBold else FontWeight.Normal,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
) { state.toggleTeam(club.key) }
|
) { state.toggleTeam(club.key) }
|
||||||
}
|
}
|
||||||
|
if (active.size < dev.castarr.tv.data.TeamFilters.MAX_ACTIVE) {
|
||||||
|
SettingRow(
|
||||||
|
"Verein hinzufügen",
|
||||||
|
subtitle = "1. bis 3. Liga",
|
||||||
|
) {
|
||||||
|
val choices = dev.castarr.tv.data.TeamFilters.all
|
||||||
|
.filter { it.key !in state.enabledTeams }
|
||||||
|
picker = Picker(
|
||||||
|
"Verein hinzufügen",
|
||||||
|
choices.map { it.fullName },
|
||||||
|
-1,
|
||||||
|
) { index ->
|
||||||
|
choices.getOrNull(index)?.let { state.toggleTeam(it.key) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard("App") {
|
SettingsCard("App") {
|
||||||
@@ -419,6 +420,24 @@ private fun ValueWithCaret(value: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun TogglePill(on: Boolean) {
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.clip(RoundedCornerShape(999.dp))
|
||||||
|
.background(if (on) CastarrColors.accent else CastarrColors.bg)
|
||||||
|
.padding(horizontal = 12.dp, vertical = 5.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
if (on) "An" else "Aus",
|
||||||
|
color = if (on) CastarrColors.onAccent else CastarrColors.muted,
|
||||||
|
fontFamily = AppFont,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = if (on) FontWeight.SemiBold else FontWeight.Normal,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SettingsCard(title: String, content: @Composable () -> Unit) {
|
private fun SettingsCard(title: String, content: @Composable () -> Unit) {
|
||||||
Column(
|
Column(
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ package dev.castarr.tv.data
|
|||||||
|
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertNull
|
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class TeamFiltersTest {
|
class TeamFiltersTest {
|
||||||
|
|
||||||
private val hansa = TeamFilters.byKey("hansa")!!
|
private val hansa = TeamFilters.byKey("hansa")!!
|
||||||
private val vfb = TeamFilters.byKey("vfb")!!
|
private val vfb = TeamFilters.byKey("stuttgart")!!
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `matches the club regardless of case and surrounding text`() {
|
fun `matches the club regardless of case and surrounding text`() {
|
||||||
@@ -39,8 +38,24 @@ class TeamFiltersTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assigns each viewer their own club by default`() {
|
fun `assigns each viewer their own club by default`() {
|
||||||
assertEquals("hansa", TeamFilters.defaultKeyFor("benjamin"))
|
assertEquals(listOf("hansa"), TeamFilters.defaultKeysFor("benjamin"))
|
||||||
assertEquals("vfb", TeamFilters.defaultKeyFor("TobiasB"))
|
assertEquals(listOf("stuttgart"), TeamFilters.defaultKeysFor("TobiasB"))
|
||||||
assertNull(TeamFilters.defaultKeyFor("someone-else"))
|
assertTrue(TeamFilters.defaultKeysFor("someone-else").isEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `club keys are unique and every club has needles`() {
|
||||||
|
val keys = TeamFilters.all.map { it.key }
|
||||||
|
assertEquals(keys.size, keys.toSet().size)
|
||||||
|
assertTrue(TeamFilters.all.all { it.needles.isNotEmpty() })
|
||||||
|
assertTrue(TeamFilters.all.all { c -> c.needles.all { it == it.lowercase() } })
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `covers all three divisions`() {
|
||||||
|
assertTrue(TeamFilters.all.size > 50)
|
||||||
|
listOf("bayern", "schalke", "hansa").forEach {
|
||||||
|
assertTrue(it, TeamFilters.byKey(it) != null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user