diff options
author | Ricki Hirner <hirner@bitfire.at> | 2022-08-31 17:47:42 +0300 |
---|---|---|
committer | Ricki Hirner <hirner@bitfire.at> | 2022-08-31 18:16:56 +0300 |
commit | f47adbef4a75333401e050b56ea2d96159ef55a8 (patch) | |
tree | cc322dd6fcaea4c71d17a0f80dbeca0467e8ff7f | |
parent | 94c9f869c92941f38783b6d7c9ce7c41350cc885 (diff) |
Wrap GrantPermissionRule into InitCalendarProviderRule
Closes bitfireAT/davx5#127
3 files changed, 62 insertions, 49 deletions
diff --git a/app/src/androidTest/java/at/bitfire/davdroid/InitCalendarProviderRule.kt b/app/src/androidTest/java/at/bitfire/davdroid/InitCalendarProviderRule.kt index bcbe1e1b..89bdc46f 100644 --- a/app/src/androidTest/java/at/bitfire/davdroid/InitCalendarProviderRule.kt +++ b/app/src/androidTest/java/at/bitfire/davdroid/InitCalendarProviderRule.kt @@ -4,11 +4,15 @@ package at.bitfire.davdroid +import android.Manifest import android.accounts.Account import android.content.ContentUris import android.content.ContentValues +import android.os.Build import android.provider.CalendarContract +import androidx.annotation.RequiresApi import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.rule.GrantPermissionRule import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.resource.LocalCalendar import at.bitfire.davdroid.resource.LocalEvent @@ -16,60 +20,77 @@ import at.bitfire.ical4android.AndroidCalendar import at.bitfire.ical4android.Event import net.fortuna.ical4j.model.property.DtStart import net.fortuna.ical4j.model.property.RRule +import org.junit.rules.RuleChain import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement /** - * JUnit ClassRule which initializes the AOSP CalendarProvider - * Needed for some "flaky" tests which would otherwise only succeed on second run + * JUnit ClassRule which initializes the AOSP CalendarProvider. + * Needed for some "flaky" tests which would otherwise only succeed on second run. + * + * Currently tested on development machine (Ryzen) with Android 12 images (with/without Google Play). + * Calendar provider behaves quite randomly, so it may or may not work. If you (the reader + * if this comment) can find out on how to initialize the calendar provider so that the + * tests are reliably run after `adb shell pm clear com.android.providers.calendar`, + * please let us know! + * + * If you run tests manually, just make sure to ignore the first run after the calendar + * provider has been accessed the first time. */ -class InitCalendarProviderRule : TestRule { +class InitCalendarProviderRule private constructor(): TestRule { companion object { - private val account = Account("LocalCalendarTest", CalendarContract.ACCOUNT_TYPE_LOCAL) - private val context = InstrumentationRegistry.getInstrumentation().targetContext - private val provider = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!! - private val uri = AndroidCalendar.create(account, provider, ContentValues()) - private val calendar = AndroidCalendar.findByID(account, provider, LocalCalendar.Factory, ContentUris.parseId(uri)) + fun getInstance() = RuleChain + .outerRule(GrantPermissionRule.grant(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR)) + .around(InitCalendarProviderRule()) } override fun apply(base: Statement, description: Description): Statement { - Logger.log.info("Before test: ${description.displayName}") + Logger.log.info("Initializing calendar provider before running ${description.displayName}") + return InitCalendarProviderStatement(base) + } - Logger.log.info("Initializing CalendarProvider (InitCalendarProviderRule)") - // single event init - val normalEvent = Event().apply { - dtStart = DtStart("20220120T010203Z") - summary = "Event with 1 instance" - } - val normalLocalEvent = LocalEvent(calendar, normalEvent, null, null, null, 0) - normalLocalEvent.add() - LocalEvent.numInstances(provider, account, normalLocalEvent.id!!) + class InitCalendarProviderStatement(val base: Statement): Statement() { + + override fun evaluate() { + if (Build.VERSION.SDK_INT < 31) + Logger.log.warning("Calendar provider initialization may or may not work. See InitCalendarProviderRule") + initCalendarProvider() - // recurring event init - val recurringEvent = Event().apply { - dtStart = DtStart("20220120T010203Z") - summary = "Event over 22 years" - rRules.add(RRule("FREQ=YEARLY;UNTIL=20740119T010203Z")) // year needs to be >2074 (not supported by Android <11 Calendar Storage) + base.evaluate() } - val localRecurringEvent = LocalEvent(calendar, recurringEvent, null, null, null, 0) - localRecurringEvent.add() - LocalEvent.numInstances(provider, account, localRecurringEvent.id!!) - // Run test - Logger.log.info("Evaluating test..") - return try { - object : Statement() { - @Throws(Throwable::class) - override fun evaluate() { - base.evaluate() + private fun initCalendarProvider() { + val account = Account("LocalCalendarTest", CalendarContract.ACCOUNT_TYPE_LOCAL) + val context = InstrumentationRegistry.getInstrumentation().targetContext + val provider = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!! + val uri = AndroidCalendar.create(account, provider, ContentValues()) + val calendar = AndroidCalendar.findByID(account, provider, LocalCalendar.Factory, ContentUris.parseId(uri)) + try { + // single event init + val normalEvent = Event().apply { + dtStart = DtStart("20220120T010203Z") + summary = "Event with 1 instance" } + val normalLocalEvent = LocalEvent(calendar, normalEvent, null, null, null, 0) + normalLocalEvent.add() + LocalEvent.numInstances(provider, account, normalLocalEvent.id!!) + + // recurring event init + val recurringEvent = Event().apply { + dtStart = DtStart("20220120T010203Z") + summary = "Event over 22 years" + rRules.add(RRule("FREQ=YEARLY;UNTIL=20740119T010203Z")) // year needs to be >2074 (not supported by Android <11 Calendar Storage) + } + val localRecurringEvent = LocalEvent(calendar, recurringEvent, null, null, null, 0) + localRecurringEvent.add() + LocalEvent.numInstances(provider, account, localRecurringEvent.id!!) + } finally { + calendar.delete() } - } finally { - Logger.log.info("After test: $description") - calendar.delete() } } -} + +}
\ No newline at end of file diff --git a/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalCalendarTest.kt b/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalCalendarTest.kt index a92cc256..945a180d 100644 --- a/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalCalendarTest.kt +++ b/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalCalendarTest.kt @@ -31,12 +31,8 @@ class LocalCalendarTest { companion object { @JvmField - @ClassRule(order = 0) - val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR)!! - - @JvmField - @ClassRule(order = 1) - val initCalendarProviderRule: TestRule = InitCalendarProviderRule() + @ClassRule + val initCalendarProviderRule: TestRule = InitCalendarProviderRule.getInstance() private lateinit var provider: ContentProviderClient diff --git a/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalEventTest.kt b/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalEventTest.kt index 24d65ed7..b76349ee 100644 --- a/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalEventTest.kt +++ b/app/src/androidTest/java/at/bitfire/davdroid/resource/LocalEventTest.kt @@ -34,12 +34,8 @@ class LocalEventTest { companion object { @JvmField - @ClassRule(order = 0) - val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR)!! - - @JvmField - @ClassRule(order = 1) - val initCalendarProviderRule: TestRule = InitCalendarProviderRule() + @ClassRule + val initCalendarProviderRule: TestRule = InitCalendarProviderRule.getInstance() private val account = Account("LocalCalendarTest", ACCOUNT_TYPE_LOCAL) |