mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-24 19:00:26 +01:00
Add Notification profiles.
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
package org.thoughtcrime.securesms.notifications.profiles
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import org.thoughtcrime.securesms.util.toMillis
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDateTime
|
||||
import java.util.TimeZone
|
||||
|
||||
class NotificationProfileScheduleTest {
|
||||
|
||||
private val sunday0am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 0, 0, 0)
|
||||
private val sunday1am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 1, 0, 0)
|
||||
private val sunday9am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 9, 0, 0)
|
||||
private val sunday10pm: LocalDateTime = LocalDateTime.of(2021, 7, 4, 22, 0, 0)
|
||||
|
||||
private val monday0am: LocalDateTime = sunday0am.plusDays(1)
|
||||
private val monday1am: LocalDateTime = sunday1am.plusDays(1)
|
||||
private val monday9am: LocalDateTime = sunday9am.plusDays(1)
|
||||
private val monday10pm: LocalDateTime = sunday10pm.plusDays(1)
|
||||
|
||||
private val tuesday1am: LocalDateTime = sunday1am.plusDays(2)
|
||||
private val tuesday9am: LocalDateTime = sunday9am.plusDays(2)
|
||||
private val tuesday10pm: LocalDateTime = sunday10pm.plusDays(2)
|
||||
|
||||
companion object {
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun setup() {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
|
||||
@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()))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package org.thoughtcrime.securesms.notifications.profiles
|
||||
|
||||
import android.app.Application
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.Matchers.`is`
|
||||
import org.hamcrest.Matchers.nullValue
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import org.thoughtcrime.securesms.SignalStoreRule
|
||||
import org.thoughtcrime.securesms.keyvalue.NotificationProfileValues
|
||||
import org.thoughtcrime.securesms.util.toMillis
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(manifest = Config.NONE, application = Application::class)
|
||||
class NotificationProfilesTest {
|
||||
|
||||
private val sunday830am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 8, 30, 0)
|
||||
private val sunday9am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 9, 0, 0)
|
||||
private val sunday930am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 9, 30, 0)
|
||||
private val utc: ZoneId = ZoneId.of("UTC")
|
||||
|
||||
private val first = NotificationProfile(
|
||||
id = 1L,
|
||||
"first",
|
||||
"",
|
||||
createdAt = 1000L,
|
||||
schedule = NotificationProfileSchedule(1)
|
||||
)
|
||||
|
||||
private val second = NotificationProfile(
|
||||
id = 2L,
|
||||
"second",
|
||||
"",
|
||||
createdAt = 2000L,
|
||||
schedule = NotificationProfileSchedule(2)
|
||||
)
|
||||
|
||||
@get:Rule
|
||||
val signalStore: SignalStoreRule = SignalStoreRule()
|
||||
|
||||
@Test
|
||||
fun `when no profiles then return null`() {
|
||||
assertThat("no active profile", NotificationProfiles.getActiveProfile(emptyList(), 1000L, utc), nullValue())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when no manually enabled or schedule profiles then return null`() {
|
||||
val profiles = listOf(first, second)
|
||||
assertThat("no active profile", NotificationProfiles.getActiveProfile(profiles, 3000L, utc), nullValue())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when first is not enabled and second is manually enabled forever 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, 5000L)
|
||||
|
||||
val profiles = listOf(first, second)
|
||||
assertThat("active profile is profile second", NotificationProfiles.getActiveProfile(profiles, 3000L, utc), `is`(profiles[1]))
|
||||
}
|
||||
|
||||
@Test
|
||||
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]))
|
||||
}
|
||||
|
||||
@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())
|
||||
|
||||
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]))
|
||||
}
|
||||
|
||||
@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())
|
||||
|
||||
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]))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when first and second have overlapping schedules and second is created after first and now is within both then return second`() {
|
||||
val firstSchedule = NotificationProfileSchedule(id = 3L, true, start = 700, daysEnabled = setOf(DayOfWeek.SUNDAY))
|
||||
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]))
|
||||
}
|
||||
|
||||
@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())
|
||||
|
||||
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]))
|
||||
}
|
||||
|
||||
@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())
|
||||
|
||||
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]))
|
||||
}
|
||||
|
||||
@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())
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user