fix(cron): preserve chosen clock time across repeat changes
Android acceptance / android (push) Successful in 24m54s
Android acceptance / android (push) Successful in 24m54s
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package com.m57.hermescontrol.ui.cron
|
package com.m57.hermescontrol.ui.cron
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -10,12 +9,10 @@ import androidx.compose.foundation.verticalScroll
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.test.hasContentDescription
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
|
||||||
import androidx.compose.ui.test.junit4.createComposeRule
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
import androidx.compose.ui.test.onAllNodesWithText
|
import androidx.compose.ui.test.onAllNodesWithText
|
||||||
import androidx.compose.ui.test.onNodeWithText
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
@@ -34,13 +31,8 @@ class SchedulePickerTest {
|
|||||||
@Test
|
@Test
|
||||||
fun repeatDropdownAndClockPreserveSchedule() {
|
fun repeatDropdownAndClockPreserveSchedule() {
|
||||||
var schedule by mutableStateOf("59 23 * * *")
|
var schedule by mutableStateOf("59 23 * * *")
|
||||||
val baseContext = InstrumentationRegistry.getInstrumentation().targetContext
|
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
val configuration = Configuration(baseContext.resources.configuration).apply {
|
|
||||||
setLocale(java.util.Locale.forLanguageTag("tr-TR"))
|
|
||||||
}
|
|
||||||
val context = baseContext.createConfigurationContext(configuration)
|
|
||||||
compose.setContent {
|
compose.setContent {
|
||||||
CompositionLocalProvider(LocalContext provides context, LocalConfiguration provides configuration) {
|
|
||||||
MaterialTheme {
|
MaterialTheme {
|
||||||
Surface {
|
Surface {
|
||||||
Column(Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(16.dp)) {
|
Column(Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(16.dp)) {
|
||||||
@@ -49,10 +41,10 @@ class SchedulePickerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
fun text(id: Int) = context.getString(id)
|
fun text(id: Int) = context.getString(id)
|
||||||
fun screenshot(name: String) {
|
fun screenshot(name: String) {
|
||||||
compose.waitForIdle()
|
compose.waitForIdle()
|
||||||
|
android.os.SystemClock.sleep(500)
|
||||||
val bitmap = InstrumentationRegistry.getInstrumentation().uiAutomation.takeScreenshot()
|
val bitmap = InstrumentationRegistry.getInstrumentation().uiAutomation.takeScreenshot()
|
||||||
File(context.getExternalFilesDir(null), "$name.png").outputStream().use {
|
File(context.getExternalFilesDir(null), "$name.png").outputStream().use {
|
||||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, it)
|
bitmap.compress(Bitmap.CompressFormat.PNG, 100, it)
|
||||||
@@ -62,7 +54,7 @@ class SchedulePickerTest {
|
|||||||
compose.onNodeWithText("23:59").performClick()
|
compose.onNodeWithText("23:59").performClick()
|
||||||
screenshot("schedule-clock-360")
|
screenshot("schedule-clock-360")
|
||||||
compose.onNodeWithText("59").performClick()
|
compose.onNodeWithText("59").performClick()
|
||||||
compose.onNodeWithText("55").performClick()
|
compose.onNode(hasContentDescription("55", substring = true)).performClick()
|
||||||
compose.onNodeWithText(text(R.string.action_ok)).performClick()
|
compose.onNodeWithText(text(R.string.action_ok)).performClick()
|
||||||
compose.runOnIdle { assertEquals("55 23 * * *", schedule) }
|
compose.runOnIdle { assertEquals("55 23 * * *", schedule) }
|
||||||
compose.onNodeWithText(text(R.string.cron_repeat_label)).performClick()
|
compose.onNodeWithText(text(R.string.cron_repeat_label)).performClick()
|
||||||
@@ -71,6 +63,12 @@ class SchedulePickerTest {
|
|||||||
compose.runOnIdle { assertEquals("55 23 1 1 *", schedule) }
|
compose.runOnIdle { assertEquals("55 23 1 1 *", schedule) }
|
||||||
screenshot("schedule-yearly-360")
|
screenshot("schedule-yearly-360")
|
||||||
compose.onNodeWithText(text(R.string.cron_repeat_label)).performClick()
|
compose.onNodeWithText(text(R.string.cron_repeat_label)).performClick()
|
||||||
|
compose.onAllNodesWithText(text(R.string.cron_repeat_hourly))[0].performClick()
|
||||||
|
compose.runOnIdle { assertEquals("55 * * * *", schedule) }
|
||||||
|
compose.onNodeWithText(text(R.string.cron_repeat_label)).performClick()
|
||||||
|
compose.onAllNodesWithText(text(R.string.cron_schedule_mode_daily))[0].performClick()
|
||||||
|
compose.runOnIdle { assertEquals("55 23 * * *", schedule) }
|
||||||
|
compose.onNodeWithText(text(R.string.cron_repeat_label)).performClick()
|
||||||
compose.onAllNodesWithText(text(R.string.cron_repeat_minutely))[0].performClick()
|
compose.onAllNodesWithText(text(R.string.cron_repeat_minutely))[0].performClick()
|
||||||
compose.runOnIdle { assertEquals("* * * * *", schedule) }
|
compose.runOnIdle { assertEquals("* * * * *", schedule) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1004,8 +1004,8 @@ internal fun SchedulePickerSection(
|
|||||||
val parsed = remember(schedule) { parseSchedule(schedule) }
|
val parsed = remember(schedule) { parseSchedule(schedule) }
|
||||||
|
|
||||||
var mode by remember(schedule) { mutableStateOf(parsed.mode) }
|
var mode by remember(schedule) { mutableStateOf(parsed.mode) }
|
||||||
var hour by remember(schedule) { mutableStateOf(parsed.hour) }
|
var hour by remember { mutableStateOf(parsed.hour) }
|
||||||
var minute by remember(schedule) { mutableStateOf(parsed.minute) }
|
var minute by remember { mutableStateOf(parsed.minute) }
|
||||||
var intervalCount by remember(schedule) { mutableStateOf(parsed.intervalCount) }
|
var intervalCount by remember(schedule) { mutableStateOf(parsed.intervalCount) }
|
||||||
var intervalUnit by remember(schedule) { mutableStateOf(parsed.intervalUnit) }
|
var intervalUnit by remember(schedule) { mutableStateOf(parsed.intervalUnit) }
|
||||||
var selectedDays by remember(schedule) { mutableStateOf(parsed.selectedDays) }
|
var selectedDays by remember(schedule) { mutableStateOf(parsed.selectedDays) }
|
||||||
@@ -1055,6 +1055,8 @@ internal fun SchedulePickerSection(
|
|||||||
} else {
|
} else {
|
||||||
val fallback = parseSchedule(schedule)
|
val fallback = parseSchedule(schedule)
|
||||||
mode = fallback.mode
|
mode = fallback.mode
|
||||||
|
hour = fallback.hour
|
||||||
|
minute = fallback.minute
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ internal data class ParsedSchedule(
|
|||||||
val minute: Int = 0,
|
val minute: Int = 0,
|
||||||
val intervalCount: Int = 1,
|
val intervalCount: Int = 1,
|
||||||
val intervalUnit: String = "h",
|
val intervalUnit: String = "h",
|
||||||
val selectedDays: Set<Int> = setOf(1, 2, 3, 4, 5),
|
val selectedDays: Set<Int> = setOf(1),
|
||||||
val dayOfMonth: Int = 1,
|
val dayOfMonth: Int = 1,
|
||||||
val month: Int = 1,
|
val month: Int = 1,
|
||||||
val raw: String = "",
|
val raw: String = "",
|
||||||
|
|||||||
Reference in New Issue
Block a user