Skip to content

Commit 9260fe4

Browse files
authored
framework-instrumentation-tests (#297)
* Fix: Use bitmap icon for shortcut Use `BitmapFactory.decodeByteArray` to decode the byte array into a bitmap before creating the icon for the shortcut. This ensures that the icon is displayed correctly. * Add tests for AssetManager, ClipboardManager, and PackageManager wrappers * Added tests for `AndroidAssetManagerWrapper` to verify the parsing of app settings templates from a JSON file. * Added tests for `AndroidClipboardManagerWrapper` to verify the behavior of `setPrimaryClip` on different API levels. * Added tests for `AndroidPackageManagerWrapper` to verify the filtering of installed applications and retrieval of app icons. * Added necessary dependencies for testing, including Robolectric and Kotlin test libraries. * Updated build configurations to enable testing and code coverage reporting. * Fix: Handle JsonSyntaxException when parsing app settings Handle JsonSyntaxException when parsing app settings from assets by returning an empty list instead of throwing an exception. This ensures the app doesn't crash if the JSON is invalid and provides a fallback behavior.
1 parent db81dfb commit 9260fe4

File tree

13 files changed

+307
-13
lines changed

13 files changed

+307
-13
lines changed

.idea/androidTestResultsUserPreferences.xml

Lines changed: 78 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/deploymentTargetSelector.xml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

data/room/build.gradle.kts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ plugins {
2424
}
2525

2626
android {
27-
defaultConfig {
28-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
29-
}
30-
3127
namespace = "com.android.geto.data.room"
3228

3329
sourceSets {

design-system/build.gradle.kts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ plugins {
2424
}
2525

2626
android {
27-
defaultConfig {
28-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
29-
}
30-
3127
namespace = "com.android.geto.designsystem"
3228
}
3329

framework/asset-manager/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
plugins {
2020
alias(libs.plugins.com.android.geto.library)
21+
alias(libs.plugins.com.android.geto.libraryJacoco)
2122
alias(libs.plugins.com.android.geto.hilt)
2223
}
2324

@@ -30,4 +31,9 @@ dependencies {
3031

3132
implementation(projects.domain.common)
3233
implementation(projects.domain.framework)
34+
35+
androidTestImplementation(kotlin("test"))
36+
androidTestImplementation(libs.androidx.test.core)
37+
androidTestImplementation(libs.androidx.test.runner)
38+
androidTestImplementation(libs.kotlinx.coroutines.test)
3339
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"Trigger JsonSyntaxException in tests"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
*
3+
* Copyright 2023 Einstein Blanco
4+
*
5+
* Licensed under the GNU General Public License v3.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.gnu.org/licenses/gpl-3.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
package com.android.geto.framework.assetmanager
19+
20+
import android.content.Context
21+
import androidx.test.core.app.ApplicationProvider
22+
import kotlinx.coroutines.test.UnconfinedTestDispatcher
23+
import kotlinx.coroutines.test.runTest
24+
import kotlin.test.BeforeTest
25+
import kotlin.test.Test
26+
import kotlin.test.assertTrue
27+
28+
class AssetManagerWrapperTest {
29+
private val context = ApplicationProvider.getApplicationContext<Context>()
30+
31+
private val testDispatcher = UnconfinedTestDispatcher()
32+
33+
private lateinit var assetManagerWrapper: AndroidAssetManagerWrapper
34+
35+
@BeforeTest
36+
fun setUp() {
37+
assetManagerWrapper = AndroidAssetManagerWrapper(
38+
ioDispatcher = testDispatcher,
39+
context = context,
40+
)
41+
}
42+
43+
@Test
44+
fun getAppSettingTemplates_shouldReturnParsedList_whenJsonIsReadSuccessfully() = runTest {
45+
assertTrue(assetManagerWrapper.getAppSettingTemplates().isNotEmpty())
46+
}
47+
48+
@Test
49+
fun getAppSettingTemplates_shouldReturnEmpty_whenIOExceptionOccurs() = runTest {
50+
assetManagerWrapper.appSettingTemplatesJson = ""
51+
52+
assertTrue(assetManagerWrapper.getAppSettingTemplates().isEmpty())
53+
}
54+
55+
@Test
56+
fun getAppSettingTemplates_shouldReturnEmpty_whenJsonSyntaxExceptionOccurs() = runTest {
57+
assetManagerWrapper.appSettingTemplatesJson = "FakeAppSettingTemplates.json"
58+
59+
assertTrue(assetManagerWrapper.getAppSettingTemplates().isEmpty())
60+
}
61+
}

framework/asset-manager/src/main/kotlin/com/android/geto/framework/assetmanager/AndroidAssetManagerWrapper.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
package com.android.geto.framework.assetmanager
1919

2020
import android.content.Context
21+
import androidx.annotation.VisibleForTesting
2122
import com.android.geto.domain.common.dispatcher.Dispatcher
2223
import com.android.geto.domain.common.dispatcher.GetoDispatchers.IO
2324
import com.android.geto.domain.framework.AssetManagerWrapper
2425
import com.android.geto.domain.model.AppSettingTemplate
2526
import com.google.gson.Gson
27+
import com.google.gson.JsonSyntaxException
2628
import com.google.gson.reflect.TypeToken
2729
import dagger.hilt.android.qualifiers.ApplicationContext
2830
import kotlinx.coroutines.CoroutineDispatcher
@@ -36,7 +38,8 @@ internal class AndroidAssetManagerWrapper @Inject constructor(
3638
) : AssetManagerWrapper {
3739
private val appSettingsType = object : TypeToken<List<AppSettingTemplate>>() {}.type
3840

39-
private val appSettingTemplatesJson = "AppSettingTemplates.json"
41+
@VisibleForTesting
42+
var appSettingTemplatesJson = "AppSettingTemplates.json"
4043

4144
override suspend fun getAppSettingTemplates(): List<AppSettingTemplate> {
4245
val jsonString = withContext(ioDispatcher) {
@@ -47,6 +50,10 @@ internal class AndroidAssetManagerWrapper @Inject constructor(
4750
}
4851
}
4952

50-
return Gson().fromJson(jsonString, appSettingsType)
53+
return try {
54+
Gson().fromJson(jsonString, appSettingsType) ?: emptyList()
55+
} catch (e: JsonSyntaxException) {
56+
emptyList()
57+
}
5158
}
5259
}

framework/clipboard-manager/build.gradle.kts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,26 @@
1818

1919
plugins {
2020
alias(libs.plugins.com.android.geto.library)
21+
alias(libs.plugins.com.android.geto.libraryJacoco)
2122
alias(libs.plugins.com.android.geto.hilt)
2223
}
2324

2425
android {
2526
namespace = "com.android.geto.framework.clipboardmanager"
27+
28+
testOptions {
29+
unitTests {
30+
isIncludeAndroidResources = true
31+
}
32+
}
2633
}
2734

2835
dependencies {
2936
implementation(projects.domain.framework)
37+
38+
testImplementation(kotlin("test"))
39+
testImplementation(libs.androidx.test.core)
40+
testImplementation(libs.androidx.test.runner)
41+
testImplementation(libs.kotlinx.coroutines.test)
42+
testImplementation(libs.robolectric)
3043
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
*
3+
* Copyright 2023 Einstein Blanco
4+
*
5+
* Licensed under the GNU General Public License v3.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.gnu.org/licenses/gpl-3.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
package com.android.geto.framework.clipboardmanager
19+
20+
import android.content.Context
21+
import android.os.Build
22+
import androidx.test.core.app.ApplicationProvider
23+
import kotlinx.coroutines.test.runTest
24+
import org.junit.runner.RunWith
25+
import org.robolectric.RobolectricTestRunner
26+
import org.robolectric.annotation.Config
27+
import kotlin.test.BeforeTest
28+
import kotlin.test.Test
29+
import kotlin.test.assertFalse
30+
import kotlin.test.assertTrue
31+
32+
@RunWith(RobolectricTestRunner::class)
33+
class ClipboardManagerWrapperTest {
34+
private val context = ApplicationProvider.getApplicationContext<Context>()
35+
36+
private lateinit var clipboardManagerWrapper: AndroidClipboardManagerWrapper
37+
38+
@BeforeTest
39+
fun setUp() {
40+
clipboardManagerWrapper = AndroidClipboardManagerWrapper(context = context)
41+
}
42+
43+
@Test
44+
@Config(sdk = [Build.VERSION_CODES.S])
45+
fun setPrimaryClip_onApi32() = runTest {
46+
assertTrue(clipboardManagerWrapper.setPrimaryClip(label = "label", text = "text"))
47+
}
48+
49+
@Test
50+
@Config(sdk = [Build.VERSION_CODES.TIRAMISU])
51+
fun setPrimaryClip_onApi33() = runTest {
52+
assertFalse(clipboardManagerWrapper.setPrimaryClip(label = "label", text = "text"))
53+
}
54+
}

0 commit comments

Comments
 (0)