mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-26 20:55:10 +00:00
Fix various issues regarding Notification Profile scheduling.
- Timezone conversion when detecting scheduled profile - Not automatically enabling a scheduled profile on creation regardless of when other profiles were enabled/disabled
This commit is contained in:
@@ -7,6 +7,7 @@ import org.junit.Test
|
||||
import org.thoughtcrime.securesms.util.toMillis
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.util.TimeZone
|
||||
|
||||
class NotificationProfileScheduleTest {
|
||||
@@ -37,105 +38,105 @@ class NotificationProfileScheduleTest {
|
||||
fun `when time is within enabled schedule 9am to 5pm then return true`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 900, end = 1700, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.plusHours(1).toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.plusHours(1).toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when time is outside enabled schedule 9am to 5pm then return false`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 900, end = 1700, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
|
||||
assertFalse(schedule.isCurrentlyActive(sunday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when time is inside enabled with day wrapping schedule 10pm to 2am then return true`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 2100, end = 200, daysEnabled = setOf(DayOfWeek.MONDAY))
|
||||
|
||||
assertTrue(schedule.isCurrentlyActive(monday10pm.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday1am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(monday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday1am.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when time is outside enabled with day wrapping schedule 10pm to 2am then return false`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 2100, end = 200, daysEnabled = setOf(DayOfWeek.MONDAY))
|
||||
|
||||
assertFalse(schedule.isCurrentlyActive(sunday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday10pm.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when time is inside enabled schedule 12am to 10am then return false`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 0, end = 1000, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
|
||||
assertTrue(schedule.isCurrentlyActive(sunday0am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday1am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday0am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when time is inside enabled schedule 12am to 12am then return false`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 0, end = 2400, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
|
||||
assertTrue(schedule.isCurrentlyActive(sunday0am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday1am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday10pm.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday0am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday10pm.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when time is outside enabled schedule 12am to 12am then return false`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 0, end = 2400, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
|
||||
assertFalse(schedule.isCurrentlyActive(monday0am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday0am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday10pm.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when enabled schedule 12am to 12am for all days then return true`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = true, start = 0, end = 2400, daysEnabled = DayOfWeek.values().toSet())
|
||||
|
||||
assertTrue(schedule.isCurrentlyActive(sunday0am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday1am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday10pm.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(monday0am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(monday1am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(monday9am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(monday10pm.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday1am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday9am.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday10pm.toMillis()))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday0am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(sunday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(monday0am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(monday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(monday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(monday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertTrue(schedule.isCurrentlyActive(tuesday10pm.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when disabled schedule 12am to 12am for all days then return false`() {
|
||||
val schedule = NotificationProfileSchedule(id = 1L, enabled = false, start = 0, end = 2400, daysEnabled = DayOfWeek.values().toSet())
|
||||
|
||||
assertFalse(schedule.isCurrentlyActive(sunday0am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday0am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(monday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday1am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday10pm.toMillis()))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday0am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(sunday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday0am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(monday10pm.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday1am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday9am.toMillis(ZoneOffset.UTC)))
|
||||
assertFalse(schedule.isCurrentlyActive(tuesday10pm.toMillis(ZoneOffset.UTC)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.util.toMillis
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(manifest = Config.NONE, application = Application::class)
|
||||
@@ -69,30 +70,30 @@ class NotificationProfilesTest {
|
||||
fun `when first is scheduled and second is not manually enabled and now is within schedule return first`() {
|
||||
val schedule = NotificationProfileSchedule(id = 3L, true, start = 700, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val profiles = listOf(first.copy(schedule = schedule), second)
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(), utc), `is`(profiles[0]))
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(ZoneOffset.UTC), utc), `is`(profiles[0]))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when first is scheduled and second is manually enabled forever within first's schedule then return second`() {
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_PROFILE, second.id)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_UNTIL, Long.MAX_VALUE)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis())
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis(ZoneOffset.UTC))
|
||||
|
||||
val schedule = NotificationProfileSchedule(id = 3L, true, start = 700, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val profiles = listOf(first.copy(schedule = schedule), second)
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(), utc), `is`(profiles[1]))
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(ZoneOffset.UTC), utc), `is`(profiles[1]))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when first is scheduled and second is manually enabled forever before first's schedule start then return first`() {
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_PROFILE, second.id)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_UNTIL, Long.MAX_VALUE)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis())
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis(ZoneOffset.UTC))
|
||||
|
||||
val schedule = NotificationProfileSchedule(id = 3L, true, start = 900, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val profiles = listOf(first.copy(schedule = schedule), second)
|
||||
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday930am.toMillis(), utc), `is`(profiles[0]))
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday930am.toMillis(ZoneOffset.UTC), utc), `is`(profiles[0]))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -101,41 +102,41 @@ class NotificationProfilesTest {
|
||||
val secondSchedule = NotificationProfileSchedule(id = 4L, true, start = 800, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val profiles = listOf(first.copy(schedule = firstSchedule), second.copy(schedule = secondSchedule))
|
||||
|
||||
assertThat("active profile is second", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(), utc), `is`(profiles[1]))
|
||||
assertThat("active profile is second", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(ZoneOffset.UTC), utc), `is`(profiles[1]))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when first and second have overlapping schedules and first is created before second and first is manually enabled within overlapping schedule then return first`() {
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_PROFILE, first.id)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_UNTIL, Long.MAX_VALUE)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis())
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis(ZoneOffset.UTC))
|
||||
|
||||
val firstSchedule = NotificationProfileSchedule(id = 3L, true, start = 700, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val secondSchedule = NotificationProfileSchedule(id = 4L, true, start = 700, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val profiles = listOf(first.copy(schedule = firstSchedule), second.copy(schedule = secondSchedule))
|
||||
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(), utc), `is`(profiles[0]))
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(ZoneOffset.UTC), utc), `is`(profiles[0]))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when profile is manually enabled for set time after schedule end and now is after schedule end but before manual then return profile`() {
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_PROFILE, first.id)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_UNTIL, sunday930am.toMillis())
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis())
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_UNTIL, sunday930am.toMillis(ZoneOffset.UTC))
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis(ZoneOffset.UTC))
|
||||
|
||||
val schedule = NotificationProfileSchedule(id = 3L, true, start = 700, end = 845, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val profiles = listOf(first.copy(schedule = schedule))
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(), utc), `is`(profiles[0]))
|
||||
assertThat("active profile is first", NotificationProfiles.getActiveProfile(profiles, sunday9am.toMillis(ZoneOffset.UTC), utc), `is`(profiles[0]))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when profile is manually enabled for set time before schedule end and now is after manual but before schedule end then return null`() {
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_PROFILE, first.id)
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_UNTIL, sunday9am.toMillis())
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis())
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_ENABLED_UNTIL, sunday9am.toMillis(ZoneOffset.UTC))
|
||||
signalStore.dataSet.putLong(NotificationProfileValues.KEY_MANUALLY_DISABLED_AT, sunday830am.toMillis(ZoneOffset.UTC))
|
||||
|
||||
val schedule = NotificationProfileSchedule(id = 3L, true, start = 700, end = 1000, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
val profiles = listOf(first.copy(schedule = schedule))
|
||||
assertThat("active profile is null", NotificationProfiles.getActiveProfile(profiles, sunday930am.toMillis(), utc), nullValue())
|
||||
assertThat("active profile is null", NotificationProfiles.getActiveProfile(profiles, sunday930am.toMillis(ZoneOffset.UTC), utc), nullValue())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user