From 660009c4d5cdf4ff265b27cab8977ad8f7f0692e Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Mon, 11 Aug 2025 14:51:47 -0700 Subject: [PATCH 1/9] init test runners --- toolkit/featureforms/build.gradle.kts | 3 + .../src/androidTest/AndroidManifest.xml | 14 + .../toolkit/featureforms/AttachmentTests.kt | 4 +- .../toolkit/featureforms/BarcodeTests.kt | 12 +- .../featureforms/FeatureFormTestRunner.kt | 15 +- .../featureforms/MockingJayTestWatcher.kt | 251 ++++++++++++++++++ 6 files changed, 291 insertions(+), 8 deletions(-) create mode 100644 toolkit/featureforms/src/androidTest/AndroidManifest.xml create mode 100644 toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt diff --git a/toolkit/featureforms/build.gradle.kts b/toolkit/featureforms/build.gradle.kts index 240711e09..05aa60fbe 100644 --- a/toolkit/featureforms/build.gradle.kts +++ b/toolkit/featureforms/build.gradle.kts @@ -141,6 +141,9 @@ apiValidation { dependencies { api(arcgis.mapsSdk) + // mocking jay + implementation("com.esri:mockingjay:2.0.0") + // implementation(libs.bundles.commonmark) implementation(platform(libs.coil.bom)) implementation(libs.coil.compose) diff --git a/toolkit/featureforms/src/androidTest/AndroidManifest.xml b/toolkit/featureforms/src/androidTest/AndroidManifest.xml new file mode 100644 index 000000000..967bfe2ab --- /dev/null +++ b/toolkit/featureforms/src/androidTest/AndroidManifest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt index 41a4e8f2c..e5cc017d3 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.test.assertTextContains import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick +import com.esri.mockingjay.MockingJayConfiguration import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Rule @@ -31,7 +32,8 @@ import org.junit.Test class AttachmentTests : FeatureFormTestRunner( uri = "https://www.arcgis.com/home/item.html?id=3e551c383fc949c7982ec73ba67d409b", - objectId = 1 + objectId = 1, + mockMode = MockingJayConfiguration.Mode.CleanRecord ) { @get:Rule val composeTestRule = createComposeRule() diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt index 9958f20ad..0d1423585 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.test.requestFocus import androidx.test.rule.GrantPermissionRule import com.arcgismaps.mapping.featureforms.BarcodeScannerFormInput import com.arcgismaps.mapping.featureforms.FieldFormElement +import com.esri.mockingjay.MockingJayConfiguration import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay @@ -39,15 +40,16 @@ import org.junit.Test class BarcodeTests : FeatureFormTestRunner( uri = "https://www.arcgis.com/home/item.html?id=a14a825c22884dfe9998ac964bd1cf89", - objectId = 2L + objectId = 2L, + mockMode = MockingJayConfiguration.Mode.CleanRecord ) { @get:Rule val composeTestRule = createComposeRule() - // Grant camera permission for barcode scanning - @get:Rule - val runtimePermissionRule: GrantPermissionRule = - GrantPermissionRule.grant(Manifest.permission.CAMERA) +// // Grant camera permission for barcode scanning +// @get:Rule +// val runtimePermissionRule: GrantPermissionRule = +// GrantPermissionRule.grant(Manifest.permission.CAMERA) /** * Test case 11.1: diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt index 737b8f828..111414048 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt @@ -16,6 +16,8 @@ package com.arcgismaps.toolkit.featureforms +import android.Manifest +import androidx.test.rule.GrantPermissionRule import com.arcgismaps.ArcGISEnvironment import com.arcgismaps.LoadStatus import com.arcgismaps.Loadable @@ -29,9 +31,11 @@ import com.arcgismaps.httpcore.authentication.ServerTrust import com.arcgismaps.mapping.ArcGISMap import com.arcgismaps.mapping.featureforms.FeatureForm import com.arcgismaps.mapping.layers.FeatureLayer +import com.esri.mockingjay.MockingJayConfiguration import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before +import org.junit.Rule /** * A test runner for feature form tests. This class is responsible for loading the map with the @@ -52,8 +56,15 @@ open class FeatureFormTestRunner( private val objectId: Long, private val user: String = BuildConfig.webMapUser, private val password: String = BuildConfig.webMapPassword, - private val layerName: String = "" -) { + private val layerName: String = "", + mockMode : MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback +) : NetworkMockTestCase(mockMode = mockMode) { + +// @Rule +// @JvmField +// val writeRule : GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE, +// Manifest.permission.READ_EXTERNAL_STORAGE, ) + /** * The feature form for the feature with the given [objectId]. */ diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt new file mode 100644 index 000000000..6ac9c727f --- /dev/null +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt @@ -0,0 +1,251 @@ +/* + * Copyright 2025 Esri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.arcgismaps.toolkit.featureforms + +import android.content.Context +import android.database.CursorWindow +import android.os.Build +import android.os.Environment +import android.util.Log +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import com.arcgismaps.ArcGISEnvironment +import com.esri.logging.Logger +import com.esri.mockingjay.MockingJay +import com.esri.mockingjay.MockingJayConfiguration +import com.esri.mockingjay.MockingJayNetworkInterceptorImpl +import com.esri.mockingjay.MockingJayNetworkObserverImpl +import org.junit.runner.Description +import kotlinx.serialization.json.JsonPrimitive +import org.junit.rules.TestWatcher +import java.io.File +import java.lang.reflect.Field +import kotlin.apply +import org.junit.Rule +import org.junit.rules.TestRule +import org.junit.runners.model.Statement + +/** + * Mocks the network requests for a test class and replays the recorded responses when the flag + * [MockingJayConfiguration.Mode.Playback] is set. + * Controls before and after actions for a test class, see [BeforeAfterTestCase] for more details. + * + * @see [LiveNetwork] annotation to skip mocking for specific tests. + * + * @since 200.7.0 + */ +open class NetworkMockTestCase( + mockMode: MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback +) { + @get:Rule + val networkMockingTestWatcher = NetworkMockingTestWatcher(mockMode) +} + +/** + * A JUnit `TestRule` that conditionally applies the MockingJay network recorder and re-player. + * It skips mocking if the test is annotated with `@LiveNetwork`, allowing live network requests. + * @since 200.8.0 + */ +class NetworkMockingTestWatcher(private val mockMode: MockingJayConfiguration.Mode) : TestRule { + override fun apply(base: Statement, description: Description): Statement { + return if (description.getAnnotation(LiveNetwork::class.java) == null) { + MockingJayTestWatcher(mockMode).apply(base, description) + } else { + base + } + } +} + +/** + * Annotation to indicate that a test should bypass network mocking and allow live network requests. + * Useful for tests in a [NetworkMockTestCase] that require direct interaction with live network services. + * + * @since 200.8.0 + */ +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.FUNCTION) +annotation class LiveNetwork + + +/** + * A JUnit TestWatcher that sets up and tears down the MockingJay network recorder and re-player. + * + * @since 200.6.0 + */ +class MockingJayTestWatcher( + private val mode: MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback +) : TestWatcher() { + private val context: Context + get() = getInstrumentation().targetContext.applicationContext + + private val testDataPath: String = "${Environment.getExternalStorageDirectory()}/Data/androidKotlin" + + + override fun starting(description: Description) { + val testFolder = description.testClass.name.replace(".", "/") + Logger.log("----------- Starting test: ${description.methodName} -------------") + super.starting(description) + ArcGISEnvironment.applicationContext = context + + // Configure the ArcGIS HTTP client to use the MockingJay network re-player and recorder + ArcGISEnvironment.configureArcGISHttpClient { + interceptor(MockingJayNetworkInterceptorImpl.shared.interceptor) + interceptor(MockingJayNetworkObserverImpl.shared.interceptor) + } + + setupMockingJay(description.methodName, testFolder) + + // Increase the CursorWindow size to 100MB to store bigger files in SQL Lite + try { + val field: Field = CursorWindow::class.java.getDeclaredField("sCursorWindowSize") + field.isAccessible = true + field.set(null, 100 * 1024 * 1024) //the 100MB is the new size + } catch (e: Exception) { + e.printStackTrace() + } + } + + override fun finished(description: Description) { + val testFolder = description.testClass.name.replace(".", "/") + teardownMockingJay(description.methodName, testFolder) + } + + /** + * Sets up the MockingJay session and configures the ArcGIS HTTP client. + * + * @param databaseName The name of the database, obtained from the test name. + * @param folder The folder where the test data is located, obtained from the test package. + * + * @since 200.8.0 + */ + private fun setupMockingJay(databaseName: String, folder: String) { + val testName = "$databaseName.db" + + if (mode == MockingJayConfiguration.Mode.Playback) { + copyDatabaseForTest(testName, "$testDataPath/mocked-responses/$folder") + } + // Set the epoch to a distant future date to avoid token expiration issues + val distantFutureEpoch = JsonPrimitive(80808080808080) + // Configure the MockingJay session + val mockingJayConfiguration = + MockingJayConfiguration(testName, mode).apply { + + // headers and query parameters to remove from the recorded requests + headersToRemove.add("User-Agent") + + headerReplacements["X-Esri-Authorization"] = "Bearer dummyToken" + + queryParametersToRemove.add("edits") + + queryParameterReplacements["v"] = -1 + queryParameterReplacements["token"] = "dummyToken" + queryParameterReplacements["code"] = "dummyCode" + queryParameterReplacements["code_verifier"] = "dummyCodeVerifier" + queryParameterReplacements["username"] = "dummyUsername" + queryParameterReplacements["password"] = "dummyPassword" + queryParameterReplacements.putAll(queryParameterReplacements) + + jsonResponseKeyValueReplacements["access_token"] = JsonPrimitive("accessDummyToken") + jsonResponseKeyValueReplacements["refresh_token"] = JsonPrimitive("refreshDummyToken") + jsonResponseKeyValueReplacements["refresh_token_expires_in"] = distantFutureEpoch + jsonResponseKeyValueReplacements["token"] = JsonPrimitive("dummyToken") + jsonResponseKeyValueReplacements["expires"] = distantFutureEpoch + jsonResponseKeyValueReplacements["expires-in"] = distantFutureEpoch + + authenticationTokenParameterKeys.add("token") + authenticationHeaderParameterKeys.add("X-Esri-Authorization") + } + + MockingJay.startSession(mockingJayConfiguration, context) + } + + /** + * Copies the database file from the test folder to the Android database path. + * + * @since 200.8.0 + */ + private fun copyDatabaseForTest(testDBName: String, testFolderSrc: String) { + val testDatabase = context.getDatabasePath(testDBName) + if (testDatabase.exists()) { + testDatabase.delete() + } + + val src = File(testFolderSrc, testDBName) + if (!src.exists()) { + Logger.log("Database file $testDBName does not exist in $testFolderSrc") + } else { + src.copyTo(testDatabase, overwrite = true) + } + } + + /** + * Copies the database file from the Android database path to the specified test folder path. + * + * @since 200.8.0 + */ + private fun copyDatabaseToPath(testDBName: String, testFolderPath: String) { + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + return + } + val dbFile = context.getDatabasePath(testDBName) + if (dbFile.exists()) { + Log.e("TAG", "copyDatabaseToPath: ${dbFile.path}", ) + val destination = File(testFolderPath, testDBName) + dbFile.copyTo(destination, overwrite = true) + } else { + Logger.log("Database file $testDBName does not exist") + } + } + + /** + * Cleans up the MockingJay session and closes the ArcGIS HTTP client. + * + * @since 200.8.0 + */ + private fun teardownMockingJay(name: String, testFolderPath: String) { + endSession(name, testFolderPath) + ArcGISEnvironment.configureArcGISHttpClient() + Logger.log("----------- Finished test: $name -------------") + } + + /** + * Ends the MockingJay session and copies the database file to the specified test folder path. + * + * @since 200.8.0 + */ + private fun endSession(name: String, testFolderPath: String) { + val testName = "$name.db" + + MockingJay.endSession() + if (mode == MockingJayConfiguration.Mode.Playback) { + removeDatabase(testName) + } else { + copyDatabaseToPath(testName, "$testDataPath/mocked-responses/$testFolderPath") + } + } + + /** + * Removes the database file from the Android database path. + * + * @since 200.8.0 + */ + private fun removeDatabase(testDBName: String) { + val testDatabase = context.getDatabasePath(testDBName) + if (testDatabase.exists()) { + testDatabase.delete() + } + } +} From e82a8b364352d3c9cfdbc594fa765fad061fb557 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Wed, 13 Aug 2025 15:31:30 -0700 Subject: [PATCH 2/9] refactor plugin --- .../.kotlin/errors/errors-1755038697331.log | 4 + buildSrc/build.gradle.kts | 5 + .../src/main/kotlin/GrantTestPermissions.kt | 102 ++++++++++++++++++ gradle/libs.versions.toml | 2 + toolkit/featureforms/build.gradle.kts | 13 ++- .../src/androidTest/AndroidManifest.xml | 7 +- .../toolkit/featureforms/AttachmentTests.kt | 2 +- 7 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 buildSrc/.kotlin/errors/errors-1755038697331.log create mode 100644 buildSrc/src/main/kotlin/GrantTestPermissions.kt diff --git a/buildSrc/.kotlin/errors/errors-1755038697331.log b/buildSrc/.kotlin/errors/errors-1755038697331.log new file mode 100644 index 000000000..1219b509f --- /dev/null +++ b/buildSrc/.kotlin/errors/errors-1755038697331.log @@ -0,0 +1,4 @@ +kotlin version: 2.0.21 +error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output: + 1. Kotlin compile daemon is ready + diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 23abc5a14..309083bfb 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -35,5 +35,10 @@ gradlePlugin { id = "artifact-deploy" implementationClass = "deploy.ArtifactPublisher" } + + create("grantTestPermissions") { + id = "grant-test-permissions" + implementationClass = "GrantTestPermissions" + } } } diff --git a/buildSrc/src/main/kotlin/GrantTestPermissions.kt b/buildSrc/src/main/kotlin/GrantTestPermissions.kt new file mode 100644 index 000000000..a0d74a7b1 --- /dev/null +++ b/buildSrc/src/main/kotlin/GrantTestPermissions.kt @@ -0,0 +1,102 @@ +/* + * Copyright 2025 Esri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.kotlin.dsl.create +import java.io.File + +/** + * An extension to configure the [GrantTestPermissions] plugin. + */ +abstract class PermissionPluginExtension { + + /** + * The package name of the application for which permissions will be granted. + */ + abstract val packageName: Property + + /** + * The path to the ADB executable. + */ + abstract val adbPath: Property + + /** + * A list of permissions to be granted to the application. + * Each permission should be specified as a string, e.g., "android.permission.CAMERA". + */ + abstract val permissions: ListProperty +} + +/** + * A Gradle plugin to grant runtime permissions to a test application. This plugin is useful for + * Android instrumented tests that require specific permissions to be granted before running tests. + * It automates the process of granting permissions using ADB. + * + * @since 300.0.0 + */ +class GrantTestPermissions : Plugin { + override fun apply(project: Project) { + val extension = + project.extensions.create("grantTestPermissionsConfig") + val grantPermissionTask = project.tasks.register("grantTestPermissions") { + doLast { + val packageName = extension.packageName.get() + val adb = extension.adbPath.get() + val permissions = extension.permissions.get() + println("Granting permissions for package: $packageName") + permissions.forEach { permission -> + if (permission.contains("MANAGE_EXTERNAL_STORAGE")) { + // Special handling for MANAGE_EXTERNAL_STORAGE permission + project.providers.exec { + commandLine( + adb, + "shell", + "appops", + "set", + "--uid", + packageName, + "MANAGE_EXTERNAL_STORAGE", + "allow" + ) + }.result.get().assertNormalExitValue() + } else { + // General permission granting + project.providers.exec { + commandLine(adb, "shell", "pm", "grant", packageName, permission) + }.result.get().assertNormalExitValue() + } + println("Granted permission: $permission") + } + } + } + + project.afterEvaluate { + // Configure the grantPermissionTask runs right before the install task + project.tasks.matching { it.name.startsWith("install") && it.name.endsWith("AndroidTest") } + .forEach { installTask -> + grantPermissionTask.get().dependsOn(installTask) + } + // Configure the grantPermissionTask runs before connected tasks + project.tasks.matching { it.name.startsWith("connected") && it.name.endsWith("AndroidTest") } + .forEach { connectedTask -> + connectedTask.dependsOn(grantPermissionTask.get()) + } + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e6599e2bc..80496ecb4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ androidxTestExt = "1.2.1" androidXTestRunner = "1.6.2" androidXTestRules = "1.6.1" androidxWindow = "1.3.0" +mockingjay = "2.0.0" workVersion = "2.10.0" binaryCompatibilityValidator = "0.17.0" compileSdk = "36" @@ -91,6 +92,7 @@ kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", vers kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core", version.ref = "kotlinxSerializationJson" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinxCoroutinesTest" } +mockingjay = { module = "com.esri:mockingjay", version.ref = "mockingjay" } mockk-android = { module = "io.mockk:mockk-android", version.ref = "mockkAndroid" } room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } diff --git a/toolkit/featureforms/build.gradle.kts b/toolkit/featureforms/build.gradle.kts index 05aa60fbe..e54a99344 100644 --- a/toolkit/featureforms/build.gradle.kts +++ b/toolkit/featureforms/build.gradle.kts @@ -1,3 +1,5 @@ +import com.android.build.gradle.internal.tasks.factory.dependsOn + /* * * Copyright 2024 Esri @@ -23,6 +25,7 @@ plugins { id("artifact-deploy") id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") id("kotlin-parcelize") + id("grant-test-permissions") alias(libs.plugins.binary.compatibility.validator) apply true alias(libs.plugins.kotlin.serialization) apply true } @@ -44,14 +47,14 @@ android { disable += "MissingTranslation" disable += "MissingQuantity" } - + defaultConfig { minSdk = libs.versions.minSdk.get().toInt() - + testApplicationId = "com.arcgismaps.toolkit.featureforms.test" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") } - + buildTypes { release { isMinifyEnabled = false @@ -134,7 +137,7 @@ apiValidation { "com.arcgismaps.toolkit.featureforms.internal.navigation.NavigationAction\$None\$Creator", "com.arcgismaps.toolkit.featureforms.internal.components.dialogs.ComposableSingletons\$ConfirmationDialogsKt" ) - + ignoredClasses.addAll(composableSingletons) } @@ -142,7 +145,7 @@ apiValidation { dependencies { api(arcgis.mapsSdk) // mocking jay - implementation("com.esri:mockingjay:2.0.0") + implementation(libs.mockingjay) // implementation(libs.bundles.commonmark) implementation(platform(libs.coil.bom)) diff --git a/toolkit/featureforms/src/androidTest/AndroidManifest.xml b/toolkit/featureforms/src/androidTest/AndroidManifest.xml index 967bfe2ab..6474d6c46 100644 --- a/toolkit/featureforms/src/androidTest/AndroidManifest.xml +++ b/toolkit/featureforms/src/androidTest/AndroidManifest.xml @@ -1,8 +1,6 @@ - + - + @@ -10,5 +8,4 @@ - diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt index e5cc017d3..2179004f6 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt @@ -33,7 +33,7 @@ import org.junit.Test class AttachmentTests : FeatureFormTestRunner( uri = "https://www.arcgis.com/home/item.html?id=3e551c383fc949c7982ec73ba67d409b", objectId = 1, - mockMode = MockingJayConfiguration.Mode.CleanRecord + mockMode = MockingJayConfiguration.Mode.Playback ) { @get:Rule val composeTestRule = createComposeRule() From 11d2fe35e7abf5e72d0a393d217f59baa0a55cd3 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 14 Aug 2025 11:49:12 -0700 Subject: [PATCH 3/9] fix config vars --- buildSrc/src/main/kotlin/GrantTestPermissions.kt | 4 ++-- toolkit/featureforms/build.gradle.kts | 13 +++++++++++++ .../toolkit/featureforms/BarcodeTests.kt | 14 +------------- .../toolkit/featureforms/FeatureFormTestRunner.kt | 10 ---------- .../toolkit/featureforms/MockingJayTestWatcher.kt | 2 +- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/buildSrc/src/main/kotlin/GrantTestPermissions.kt b/buildSrc/src/main/kotlin/GrantTestPermissions.kt index a0d74a7b1..5f10d912d 100644 --- a/buildSrc/src/main/kotlin/GrantTestPermissions.kt +++ b/buildSrc/src/main/kotlin/GrantTestPermissions.kt @@ -87,12 +87,12 @@ class GrantTestPermissions : Plugin { } project.afterEvaluate { - // Configure the grantPermissionTask runs right before the install task + // Configure the task runs right after the install task project.tasks.matching { it.name.startsWith("install") && it.name.endsWith("AndroidTest") } .forEach { installTask -> grantPermissionTask.get().dependsOn(installTask) } - // Configure the grantPermissionTask runs before connected tasks + // Configure the task runs before the connectedAndroidTest tasks project.tasks.matching { it.name.startsWith("connected") && it.name.endsWith("AndroidTest") } .forEach { connectedTask -> connectedTask.dependsOn(grantPermissionTask.get()) diff --git a/toolkit/featureforms/build.gradle.kts b/toolkit/featureforms/build.gradle.kts index e54a99344..a4deaadfd 100644 --- a/toolkit/featureforms/build.gradle.kts +++ b/toolkit/featureforms/build.gradle.kts @@ -102,6 +102,19 @@ android { } } +grantTestPermissionsConfig { + packageName.set(android.defaultConfig.testApplicationId) + adbPath.set(android.adbExecutable.absoluteFile) + permissions.set( + listOf( + "android.permission.CAMERA", + "android.permission.WRITE_EXTERNAL_STORAGE", + "android.permission.READ_EXTERNAL_STORAGE", + "android.permission.MANAGE_EXTERNAL_STORAGE" + ) + ) +} + apiValidation { ignoredClasses.add("com.arcgismaps.toolkit.featureforms.BuildConfig") // todo: remove when this is resolved https://github.com/Kotlin/binary-compatibility-validator/issues/74 diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt index 0d1423585..251da7298 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/BarcodeTests.kt @@ -16,7 +16,6 @@ package com.arcgismaps.toolkit.featureforms -import android.Manifest import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsFocused import androidx.compose.ui.test.junit4.createComposeRule @@ -25,32 +24,21 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTextInput import androidx.compose.ui.test.requestFocus -import androidx.test.rule.GrantPermissionRule import com.arcgismaps.mapping.featureforms.BarcodeScannerFormInput import com.arcgismaps.mapping.featureforms.FieldFormElement -import com.esri.mockingjay.MockingJayConfiguration import com.google.common.truth.Truth.assertThat -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test class BarcodeTests : FeatureFormTestRunner( uri = "https://www.arcgis.com/home/item.html?id=a14a825c22884dfe9998ac964bd1cf89", - objectId = 2L, - mockMode = MockingJayConfiguration.Mode.CleanRecord + objectId = 2L ) { @get:Rule val composeTestRule = createComposeRule() -// // Grant camera permission for barcode scanning -// @get:Rule -// val runtimePermissionRule: GrantPermissionRule = -// GrantPermissionRule.grant(Manifest.permission.CAMERA) - /** * Test case 11.1: * Given a `FeatureForm` with a `BarcodeScannerFormInput` diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt index 111414048..0fcb15d0f 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt @@ -16,15 +16,11 @@ package com.arcgismaps.toolkit.featureforms -import android.Manifest -import androidx.test.rule.GrantPermissionRule import com.arcgismaps.ArcGISEnvironment import com.arcgismaps.LoadStatus import com.arcgismaps.Loadable import com.arcgismaps.data.ArcGISFeature import com.arcgismaps.data.QueryParameters -import com.arcgismaps.httpcore.authentication.ArcGISAuthenticationChallengeResponse -import com.arcgismaps.httpcore.authentication.NetworkAuthenticationChallenge import com.arcgismaps.httpcore.authentication.NetworkAuthenticationChallengeHandler import com.arcgismaps.httpcore.authentication.NetworkAuthenticationChallengeResponse import com.arcgismaps.httpcore.authentication.ServerTrust @@ -35,7 +31,6 @@ import com.esri.mockingjay.MockingJayConfiguration import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before -import org.junit.Rule /** * A test runner for feature form tests. This class is responsible for loading the map with the @@ -60,11 +55,6 @@ open class FeatureFormTestRunner( mockMode : MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback ) : NetworkMockTestCase(mockMode = mockMode) { -// @Rule -// @JvmField -// val writeRule : GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE, -// Manifest.permission.READ_EXTERNAL_STORAGE, ) - /** * The feature form for the feature with the given [objectId]. */ diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt index 6ac9c727f..e3bb159e9 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt @@ -135,7 +135,7 @@ class MockingJayTestWatcher( val testName = "$databaseName.db" if (mode == MockingJayConfiguration.Mode.Playback) { - copyDatabaseForTest(testName, "$testDataPath/mocked-responses/$folder") + copyDatabaseForTest(testName, "$testDataPath/test-data/mockingjay/$folder") } // Set the epoch to a distant future date to avoid token expiration issues val distantFutureEpoch = JsonPrimitive(80808080808080) From 65d49ceda61553f9ace3b6c4bd78fc3b91519e81 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 14 Aug 2025 14:29:12 -0700 Subject: [PATCH 4/9] update tests to use mock class --- .../com/arcgismaps/toolkit/featureforms/AttachmentTests.kt | 4 +--- .../featureforms/UtilityAssociationsFormElementTests.kt | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt index 2179004f6..41a4e8f2c 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt @@ -24,7 +24,6 @@ import androidx.compose.ui.test.assertTextContains import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick -import com.esri.mockingjay.MockingJayConfiguration import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Rule @@ -32,8 +31,7 @@ import org.junit.Test class AttachmentTests : FeatureFormTestRunner( uri = "https://www.arcgis.com/home/item.html?id=3e551c383fc949c7982ec73ba67d409b", - objectId = 1, - mockMode = MockingJayConfiguration.Mode.Playback + objectId = 1 ) { @get:Rule val composeTestRule = createComposeRule() diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/UtilityAssociationsFormElementTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/UtilityAssociationsFormElementTests.kt index 9d7992c4f..a6574343a 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/UtilityAssociationsFormElementTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/UtilityAssociationsFormElementTests.kt @@ -38,6 +38,7 @@ import com.arcgismaps.mapping.ArcGISMap import com.arcgismaps.mapping.featureforms.FeatureForm import com.arcgismaps.mapping.featureforms.UtilityAssociationsFormElement import com.arcgismaps.mapping.layers.FeatureLayer +import com.esri.mockingjay.MockingJayConfiguration import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -46,7 +47,7 @@ import org.junit.Before import org.junit.Rule import org.junit.Test -class UtilityAssociationsFormElementTests { +class UtilityAssociationsFormElementTests : NetworkMockTestCase() { private lateinit var map: ArcGISMap From 9f1e58aba743b87ea434be9c9086fc52eea89ead Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Sun, 17 Aug 2025 10:50:56 -0700 Subject: [PATCH 5/9] add log interceptor --- .../toolkit/featureforms/FeatureFormTestRunner.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt index 0fcb15d0f..550546120 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt @@ -16,6 +16,7 @@ package com.arcgismaps.toolkit.featureforms +import android.util.Log import com.arcgismaps.ArcGISEnvironment import com.arcgismaps.LoadStatus import com.arcgismaps.Loadable @@ -63,6 +64,17 @@ open class FeatureFormTestRunner( @Before fun setup(): Unit = runTest { + ArcGISEnvironment.configureArcGISHttpClient { + interceptor { chain -> + val request = chain.request() + Log.e("FeatureFormTestRunner", ": --- Request --->", ) + Log.e("FeatureFormTestRunner", ": ${request.method} ${request.url}", ) + Log.e("FeatureFormTestRunner", ": ${request.headers}", ) + Log.e("FeatureFormTestRunner", ": ${request.parameters}", ) + Log.e("FeatureFormTestRunner", ": <--- END Request ---", ) + chain.proceed(request) + } + } // If the feature form is already initialized, return if (::featureForm.isInitialized) return@runTest // Set the authentication challenge handler From 64fc1ddd18d99f20aad726ac1b14ddd5aa8b72ad Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Sun, 17 Aug 2025 10:53:40 -0700 Subject: [PATCH 6/9] add logs --- .../toolkit/featureforms/AttachmentTests.kt | 3 ++- .../featureforms/FeatureFormTestRunner.kt | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt index 41a4e8f2c..33ef24269 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt @@ -31,7 +31,8 @@ import org.junit.Test class AttachmentTests : FeatureFormTestRunner( uri = "https://www.arcgis.com/home/item.html?id=3e551c383fc949c7982ec73ba67d409b", - objectId = 1 + objectId = 1, + log = true ) { @get:Rule val composeTestRule = createComposeRule() diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt index 550546120..9a120ecf0 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt @@ -53,7 +53,8 @@ open class FeatureFormTestRunner( private val user: String = BuildConfig.webMapUser, private val password: String = BuildConfig.webMapPassword, private val layerName: String = "", - mockMode : MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback + mockMode : MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback, + private val log : Boolean = false ) : NetworkMockTestCase(mockMode = mockMode) { /** @@ -64,15 +65,17 @@ open class FeatureFormTestRunner( @Before fun setup(): Unit = runTest { - ArcGISEnvironment.configureArcGISHttpClient { - interceptor { chain -> - val request = chain.request() - Log.e("FeatureFormTestRunner", ": --- Request --->", ) - Log.e("FeatureFormTestRunner", ": ${request.method} ${request.url}", ) - Log.e("FeatureFormTestRunner", ": ${request.headers}", ) - Log.e("FeatureFormTestRunner", ": ${request.parameters}", ) - Log.e("FeatureFormTestRunner", ": <--- END Request ---", ) - chain.proceed(request) + if (log) { + ArcGISEnvironment.configureArcGISHttpClient { + interceptor { chain -> + val request = chain.request() + Log.e("FeatureFormTestRunner", ": --- Request --->",) + Log.e("FeatureFormTestRunner", ": ${request.method} ${request.url}",) + Log.e("FeatureFormTestRunner", ": ${request.headers}",) + Log.e("FeatureFormTestRunner", ": ${request.parameters}",) + Log.e("FeatureFormTestRunner", ": <--- END Request ---",) + chain.proceed(request) + } } } // If the feature form is already initialized, return From 765d072c343cc178856f1329e9d670c0256a18f2 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Mon, 18 Aug 2025 11:07:17 -0700 Subject: [PATCH 7/9] Delete buildSrc/.kotlin/errors/errors-1755038697331.log --- buildSrc/.kotlin/errors/errors-1755038697331.log | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 buildSrc/.kotlin/errors/errors-1755038697331.log diff --git a/buildSrc/.kotlin/errors/errors-1755038697331.log b/buildSrc/.kotlin/errors/errors-1755038697331.log deleted file mode 100644 index 1219b509f..000000000 --- a/buildSrc/.kotlin/errors/errors-1755038697331.log +++ /dev/null @@ -1,4 +0,0 @@ -kotlin version: 2.0.21 -error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output: - 1. Kotlin compile daemon is ready - From f108f01b7f0298f79be9e310cf08b777c6e51ae8 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Mon, 18 Aug 2025 11:10:34 -0700 Subject: [PATCH 8/9] remove logging --- toolkit/featureforms/build.gradle.kts | 3 --- .../toolkit/featureforms/AttachmentTests.kt | 3 +-- .../featureforms/FeatureFormTestRunner.kt | 17 +----------- .../featureforms/MockingJayTestWatcher.kt | 27 ++++++------------- 4 files changed, 10 insertions(+), 40 deletions(-) diff --git a/toolkit/featureforms/build.gradle.kts b/toolkit/featureforms/build.gradle.kts index a4deaadfd..3518c3a3d 100644 --- a/toolkit/featureforms/build.gradle.kts +++ b/toolkit/featureforms/build.gradle.kts @@ -1,5 +1,3 @@ -import com.android.build.gradle.internal.tasks.factory.dependsOn - /* * * Copyright 2024 Esri @@ -150,7 +148,6 @@ apiValidation { "com.arcgismaps.toolkit.featureforms.internal.navigation.NavigationAction\$None\$Creator", "com.arcgismaps.toolkit.featureforms.internal.components.dialogs.ComposableSingletons\$ConfirmationDialogsKt" ) - ignoredClasses.addAll(composableSingletons) } diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt index 33ef24269..41a4e8f2c 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/AttachmentTests.kt @@ -31,8 +31,7 @@ import org.junit.Test class AttachmentTests : FeatureFormTestRunner( uri = "https://www.arcgis.com/home/item.html?id=3e551c383fc949c7982ec73ba67d409b", - objectId = 1, - log = true + objectId = 1 ) { @get:Rule val composeTestRule = createComposeRule() diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt index 9a120ecf0..0fcb15d0f 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/FeatureFormTestRunner.kt @@ -16,7 +16,6 @@ package com.arcgismaps.toolkit.featureforms -import android.util.Log import com.arcgismaps.ArcGISEnvironment import com.arcgismaps.LoadStatus import com.arcgismaps.Loadable @@ -53,8 +52,7 @@ open class FeatureFormTestRunner( private val user: String = BuildConfig.webMapUser, private val password: String = BuildConfig.webMapPassword, private val layerName: String = "", - mockMode : MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback, - private val log : Boolean = false + mockMode : MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback ) : NetworkMockTestCase(mockMode = mockMode) { /** @@ -65,19 +63,6 @@ open class FeatureFormTestRunner( @Before fun setup(): Unit = runTest { - if (log) { - ArcGISEnvironment.configureArcGISHttpClient { - interceptor { chain -> - val request = chain.request() - Log.e("FeatureFormTestRunner", ": --- Request --->",) - Log.e("FeatureFormTestRunner", ": ${request.method} ${request.url}",) - Log.e("FeatureFormTestRunner", ": ${request.headers}",) - Log.e("FeatureFormTestRunner", ": ${request.parameters}",) - Log.e("FeatureFormTestRunner", ": <--- END Request ---",) - chain.proceed(request) - } - } - } // If the feature form is already initialized, return if (::featureForm.isInitialized) return@runTest // Set the authentication challenge handler diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt index e3bb159e9..826042a7a 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt @@ -41,11 +41,10 @@ import org.junit.runners.model.Statement /** * Mocks the network requests for a test class and replays the recorded responses when the flag * [MockingJayConfiguration.Mode.Playback] is set. - * Controls before and after actions for a test class, see [BeforeAfterTestCase] for more details. * * @see [LiveNetwork] annotation to skip mocking for specific tests. * - * @since 200.7.0 + * @since 300.0.0 */ open class NetworkMockTestCase( mockMode: MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback @@ -73,7 +72,7 @@ class NetworkMockingTestWatcher(private val mockMode: MockingJayConfiguration.Mo * Annotation to indicate that a test should bypass network mocking and allow live network requests. * Useful for tests in a [NetworkMockTestCase] that require direct interaction with live network services. * - * @since 200.8.0 + * @since 300.0.0 */ @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FUNCTION) @@ -83,7 +82,7 @@ annotation class LiveNetwork /** * A JUnit TestWatcher that sets up and tears down the MockingJay network recorder and re-player. * - * @since 200.6.0 + * @since 300.0.0 */ class MockingJayTestWatcher( private val mode: MockingJayConfiguration.Mode = MockingJayConfiguration.Mode.Playback @@ -91,7 +90,8 @@ class MockingJayTestWatcher( private val context: Context get() = getInstrumentation().targetContext.applicationContext - private val testDataPath: String = "${Environment.getExternalStorageDirectory()}/Data/androidKotlin" + private val testDataPath: String = + "${Environment.getExternalStorageDirectory()}/Data/androidKotlin" override fun starting(description: Description) { @@ -128,8 +128,6 @@ class MockingJayTestWatcher( * * @param databaseName The name of the database, obtained from the test name. * @param folder The folder where the test data is located, obtained from the test package. - * - * @since 200.8.0 */ private fun setupMockingJay(databaseName: String, folder: String) { val testName = "$databaseName.db" @@ -159,7 +157,8 @@ class MockingJayTestWatcher( queryParameterReplacements.putAll(queryParameterReplacements) jsonResponseKeyValueReplacements["access_token"] = JsonPrimitive("accessDummyToken") - jsonResponseKeyValueReplacements["refresh_token"] = JsonPrimitive("refreshDummyToken") + jsonResponseKeyValueReplacements["refresh_token"] = + JsonPrimitive("refreshDummyToken") jsonResponseKeyValueReplacements["refresh_token_expires_in"] = distantFutureEpoch jsonResponseKeyValueReplacements["token"] = JsonPrimitive("dummyToken") jsonResponseKeyValueReplacements["expires"] = distantFutureEpoch @@ -174,8 +173,6 @@ class MockingJayTestWatcher( /** * Copies the database file from the test folder to the Android database path. - * - * @since 200.8.0 */ private fun copyDatabaseForTest(testDBName: String, testFolderSrc: String) { val testDatabase = context.getDatabasePath(testDBName) @@ -193,8 +190,6 @@ class MockingJayTestWatcher( /** * Copies the database file from the Android database path to the specified test folder path. - * - * @since 200.8.0 */ private fun copyDatabaseToPath(testDBName: String, testFolderPath: String) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { @@ -202,7 +197,7 @@ class MockingJayTestWatcher( } val dbFile = context.getDatabasePath(testDBName) if (dbFile.exists()) { - Log.e("TAG", "copyDatabaseToPath: ${dbFile.path}", ) + Log.e("TAG", "copyDatabaseToPath: ${dbFile.path}") val destination = File(testFolderPath, testDBName) dbFile.copyTo(destination, overwrite = true) } else { @@ -212,8 +207,6 @@ class MockingJayTestWatcher( /** * Cleans up the MockingJay session and closes the ArcGIS HTTP client. - * - * @since 200.8.0 */ private fun teardownMockingJay(name: String, testFolderPath: String) { endSession(name, testFolderPath) @@ -223,8 +216,6 @@ class MockingJayTestWatcher( /** * Ends the MockingJay session and copies the database file to the specified test folder path. - * - * @since 200.8.0 */ private fun endSession(name: String, testFolderPath: String) { val testName = "$name.db" @@ -239,8 +230,6 @@ class MockingJayTestWatcher( /** * Removes the database file from the Android database path. - * - * @since 200.8.0 */ private fun removeDatabase(testDBName: String) { val testDatabase = context.getDatabasePath(testDBName) From 443d19fe0e3dc6c6c88278d43916695ab86cf1fb Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Mon, 18 Aug 2025 11:12:27 -0700 Subject: [PATCH 9/9] update since tags --- .../arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt index 826042a7a..632128ab4 100644 --- a/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt +++ b/toolkit/featureforms/src/androidTest/java/com/arcgismaps/toolkit/featureforms/MockingJayTestWatcher.kt @@ -56,7 +56,8 @@ open class NetworkMockTestCase( /** * A JUnit `TestRule` that conditionally applies the MockingJay network recorder and re-player. * It skips mocking if the test is annotated with `@LiveNetwork`, allowing live network requests. - * @since 200.8.0 + * + * @since 300.0.0 */ class NetworkMockingTestWatcher(private val mockMode: MockingJayConfiguration.Mode) : TestRule { override fun apply(base: Statement, description: Description): Statement {