diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index 5a212bffb..6fbdcb3fe 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -76,7 +76,7 @@ jobs: - name: Run all local screenshot tests (Roborazzi) id: screenshotsverify continue-on-error: true - run: ./gradlew verifyRoborazziDemoDebug + run: ./gradlew verifyRoborazziDebug - name: Prevent pushing new screenshots if this is a fork id: checkfork_screenshots @@ -92,7 +92,7 @@ jobs: id: screenshotsrecord if: steps.screenshotsverify.outcome == 'failure' && github.event_name == 'pull_request' run: | - ./gradlew recordRoborazziDemoDebug + ./gradlew recordRoborazziDebug - name: Push new screenshots if available uses: stefanzweifel/git-auto-commit-action@v5 @@ -104,7 +104,7 @@ jobs: # Run local tests after screenshot tests to avoid wrong UP-TO-DATE. TODO: Ignore screenshots. - name: Run local tests - run: ./gradlew testDemoDebug :lint:test + run: ./gradlew testDebugUnitTest :lint:test - name: Build all build type and flavor permutations run: ./gradlew :app:assemble @@ -130,7 +130,7 @@ jobs: path: '**/build/outputs/roborazzi/*_compare.png' - name: Check lint - run: ./gradlew :app:lintProdRelease :app-nia-catalog:lintRelease :lint:lint + run: ./gradlew :app:lintRelease :app-nia-catalog:lintRelease :lint:lint - name: Upload lint reports (HTML) if: ${{ !cancelled() }} @@ -146,7 +146,7 @@ jobs: sarif_file: './' - name: Check badging - run: ./gradlew :app:checkProdReleaseBadging + run: ./gradlew :app:checkReleaseBadging androidTest: runs-on: ubuntu-latest @@ -199,17 +199,16 @@ jobs: disable-animations: true disk-size: 6000M heap-size: 600M - script: ./gradlew connectedDemoDebugAndroidTest --daemon + script: ./gradlew connectedDebugAndroidTest --daemon - name: Run local tests (including Roborazzi) for the combined coverage report (only API 30) if: matrix.api-level == 30 # There is no need to verify Roborazzi tests to generate coverage. - run: ./gradlew testDemoDebugUnitTest -Proborazzi.test.verify=false # Add Prod if we ever add JVM tests for prod + run: ./gradlew testDebugUnitTest -Proborazzi.test.verify=false - # Add `createProdDebugUnitTestCoverageReport` if we ever add JVM tests for prod - name: Generate coverage reports for Debug variants (only API 30) if: matrix.api-level == 30 - run: ./gradlew createDemoDebugCombinedCoverageReport + run: ./gradlew createDebugCombinedCoverageReport - name: Upload test reports if: ${{ !cancelled() }} diff --git a/AGENTS.md b/AGENTS.md index 9711ef574..84ae649c1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,21 +20,21 @@ Now in Android (KMP edition) — a Kotlin Multiplatform fork of Google's Now in # Run desktop app # Gradle run config task: desktopRun -DmainClass=MainKt --quiet -# Unit tests (only demoDebug variant has test coverage) -./gradlew testDemoDebug # all module tests -./gradlew :feature:foryou:testDemoDebug # single module test +# Unit tests +./gradlew testDebugUnitTest # all module tests +./gradlew :feature:foryou:testDebugUnitTest # single module test ./gradlew :lint:test # lint rule tests # Instrumented tests (requires a connected Android emulator) -./gradlew connectedDemoDebugAndroidTest +./gradlew connectedDebugAndroidTest # Screenshot tests (Roborazzi — CI only, do NOT run locally) # CI records/verifies screenshots and auto-commits updates via PR -# ./gradlew verifyRoborazziDemoDebug # verify against baselines (CI only) -# ./gradlew recordRoborazziDemoDebug # record new baselines (CI only) +# ./gradlew verifyRoborazziDebug # verify against baselines (CI only) +# ./gradlew recordRoborazziDebug # record new baselines (CI only) # Lint -./gradlew :app:lintProdRelease :app-nia-catalog:lintRelease :lint:lint +./gradlew :app:lintRelease :app-nia-catalog:lintRelease :lint:lint # Dependency guard ./gradlew dependencyGuard # check @@ -44,7 +44,7 @@ Now in Android (KMP edition) — a Kotlin Multiplatform fork of Google's Now in ./gradlew :build-logic:convention:check # Badging check -./gradlew :app:checkProdReleaseBadging +./gradlew :app:checkReleaseBadging ``` ## Architecture @@ -86,7 +86,7 @@ All modules use convention plugins from `build-logic/convention/` (plugin IDs pr ### Build Variants -Two flavor dimensions: `demo` (local static data) and `prod` (requires backend server, not public). Use `demoDebug` for development. +Two build types: `debug` and `release`. No flavor dimensions (demo/prod flavors were removed during KMP migration). ### KMP Source Set Layout diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index 6882d1d3b..9ca68afbb 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -2,8 +2,8 @@ androidx.activity:activity-compose:1.9.3 androidx.activity:activity-ktx:1.9.3 androidx.activity:activity:1.9.3 androidx.annotation:annotation-experimental:1.4.1 -androidx.annotation:annotation-jvm:1.9.0 -androidx.annotation:annotation:1.9.0 +androidx.annotation:annotation-jvm:1.9.1 +androidx.annotation:annotation:1.9.1 androidx.appcompat:appcompat-resources:1.7.0 androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 @@ -11,48 +11,48 @@ androidx.autofill:autofill:1.0.0 androidx.collection:collection-jvm:1.4.4 androidx.collection:collection-ktx:1.4.4 androidx.collection:collection:1.4.4 -androidx.compose.animation:animation-android:1.7.4 -androidx.compose.animation:animation-core-android:1.7.4 -androidx.compose.animation:animation-core:1.7.4 -androidx.compose.animation:animation:1.7.4 -androidx.compose.foundation:foundation-android:1.7.4 -androidx.compose.foundation:foundation-layout-android:1.7.4 -androidx.compose.foundation:foundation-layout:1.7.4 -androidx.compose.foundation:foundation:1.7.4 +androidx.compose.animation:animation-android:1.7.6 +androidx.compose.animation:animation-core-android:1.7.6 +androidx.compose.animation:animation-core:1.7.6 +androidx.compose.animation:animation:1.7.6 +androidx.compose.foundation:foundation-android:1.7.6 +androidx.compose.foundation:foundation-layout-android:1.7.6 +androidx.compose.foundation:foundation-layout:1.7.6 +androidx.compose.foundation:foundation:1.7.6 androidx.compose.material3.adaptive:adaptive-android:1.0.0 androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0 androidx.compose.material3.adaptive:adaptive-layout:1.0.0 androidx.compose.material3.adaptive:adaptive:1.0.0 -androidx.compose.material3:material3-adaptive-navigation-suite-android:1.3.0 -androidx.compose.material3:material3-adaptive-navigation-suite:1.3.0 -androidx.compose.material3:material3-android:1.3.0 -androidx.compose.material3:material3:1.3.0 -androidx.compose.material:material-android:1.7.1 -androidx.compose.material:material-icons-core-android:1.7.1 -androidx.compose.material:material-icons-core:1.7.1 -androidx.compose.material:material-icons-extended-android:1.7.1 -androidx.compose.material:material-icons-extended:1.7.1 -androidx.compose.material:material-ripple-android:1.7.1 -androidx.compose.material:material-ripple:1.7.1 -androidx.compose.material:material:1.7.1 -androidx.compose.runtime:runtime-android:1.7.4 -androidx.compose.runtime:runtime-saveable-android:1.7.4 -androidx.compose.runtime:runtime-saveable:1.7.4 -androidx.compose.runtime:runtime:1.7.4 -androidx.compose.ui:ui-android:1.7.4 -androidx.compose.ui:ui-geometry-android:1.7.4 -androidx.compose.ui:ui-geometry:1.7.4 -androidx.compose.ui:ui-graphics-android:1.7.4 -androidx.compose.ui:ui-graphics:1.7.4 -androidx.compose.ui:ui-text-android:1.7.4 -androidx.compose.ui:ui-text:1.7.4 -androidx.compose.ui:ui-tooling-preview-android:1.7.4 -androidx.compose.ui:ui-tooling-preview:1.7.4 -androidx.compose.ui:ui-unit-android:1.7.4 -androidx.compose.ui:ui-unit:1.7.4 -androidx.compose.ui:ui-util-android:1.7.4 -androidx.compose.ui:ui-util:1.7.4 -androidx.compose.ui:ui:1.7.4 +androidx.compose.material3:material3-adaptive-navigation-suite-android:1.3.1 +androidx.compose.material3:material3-adaptive-navigation-suite:1.3.1 +androidx.compose.material3:material3-android:1.3.1 +androidx.compose.material3:material3:1.3.1 +androidx.compose.material:material-android:1.7.6 +androidx.compose.material:material-icons-core-android:1.7.6 +androidx.compose.material:material-icons-core:1.7.6 +androidx.compose.material:material-icons-extended-android:1.7.6 +androidx.compose.material:material-icons-extended:1.7.6 +androidx.compose.material:material-ripple-android:1.7.6 +androidx.compose.material:material-ripple:1.7.6 +androidx.compose.material:material:1.7.6 +androidx.compose.runtime:runtime-android:1.7.6 +androidx.compose.runtime:runtime-saveable-android:1.7.6 +androidx.compose.runtime:runtime-saveable:1.7.6 +androidx.compose.runtime:runtime:1.7.6 +androidx.compose.ui:ui-android:1.7.6 +androidx.compose.ui:ui-geometry-android:1.7.6 +androidx.compose.ui:ui-geometry:1.7.6 +androidx.compose.ui:ui-graphics-android:1.7.6 +androidx.compose.ui:ui-graphics:1.7.6 +androidx.compose.ui:ui-text-android:1.7.6 +androidx.compose.ui:ui-text:1.7.6 +androidx.compose.ui:ui-tooling-preview-android:1.7.6 +androidx.compose.ui:ui-tooling-preview:1.7.6 +androidx.compose.ui:ui-unit-android:1.7.6 +androidx.compose.ui:ui-unit:1.7.6 +androidx.compose.ui:ui-util-android:1.7.6 +androidx.compose.ui:ui-util:1.7.6 +androidx.compose.ui:ui:1.7.6 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.13.1 androidx.core:core:1.13.1 @@ -61,21 +61,21 @@ androidx.emoji2:emoji2:1.3.0 androidx.exifinterface:exifinterface:1.3.7 androidx.graphics:graphics-path:1.0.1 androidx.interpolator:interpolator:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.8.6 -androidx.lifecycle:lifecycle-common-jvm:2.8.6 -androidx.lifecycle:lifecycle-common:2.8.6 -androidx.lifecycle:lifecycle-livedata-core:2.8.6 -androidx.lifecycle:lifecycle-process:2.8.6 -androidx.lifecycle:lifecycle-runtime-android:2.8.6 -androidx.lifecycle:lifecycle-runtime-compose-android:2.8.6 -androidx.lifecycle:lifecycle-runtime-compose:2.8.6 -androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.6 -androidx.lifecycle:lifecycle-runtime-ktx:2.8.6 -androidx.lifecycle:lifecycle-runtime:2.8.6 -androidx.lifecycle:lifecycle-viewmodel-android:2.8.6 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.6 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.6 -androidx.lifecycle:lifecycle-viewmodel:2.8.6 +androidx.lifecycle:lifecycle-common-java8:2.8.7 +androidx.lifecycle:lifecycle-common-jvm:2.8.7 +androidx.lifecycle:lifecycle-common:2.8.7 +androidx.lifecycle:lifecycle-livedata-core:2.8.7 +androidx.lifecycle:lifecycle-process:2.8.7 +androidx.lifecycle:lifecycle-runtime-android:2.8.7 +androidx.lifecycle:lifecycle-runtime-compose-android:2.8.7 +androidx.lifecycle:lifecycle-runtime-compose:2.8.7 +androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.7 +androidx.lifecycle:lifecycle-runtime-ktx:2.8.7 +androidx.lifecycle:lifecycle-runtime:2.8.7 +androidx.lifecycle:lifecycle-viewmodel-android:2.8.7 +androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.7 +androidx.lifecycle:lifecycle-viewmodel:2.8.7 androidx.profileinstaller:profileinstaller:1.4.1 androidx.savedstate:savedstate-ktx:1.2.1 androidx.savedstate:savedstate:1.2.1 @@ -92,42 +92,42 @@ com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.guava:listenablefuture:1.0 com.squareup.okio:okio-jvm:3.9.1 com.squareup.okio:okio:3.9.1 -io.coil-kt.coil3:coil-compose-core-android:3.0.0-rc02 -io.coil-kt.coil3:coil-compose-core:3.0.0-rc02 -io.coil-kt.coil3:coil-core-android:3.0.0-rc02 -io.coil-kt.coil3:coil-core:3.0.0-rc02 -org.jetbrains.androidx.lifecycle:lifecycle-common:2.8.3 -org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose:2.8.3 -org.jetbrains.androidx.lifecycle:lifecycle-runtime:2.8.3 -org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.3 -org.jetbrains.androidx.window:window-core:1.3.0 -org.jetbrains.compose.animation:animation-core:1.7.0 -org.jetbrains.compose.animation:animation:1.7.0 -org.jetbrains.compose.annotation-internal:annotation:1.7.0 -org.jetbrains.compose.collection-internal:collection:1.7.0 -org.jetbrains.compose.components:components-resources-android:1.7.0 -org.jetbrains.compose.components:components-resources:1.7.0 -org.jetbrains.compose.components:components-ui-tooling-preview-android:1.7.0 -org.jetbrains.compose.components:components-ui-tooling-preview:1.7.0 -org.jetbrains.compose.foundation:foundation-layout:1.7.0 -org.jetbrains.compose.foundation:foundation:1.7.0 -org.jetbrains.compose.material3.adaptive:adaptive-layout:1.0.0-alpha03 -org.jetbrains.compose.material3.adaptive:adaptive:1.0.0 -org.jetbrains.compose.material3:material3-adaptive-navigation-suite:1.7.0 -org.jetbrains.compose.material3:material3:1.7.0 -org.jetbrains.compose.material:material-icons-core:1.7.0 -org.jetbrains.compose.material:material-icons-extended:1.7.0 -org.jetbrains.compose.material:material-ripple:1.7.0 -org.jetbrains.compose.material:material:1.7.0 -org.jetbrains.compose.runtime:runtime-saveable:1.7.0 -org.jetbrains.compose.runtime:runtime:1.7.0 -org.jetbrains.compose.ui:ui-geometry:1.7.0 -org.jetbrains.compose.ui:ui-graphics:1.7.0 -org.jetbrains.compose.ui:ui-text:1.7.0 -org.jetbrains.compose.ui:ui-unit:1.7.0 -org.jetbrains.compose.ui:ui-util:1.7.0 -org.jetbrains.compose.ui:ui:1.7.0 -org.jetbrains.kotlin:kotlin-stdlib:2.0.21 +io.coil-kt.coil3:coil-compose-core-android:3.0.3 +io.coil-kt.coil3:coil-compose-core:3.0.3 +io.coil-kt.coil3:coil-core-android:3.0.3 +io.coil-kt.coil3:coil-core:3.0.3 +org.jetbrains.androidx.lifecycle:lifecycle-common:2.8.4 +org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose:2.8.4 +org.jetbrains.androidx.lifecycle:lifecycle-runtime:2.8.4 +org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.4 +org.jetbrains.androidx.window:window-core:1.3.1 +org.jetbrains.compose.animation:animation-core:1.7.3 +org.jetbrains.compose.animation:animation:1.7.3 +org.jetbrains.compose.annotation-internal:annotation:1.7.3 +org.jetbrains.compose.collection-internal:collection:1.7.3 +org.jetbrains.compose.components:components-resources-android:1.7.3 +org.jetbrains.compose.components:components-resources:1.7.3 +org.jetbrains.compose.components:components-ui-tooling-preview-android:1.7.3 +org.jetbrains.compose.components:components-ui-tooling-preview:1.7.3 +org.jetbrains.compose.foundation:foundation-layout:1.7.3 +org.jetbrains.compose.foundation:foundation:1.7.3 +org.jetbrains.compose.material3.adaptive:adaptive-layout:1.0.1 +org.jetbrains.compose.material3.adaptive:adaptive:1.0.1 +org.jetbrains.compose.material3:material3-adaptive-navigation-suite:1.7.3 +org.jetbrains.compose.material3:material3:1.7.3 +org.jetbrains.compose.material:material-icons-core:1.7.3 +org.jetbrains.compose.material:material-icons-extended:1.7.3 +org.jetbrains.compose.material:material-ripple:1.7.3 +org.jetbrains.compose.material:material:1.7.3 +org.jetbrains.compose.runtime:runtime-saveable:1.7.3 +org.jetbrains.compose.runtime:runtime:1.7.3 +org.jetbrains.compose.ui:ui-geometry:1.7.3 +org.jetbrains.compose.ui:ui-graphics:1.7.3 +org.jetbrains.compose.ui:ui-text:1.7.3 +org.jetbrains.compose.ui:ui-unit:1.7.3 +org.jetbrains.compose.ui:ui-util:1.7.3 +org.jetbrains.compose.ui:ui:1.7.3 +org.jetbrains.kotlin:kotlin-stdlib:2.1.0 org.jetbrains.kotlinx:atomicfu-jvm:0.23.2 org.jetbrains.kotlinx:atomicfu:0.23.2 org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0 diff --git a/app/prodRelease-badging.txt b/app/release-badging.txt similarity index 95% rename from app/prodRelease-badging.txt rename to app/release-badging.txt index 0d770604e..1660c766c 100644 --- a/app/prodRelease-badging.txt +++ b/app/release-badging.txt @@ -1,12 +1,10 @@ package: name='com.google.samples.apps.nowinandroid' versionCode='8' versionName='0.1.2' platformBuildVersionName='15' platformBuildVersionCode='35' compileSdkVersion='35' compileSdkVersionCodename='15' sdkVersion:'21' -targetSdkVersion:'35' +targetSdkVersion:'34' uses-permission: name='android.permission.INTERNET' uses-permission: name='android.permission.ACCESS_NETWORK_STATE' uses-permission: name='android.permission.POST_NOTIFICATIONS' uses-permission: name='android.permission.WAKE_LOCK' -uses-permission: name='com.google.android.c2dm.permission.RECEIVE' -uses-permission: name='com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE' uses-permission: name='android.permission.RECEIVE_BOOT_COMPLETED' uses-permission: name='android.permission.FOREGROUND_SERVICE' uses-permission: name='com.google.samples.apps.nowinandroid.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION' @@ -105,14 +103,12 @@ application-icon-640:'res/mipmap-anydpi-v26/ic_launcher.xml' application-icon-65534:'res/mipmap-anydpi-v26/ic_launcher.xml' application: label='Now in Android' icon='res/mipmap-anydpi-v26/ic_launcher.xml' launchable-activity: name='com.google.samples.apps.nowinandroid.MainActivity' label='' icon='' -uses-library-not-required:'android.ext.adservices' uses-library-not-required:'androidx.window.extensions' uses-library-not-required:'androidx.window.sidecar' feature-group: label='' uses-feature: name='android.hardware.faketouch' uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps' main -other-activities other-receivers other-services supports-screens: 'small' 'normal' 'large' 'xlarge' diff --git a/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt b/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt index 1a5551748..aa8a0db65 100644 --- a/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt +++ b/app/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt @@ -25,7 +25,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.util.trace import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hasRoute -import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions @@ -33,6 +32,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourc import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.navigateToBookmarks +import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouBaseRoute import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch @@ -156,7 +156,7 @@ class NiaAppState( // Pop up to the start destination of the graph to // avoid building up a large stack of destinations // on the back stack as users select items - popUpTo(navController.graph.findStartDestination().id) { + popUpTo { saveState = true } // Avoid multiple copies of the same destination when diff --git a/build-logic/convention/src/main/kotlin/CmpApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/CmpApplicationConventionPlugin.kt index 978e24ae1..47d4cd0a4 100644 --- a/build-logic/convention/src/main/kotlin/CmpApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/CmpApplicationConventionPlugin.kt @@ -118,7 +118,7 @@ private fun Project.configureComposeMultiplatformApp() { // Fixes Cannot locate tasks that match ':core:model:testClasses' as task 'testClasses' // not found in project ':core:model'. Some candidates are: 'jsTestClasses', 'jvmTestClasses'. - project.tasks.create("testClasses") { + project.tasks.register("testClasses") { dependsOn("allTests") } } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt index c23d058ff..f9b56ee7d 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt @@ -101,7 +101,7 @@ internal fun Project.configureKotlinMultiplatform() { // Fixes Cannot locate tasks that match ':core:model:testClasses' as task 'testClasses' // not found in project ':core:model'. Some candidates are: 'jsTestClasses', 'jvmTestClasses'. - project.tasks.create("testClasses") { + project.tasks.register("testClasses") { dependsOn("allTests") } } diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt index d65a19dae..50cbc69be 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt @@ -25,7 +25,6 @@ import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaGradientBackground import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -36,7 +35,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class BackgroundScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt index b4297f372..06b2c35a1 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt @@ -25,7 +25,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaButto import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOutlinedButton import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -36,7 +35,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class ButtonScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt index f1a8bc634..9e271e0a1 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt @@ -35,7 +35,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilte import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -46,7 +45,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class FilterChipScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt index 5f12e44fd..1e6155dbb 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt @@ -24,7 +24,6 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -35,7 +34,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class IconButtonScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt index efb6ca469..5698b126f 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt @@ -26,7 +26,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverl import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -37,7 +36,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class LoadingWheelScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt index 10ebd233f..6eac86b24 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt @@ -34,7 +34,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -45,7 +44,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class NavigationScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt index 259e93c72..1474468a7 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt @@ -32,7 +32,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTabRo import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -43,7 +42,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class TabsScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt index a4324cdfb..b60bf7ec8 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt @@ -29,7 +29,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopic import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -40,7 +39,7 @@ import org.robolectric.annotation.LooperMode @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class TagScreenshotTests { diff --git a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt index b318cd2f3..652010d87 100644 --- a/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt +++ b/core/designsystem/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt @@ -31,7 +31,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme -import dagger.hilt.android.testing.HiltTestApplication import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -43,7 +42,7 @@ import org.robolectric.annotation.LooperMode @OptIn(ExperimentalMaterial3Api::class) @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class, qualifiers = "480dpi") +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class TopAppBarScreenshotTests { diff --git a/core/screenshot-testing/build.gradle.kts b/core/screenshot-testing/build.gradle.kts index 4f6cdf770..6a33213cf 100644 --- a/core/screenshot-testing/build.gradle.kts +++ b/core/screenshot-testing/build.gradle.kts @@ -15,6 +15,8 @@ */ plugins { alias(libs.plugins.nowinandroid.kmp.library) + alias(libs.plugins.jetbrains.compose) + alias(libs.plugins.compose) } android { diff --git a/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt b/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt index 80f90af3f..5bf599eea 100644 --- a/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt +++ b/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt @@ -22,11 +22,15 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepo import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals @@ -50,12 +54,18 @@ class BookmarksViewModelTest { @BeforeTest fun setup() { + Dispatchers.setMain(UnconfinedTestDispatcher()) viewModel = BookmarksViewModel( userDataRepository = userDataRepository, userNewsResourceRepository = userNewsResourceRepository, ) } + @AfterTest + fun tearDown() { + Dispatchers.resetMain() + } + @Test fun stateIsInitiallyLoading() = runTest { assertEquals(Loading, viewModel.feedUiState.value) diff --git a/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt b/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt index 29fc6f536..59b544f6b 100644 --- a/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt +++ b/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt @@ -34,7 +34,6 @@ import com.google.samples.apps.nowinandroid.core.ui.UserNewsResourcePreviewParam import com.google.samples.apps.nowinandroid.feature.foryou.OnboardingUiState.Loading import com.google.samples.apps.nowinandroid.feature.foryou.OnboardingUiState.NotShown import com.google.samples.apps.nowinandroid.feature.foryou.OnboardingUiState.Shown -import dagger.hilt.android.testing.HiltTestApplication import org.hamcrest.Matchers import org.junit.Before import org.junit.Rule @@ -51,7 +50,7 @@ import java.util.TimeZone */ @RunWith(RobolectricTestRunner::class) @GraphicsMode(GraphicsMode.Mode.NATIVE) -@Config(application = HiltTestApplication::class) +@Config(qualifiers = "480dpi") @LooperMode(LooperMode.Mode.PAUSED) class ForYouScreenScreenshotTests { diff --git a/feature/interests/build.gradle.kts b/feature/interests/build.gradle.kts index 66c6e6f53..32d420a72 100644 --- a/feature/interests/build.gradle.kts +++ b/feature/interests/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { androidUnitTest.dependencies { implementation(libs.robolectric) implementation(libs.roborazzi) + implementation(libs.androidx.navigation.testing) implementation(projects.core.screenshotTesting) } androidInstrumentedTest.dependencies { diff --git a/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt b/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt index a89c8494b..83ca214bd 100644 --- a/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt +++ b/feature/settings/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt @@ -21,11 +21,15 @@ import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.ANDROID import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Loading import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Success +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals @@ -38,9 +42,15 @@ class SettingsViewModelTest { @BeforeTest fun setup() { + Dispatchers.setMain(UnconfinedTestDispatcher()) viewModel = SettingsViewModel(userDataRepository) } + @AfterTest + fun tearDown() { + Dispatchers.resetMain() + } + @Test fun stateIsInitiallyLoading() = runTest { assertEquals(Loading, viewModel.settingsUiState.value) diff --git a/feature/topic/build.gradle.kts b/feature/topic/build.gradle.kts index 28dffb475..86e596836 100644 --- a/feature/topic/build.gradle.kts +++ b/feature/topic/build.gradle.kts @@ -44,6 +44,7 @@ kotlin { androidUnitTest.dependencies { implementation(libs.robolectric) implementation(libs.roborazzi) + implementation(libs.androidx.navigation.testing) implementation(projects.core.screenshotTesting) } androidInstrumentedTest.dependencies { diff --git a/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt b/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt index d7acdfa6e..34f21a59a 100644 --- a/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt +++ b/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt @@ -26,6 +26,7 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepo import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule +import com.google.samples.apps.nowinandroid.feature.topic.navigation.TopicRoute import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.first @@ -70,7 +71,7 @@ class TopicViewModelTest { fun setup() { viewModel = TopicViewModel( savedStateHandle = SavedStateHandle( -// route = TopicRoute(id = testInputTopics[0].topic.id), + route = TopicRoute(id = testInputTopics[0].topic.id), ), userDataRepository = userDataRepository, topicsRepository = topicsRepository,