Skip to content

Commit d269fc8

Browse files
committed
feat: Implement database backup (import/export) and refactor module structure
This commit introduces a new backup feature for database import and export across all supported platforms, reorganizes core modules into feature-based structures, and updates dependencies to use official KMP artifacts. - **New Feature: Database Backup**: - Created `feature:backup:domain` and `feature:backup:ui` modules to handle database import/export logic and UI. - Implemented platform-specific `DatabaseFilePicker` and `DatabaseFileTransfer` using Okio for file operations (WASM excluded). - Added `ExportDatabaseUseCase` and `ImportDatabaseUseCase` to manage database states and file copying. - Added new settings category for "Backup" with export/import actions in `SettingsDetailScreen`. - Integrated backup functionality into `SettingsViewModel` and added relevant localized strings. - **Refactor & Module Reorganization**: - Renamed and moved `core:data:file-explorer` to `feature:file-explorer:data`. - Removed vendored `thirdparty:androidx:paging:compose` in favor of the official `androidx.paging:paging-compose` (version 3.4.0) now supporting KMP. - Reorganized `sharedModules.kt` and `uiTestModules.kt` to include new backup use cases and test mocks. - **Test Infrastructure**: - Added `BackupFeatureTestCase` for integration testing of the import/export flow. - Implemented `createTempBackupPath` expect/actual utility for cross-platform test file management. - Updated `AndroidUiTests` and `DesktopUiTests` to include the new backup feature test. - Added `TestDatabaseFilePicker` for headless UI testing of file selection. - **Build & Dependency Updates**: - Updated various dependencies: `androidSqlCipher` (4.13.0), `kotlinx-serialization` (1.10.0), and `androidx-paging` (3.4.0). - Switched internal library references from direct `compose` properties to `libs.compose` version catalog entries for better consistency. - Added `disableIosReleaseTasks` utility to convention plugins to optimize CI test builds. - **Bug Fixes**: - Updated `OffsetQueryPagingSource` in SQLDelight paging implementation to fix `getRefreshKey` calculation. - Fixed `ChangePasswordUseCase` logic to handle null/empty password scenarios correctly.
1 parent 7172961 commit d269fc8

File tree

70 files changed

+1083
-141
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1083
-141
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Supported platforms:
4040
|:------------------:|:-------:|:---:|:------------:|:---:|
4141
| database |||||
4242
| encryption |||| |
43-
| ui |||| |
43+
| import/export |||| |
4444

4545
Check out [CONTRIBUTING.md](/CONTRIBUTING.md) if you want to develop missing features.
4646

app/android/build.gradle.kts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,16 @@ dependencies {
7272
implementation(project(project.property("CORE_DATA_DB_MODULE").toString()))
7373
implementation(projects.core.presentation)
7474
implementation(projects.ui.shared)
75+
implementation(projects.feature.backup.domain)
76+
implementation(projects.feature.backup.ui)
7577
implementation(kotlin("reflect", libs.versions.kotlin.get()))
7678
implementation(libs.androidx.core.splashscreen)
7779
implementation(libs.androidx.appcompat)
7880
implementation(libs.androidx.activity.compose)
79-
implementation(compose.ui)
80-
implementation(compose.material3)
81-
implementation(compose.preview)
82-
debugImplementation(compose.uiTooling)
81+
implementation(libs.compose.ui)
82+
implementation(libs.compose.material3)
83+
implementation(libs.compose.ui.tooling.preview)
84+
debugImplementation(libs.compose.ui.tooling)
8385
debugImplementation(libs.androidx.compose.test.manifest)
8486
implementation(libs.androidx.navigation.compose)
8587
implementation(libs.material.theme.prefs)
@@ -108,7 +110,7 @@ dependencies {
108110
androidTestUtil(libs.androidx.test.orchestrator)
109111
androidTestImplementation(libs.espresso.core)
110112
androidTestImplementation(libs.espresso.device)
111-
androidTestImplementation(compose.desktop.uiTestJUnit4)
113+
androidTestImplementation(libs.compose.ui.test.junit4)
112114
androidTestImplementation(libs.turbine)
113115
androidTestImplementation(libs.leakCanary.android.instrumentation)
114116
lintChecks(libs.android.security.lint)

app/android/src/androidTest/java/com/softartdev/notedelight/ui/AndroidUiTests.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
66
import androidx.test.filters.FlakyTest
77
import androidx.test.filters.LargeTest
88
import com.softartdev.notedelight.MainActivity
9+
import com.softartdev.notedelight.di.backupTestModule
910
import leakcanary.DetectLeaksAfterTestSuccess
1011
import leakcanary.TestDescriptionHolder
1112
import org.junit.After
@@ -14,6 +15,8 @@ import org.junit.Rule
1415
import org.junit.Test
1516
import org.junit.rules.RuleChain
1617
import org.junit.runner.RunWith
18+
import org.koin.core.context.loadKoinModules
19+
import org.koin.core.context.unloadKoinModules
1720

1821
@LargeTest
1922
@FlakyTest
@@ -57,6 +60,13 @@ class AndroidUiTests : AbstractJvmUiTests() {
5760
@Test
5861
override fun localeTest() = super.localeTest()
5962

63+
@Test
64+
override fun backupFeatureTest() {
65+
loadKoinModules(backupTestModule)
66+
super.backupFeatureTest()
67+
unloadKoinModules(backupTestModule)
68+
}
69+
6070
override fun pressBack() = Espresso.pressBack()
6171

6272
override fun closeSoftKeyboard() = Espresso.closeSoftKeyboard()

app/android/src/androidTest/java/com/softartdev/notedelight/ui/RotationTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ class RotationTest {
4949

5050
onDevice().setScreenOrientation(ScreenOrientation.PORTRAIT)
5151
}
52-
}
52+
}

app/android/src/androidTest/java/com/softartdev/notedelight/ui/SignInTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ class SignInTest {
3535

3636
@Test
3737
fun signInTest() = SignInTestCase(composeUiTest, Espresso::closeSoftKeyboard).invoke()
38-
}
38+
}

app/android/src/androidTest/java/com/softartdev/notedelight/ui/SignOutTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ class SignOutTest {
3939

4040
assertTrue(composeTestRule.activityRule.scenario.state.isAtLeast(DESTROYED))
4141
}
42-
}
42+
}

app/desktop/build.gradle.kts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
33

44
plugins {
55
alias(libs.plugins.kotlin.multiplatform)
6+
alias(libs.plugins.gradle.convention)
67
alias(libs.plugins.compose)
78
alias(libs.plugins.compose.compiler)
89
}
@@ -24,18 +25,19 @@ kotlin {
2425
implementation(project.dependencies.platform(libs.coroutines.bom))
2526
implementation(libs.coroutines.swing)
2627
implementation(libs.androidx.lifecycle.runtime.compose)
27-
implementation(compose.materialIconsExtended)
28+
implementation(libs.compose.material.icons.extended)
2829
implementation(compose.desktop.currentOs)
29-
implementation(compose.components.resources)
30+
implementation(libs.compose.components.resources)
3031
implementation(project.dependencies.platform(libs.koin.bom))
3132
implementation(libs.koin.core)
3233
implementation(libs.kermit)
3334
}
3435
jvmTest.dependencies {
3536
implementation(projects.ui.test)
3637
implementation(projects.ui.testJvm)
38+
implementation(projects.feature.backup.ui)
3739
implementation(kotlin("test"))
38-
implementation(compose.desktop.uiTestJUnit4)
40+
implementation(libs.compose.ui.test.junit4)
3941
implementation(compose.desktop.currentOs)
4042
implementation(libs.koin.compose)
4143
implementation(libs.kotlinx.datetime)

app/desktop/src/jvmTest/kotlin/com/softartdev/notedelight/ui/DesktopUiTests.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ class DesktopUiTests : AbstractJvmUiTests() {
103103
@Test
104104
override fun localeTest() = super.localeTest()
105105

106+
@Test
107+
override fun backupFeatureTest() = super.backupFeatureTest()
108+
106109
override fun pressBack() {
107110
val backButtons = composeTestRule.onAllNodesWithContentDescription(
108111
label = Icons.AutoMirrored.Filled.ArrowBack.name

app/ios-kit/build.gradle.kts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
@file:OptIn(ExperimentalComposeLibrary::class)
2-
31
import org.gradle.internal.os.OperatingSystem
4-
import org.jetbrains.compose.ExperimentalComposeLibrary
52

63
plugins {
74
alias(libs.plugins.kotlin.multiplatform)
@@ -35,18 +32,19 @@ kotlin {
3532
commonMain.dependencies {
3633
api(projects.core.domain)
3734
api(projects.ui.shared)
38-
implementation(compose.ui)
39-
implementation(compose.foundation)
40-
implementation(compose.material3)
41-
implementation(compose.runtime)
35+
implementation(libs.compose.ui)
36+
implementation(libs.compose.foundation)
37+
implementation(libs.compose.material3)
38+
implementation(libs.compose.runtime)
4239
implementation(project.dependencies.platform(libs.koin.bom))
4340
api(libs.koin.core)
41+
implementation(libs.kermit)
4442
}
4543
commonTest.dependencies {
4644
implementation(kotlin("test"))
4745
implementation(projects.ui.test)
48-
implementation(compose.uiTest)
49-
implementation(compose.materialIconsExtended)
46+
implementation(libs.compose.ui.test)
47+
implementation(libs.compose.material.icons.extended)
5048
implementation(libs.androidx.lifecycle.runtime.compose)
5149
implementation(libs.androidx.lifecycle.runtime.testing)
5250
}
Binary file not shown.

0 commit comments

Comments
 (0)