diff --git a/.gitignore b/.gitignore index fa0506f..89f36f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .idea .gradle +.kotlin local.properties build capture +app/release diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 04ce6af..0000000 --- a/app/build.gradle +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright 2020 Google LLC - * - * 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 - * - * https://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. - */ -apply plugin: 'com.android.application' -apply plugin: 'com.google.android.gms.strict-version-matcher-plugin' -apply plugin: 'kotlin-android' -apply plugin: 'com.google.android.gms.oss-licenses-plugin' - -android { - compileSdkVersion 30 - - defaultConfig { - applicationId "com.amapi.extensibility.demo" - minSdkVersion 21 - targetSdkVersion 30 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') - } - } - - compileOptions { - // Flag to enable support for the new language APIs - coreLibraryDesugaringEnabled true - - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - freeCompilerArgs = ['-Xjvm-default=enable'] - jvmTarget = '1.8' - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - - implementation 'io.grpc:grpc-okhttp:1.44.0' // CURRENT_GRPC_VERSION - implementation 'com.google.android.libraries.enterprise.amapi:amapi:1.0.1' - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.5.0' - implementation 'androidx.appcompat:appcompat:1.3.0' - implementation 'com.google.android.material:material:1.2.1' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0' - implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' - implementation 'com.google.guava:guava:30.0-android' - implementation 'androidx.core:core:1.3.2' - implementation 'com.google.android.gms:play-services-oss-licenses:17.0.0' - - testImplementation 'junit:junit:4.12' - - androidTestImplementation 'androidx.test:rules:1.1.0' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test:runner:1.1.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..1ab97ee --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,89 @@ +/* Copyright 2020 Google LLC + * + * 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 + * + * https://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. + */ +//classpath("com.google.android.gms:strict-version-matcher-plugin:1.2.4") + +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) +// id("com.google.android.gms.strict-version-matcher-plugin") + id("com.google.android.gms.oss-licenses-plugin") +} + +android { + namespace = "com.amapi.extensibility.demo" + compileSdk = 35 + + defaultConfig { + applicationId = "com.amapi.extensibility.demo" + minSdk = 21 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + debug { + isMinifyEnabled = false + isDebuggable = true + } + + release { + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + + buildFeatures { + viewBinding = true + } +} + +dependencies { +// implementation 'io.grpc:grpc-okhttp:1.44.0' // CURRENT_GRPC_VERSION +// implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +// implementation 'com.google.android.material:material:1.12.0' +// implementation 'androidx.constraintlayout:constraintlayout:2.2.1' +// implementation 'androidx.constraintlayout:constraintlayout:2.2.1' +// implementation 'com.google.android.gms:play-services-oss-licenses:17.1.0' + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraint.layout) + api(libs.amapi) + implementation(libs.play.services.oss.licenses) + implementation(libs.material) + implementation(libs.androidx.constraint.layout) + implementation(libs.androidx.constraint.layout) + implementation(libs.coroutines) + + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.rules) + androidTestImplementation(libs.androidx.runner) + androidTestImplementation(libs.androidx.espresso.core) +} diff --git a/app/src/androidTest/java/com/amapi/extensibility/demo/commands/CommandTest.kt b/app/src/androidTest/java/com/amapi/extensibility/demo/commands/CommandTest.kt index 3e922a5..8fef9bb 100644 --- a/app/src/androidTest/java/com/amapi/extensibility/demo/commands/CommandTest.kt +++ b/app/src/androidTest/java/com/amapi/extensibility/demo/commands/CommandTest.kt @@ -18,36 +18,75 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.replaceText import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withSubstring +import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.rule.ActivityTestRule import com.amapi.extensibility.demo.R import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -/** Tests main activity from test app. */ +/** + * Instrumentation tests for CommandActivity. + */ @RunWith(AndroidJUnit4::class) class CommandTest { - @Rule - @JvmField - var mActivityRule: ActivityTestRule = - ActivityTestRule(CommandActivity::class.java) + /** + * Replaced ActivityTestRule with ActivityScenarioRule to better manage the Activity's lifecycle. + */ + @get:Rule + val activityRule = ActivityScenarioRule(CommandActivity::class.java) + /** + * Tests retrieving a command by ID. + */ @Test - fun getCommandById() { + fun getCommandById_displaysUnimplementedMessage() { + // Arrange: Input a command ID. onView(withId(R.id.command_id_edittext)).perform(replaceText("1")) + + // Act: Click the button to retrieve the command. onView(withId(R.id.get_command_button)).perform(click()) + + // Assert: Verify the result text view displays the expected "UNIMPLEMENTED" message. onView(withId(R.id.command_result_textview)) .check(ViewAssertions.matches(withSubstring("UNIMPLEMENTED"))) } @Test - fun issueCommand() { - onView(withId(R.id.clear_app_package_edittext)).perform(replaceText("com.android.settings")) + fun testClearAppDataCommand_editTextIsPresent(){ + onView(withId(R.id.clear_app_package_edittext)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + @Test + fun testClearAppDataCommand_editTextCanBeFilled(){ + onView(withId(R.id.clear_app_package_edittext)).perform(replaceText(TEST_PACKAGE_NAME)) + onView(withId(R.id.clear_app_package_edittext)) + .check(ViewAssertions.matches(ViewMatchers.withText(TEST_PACKAGE_NAME))) + } + + @Test + fun testClearAppDataCommand_buttonIsPresent(){ + onView(withId(R.id.clear_app_command_button)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + /** + * Verifies that attempting to clear an app's data via the UI results in the correct "UNIMPLEMENTED" + * message being displayed. This checks that the command is received, but the action is not supported yet. + */ + @Test + fun testClearAppDataCommand_displaysUnimplementedMessage() { + onView(withId(R.id.clear_app_package_edittext)).perform(replaceText(TEST_PACKAGE_NAME)) onView(withId(R.id.clear_app_command_button)).perform(click()) onView(withId(R.id.command_result_textview)) .check(ViewAssertions.matches(withSubstring("UNIMPLEMENTED"))) } -} + + companion object { + private const val TEST_PACKAGE_NAME = "com.android.settings" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/amapi/extensibility/demo/commands/CommandActivity.kt b/app/src/main/java/com/amapi/extensibility/demo/commands/CommandActivity.kt index 23ace23..c58e98b 100644 --- a/app/src/main/java/com/amapi/extensibility/demo/commands/CommandActivity.kt +++ b/app/src/main/java/com/amapi/extensibility/demo/commands/CommandActivity.kt @@ -16,36 +16,37 @@ package com.amapi.extensibility.demo.commands import android.content.Intent import android.os.Bundle -import android.widget.Button -import android.widget.EditText -import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider -import com.amapi.extensibility.demo.R +import com.amapi.extensibility.demo.databinding.ActivityCommandBinding import com.google.android.gms.oss.licenses.OssLicensesMenuActivity class CommandActivity : AppCompatActivity() { private lateinit var commandViewModel: CommandViewModel + private lateinit var binding: ActivityCommandBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_command) - commandViewModel = ViewModelProvider(this).get(CommandViewModel::class.java) + binding = ActivityCommandBinding.inflate(layoutInflater) + setContentView(binding.root) + + commandViewModel = ViewModelProvider(this)[CommandViewModel::class.java] commandViewModel.commandResultLiveData.observe(this) { results -> - findViewById(R.id.command_result_textview).apply { - text = results - } - } - findViewById