Skip to content

Commit 984d7ed

Browse files
TimoPtrjpelgrom
andauthored
Cleanup and add test for the database (#6232)
--------- Co-authored-by: Joris Pelgröm <jpelgrom@users.noreply.github.com>
1 parent ca96089 commit 984d7ed

File tree

8 files changed

+1043
-921
lines changed

8 files changed

+1043
-921
lines changed

common/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ android {
1919
buildConfigField("String", "RATE_LIMIT_URL", "\"$homeAssistantAndroidRateLimitUrl\"")
2020
buildConfigField("String", "VERSION_NAME", "\"$versionName-$versionCode\"")
2121
}
22+
23+
sourceSets {
24+
// Adds exported schema location as test app assets.
25+
getByName("androidTest").assets.srcDirs("$projectDir/schemas")
26+
}
2227
}
2328

2429
ksp {
@@ -59,6 +64,7 @@ dependencies {
5964
}
6065

6166
androidTestImplementation(libs.bundles.androidx.test)
67+
androidTestImplementation(libs.androidx.room.testing)
6268

6369
// This fix an issue: provided Metadata instance has version 2.1.0, while maximum supported version is 2.0.0. To support newer versions, update the kotlinx-metadata-jvm library
6470
lintChecks(libs.androidx.runtime.lint)

common/gradle.lockfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,14 @@ androidx.room:room-compiler-processing:2.8.4=_agp_internal_javaPreCompileDebug_k
134134
androidx.room:room-compiler:2.8.4=_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorReleaseUnitTest,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath
135135
androidx.room:room-external-antlr:2.8.4=_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorReleaseUnitTest,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath
136136
androidx.room:room-ktx:2.8.4=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
137-
androidx.room:room-migration-jvm:2.8.4=_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorReleaseUnitTest,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath
138-
androidx.room:room-migration:2.8.4=_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorReleaseUnitTest,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath
137+
androidx.room:room-migration-jvm:2.8.4=_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,debugAndroidTestRuntimeClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorReleaseUnitTest,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath
138+
androidx.room:room-migration:2.8.4=_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,debugAndroidTestRuntimeClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorReleaseUnitTest,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath
139139
androidx.room:room-paging-android:2.8.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
140140
androidx.room:room-paging:2.8.4=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
141141
androidx.room:room-runtime-android:2.8.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
142142
androidx.room:room-runtime:2.8.4=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
143+
androidx.room:room-testing-android:2.8.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
144+
androidx.room:room-testing:2.8.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath
143145
androidx.savedstate:savedstate-android:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
144146
androidx.savedstate:savedstate-compose-android:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
145147
androidx.savedstate:savedstate-compose:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath

common/lint-baseline.xml

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<issues format="6" by="lint 8.13.2" type="baseline" client="gradle" dependencies="false" name="AGP (8.13.2)" variant="all" version="8.13.2">
33

4-
<issue
5-
id="MissingPermission"
6-
message="Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with `checkPermission`) or explicitly handle a potential `SecurityException`"
7-
errorLine1=" notify(NOTIFICATION_ID, notification)"
8-
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
9-
<location
10-
file="src/main/kotlin/io/homeassistant/companion/android/database/AppDatabase.kt"
11-
line="1035"
12-
column="17"/>
13-
</issue>
14-
15-
<issue
16-
id="MissingPermission"
17-
message="Missing permissions required by NotificationManagerCompat.notify: android.permission.POST_NOTIFICATIONS"
18-
errorLine1=" notify(NOTIFICATION_ID, notification)"
19-
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
20-
<location
21-
file="src/main/kotlin/io/homeassistant/companion/android/database/AppDatabase.kt"
22-
line="1035"
23-
column="17"/>
24-
</issue>
25-
264
<issue
275
id="MissingPermission"
286
message="Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with `checkPermission`) or explicitly handle a potential `SecurityException`"
@@ -100,6 +78,28 @@
10078
column="46"/>
10179
</issue>
10280

81+
<issue
82+
id="MissingPermission"
83+
message="Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with `checkPermission`) or explicitly handle a potential `SecurityException`"
84+
errorLine1=" notify(NOTIFICATION_ID, notification)"
85+
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
86+
<location
87+
file="src/main/kotlin/io/homeassistant/companion/android/database/migration/Utils.kt"
88+
line="59"
89+
column="9"/>
90+
</issue>
91+
92+
<issue
93+
id="MissingPermission"
94+
message="Missing permissions required by NotificationManagerCompat.notify: android.permission.POST_NOTIFICATIONS"
95+
errorLine1=" notify(NOTIFICATION_ID, notification)"
96+
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
97+
<location
98+
file="src/main/kotlin/io/homeassistant/companion/android/database/migration/Utils.kt"
99+
line="59"
100+
column="9"/>
101+
</issue>
102+
103103
<issue
104104
id="DefaultLocale"
105105
message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.homeassistant.companion.android.database.migration
2+
3+
import android.content.Context
4+
import androidx.room.Room
5+
import androidx.room.testing.MigrationTestHelper
6+
import androidx.test.core.app.ApplicationProvider
7+
import androidx.test.ext.junit.runners.AndroidJUnit4
8+
import androidx.test.platform.app.InstrumentationRegistry
9+
import io.homeassistant.companion.android.database.AppDatabase
10+
import org.junit.Rule
11+
import org.junit.Test
12+
import org.junit.runner.RunWith
13+
14+
/**
15+
* Migration tests for AppDatabase.
16+
*
17+
* These tests verify that database migrations correctly transform the schema
18+
* and preserve existing data.
19+
*
20+
* @see <a href="https://developer.android.com/training/data-storage/room/migrating-db-versions">Room Migration Testing</a>
21+
*/
22+
@RunWith(AndroidJUnit4::class)
23+
class AppDatabaseMigrationTest {
24+
25+
private val testDbName = "migration-test"
26+
private val context: Context = ApplicationProvider.getApplicationContext()
27+
28+
@get:Rule
29+
val helper: MigrationTestHelper = MigrationTestHelper(
30+
InstrumentationRegistry.getInstrumentation(),
31+
AppDatabase::class.java,
32+
)
33+
34+
/**
35+
* Tests the full migration path from the earliest available schema (v24) to the latest.
36+
*
37+
* Note: Schema files for versions 1-23 were not exported when those versions were developed.
38+
* Some tables (like Authentication_List) were added as Room entities without migrations,
39+
* making it impossible to reconstruct earlier schemas. The earliest testable version is 24.
40+
*/
41+
@Test
42+
fun migrateFromVersion24ToLatest() {
43+
// Create database at version 24 - the earliest version with an exported schema
44+
helper.createDatabase(testDbName, 24).use { db ->
45+
db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='sensors'").use { cursor ->
46+
assert(cursor.count == 1) { "sensors table should exist at version 24" }
47+
}
48+
db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='Authentication_List'").use { cursor ->
49+
assert(cursor.count == 1) { "Authentication_List table should exist at version 24" }
50+
}
51+
}
52+
53+
val database = Room.databaseBuilder(
54+
context,
55+
AppDatabase::class.java,
56+
testDbName,
57+
).addMigrations(*migrationPath(context)).build()
58+
59+
try {
60+
database.openHelper.writableDatabase
61+
// If we get here without exception, all migrations from v24 to current succeeded
62+
} finally {
63+
database.close()
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)