Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit f47adbef authored by Ricki Hirner's avatar Ricki Hirner
Browse files

Wrap GrantPermissionRule into InitCalendarProviderRule

Closes bitfireAT/davx5#127
parent 94c9f869
Loading
Loading
Loading
Loading
+58 −37
Original line number Diff line number Diff line
@@ -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,29 +20,55 @@ 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)")
    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()

            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")
@@ -57,19 +87,10 @@ class InitCalendarProviderRule : TestRule {
                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()
                }
            }
            } finally {
            Logger.log.info("After test: $description")
                calendar.delete()
            }
        }
    }

}
 No newline at end of file
+2 −6
Original line number Diff line number Diff line
@@ -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

+2 −6
Original line number Diff line number Diff line
@@ -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)