diff --git a/.editorconfig b/.editorconfig index 7be3f8784..6c8c930bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,3 +5,13 @@ ij_kotlin_allow_trailing_comma=true ij_kotlin_allow_trailing_comma_on_call_site=true ktlint_function_naming_ignore_when_annotated_with=Composable, Test +ktlint_standard_backing-property-naming = disabled +ktlint_standard_binary-expression-wrapping = disabled +ktlint_standard_chain-method-continuation = disabled +ktlint_standard_class-signature = disabled +ktlint_standard_condition-wrapping = disabled +ktlint_standard_function-expression-body = disabled +ktlint_standard_function-literal = disabled +ktlint_standard_function-type-modifier-spacing = disabled +ktlint_standard_multiline-loop = disabled +ktlint_standard_function-signature = disabled diff --git a/README.md b/README.md index 1f5270323..83bf139be 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ To run the tests execute the following gradle tasks: - `connectedDemoDebugAndroidTest` run all instrumented tests against the `demoDebug` variant. **Note:** You should not run `./gradlew test` or `./gradlew connectedAndroidTest` as this will execute -tests against _all_ build variants which is both unecessary and will result in failures as only the +tests against _all_ build variants which is both unnecessary and will result in failures as only the `demoDebug` variant is supported. No other variants have any tests (although this might change in future). ## Screenshot tests diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index 0c6d06a5c..e009e88ee 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -1,56 +1,56 @@ -androidx.activity:activity-compose:1.9.2 -androidx.activity:activity-ktx:1.9.2 -androidx.activity:activity:1.9.2 -androidx.annotation:annotation-experimental:1.4.0 -androidx.annotation:annotation-jvm:1.8.0 -androidx.annotation:annotation:1.8.0 +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.8.1 +androidx.annotation:annotation:1.8.1 androidx.appcompat:appcompat-resources:1.6.1 androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.8.0 -androidx.collection:collection-jvm:1.4.0 -androidx.collection:collection-ktx:1.4.0 -androidx.collection:collection:1.4.0 -androidx.compose.animation:animation-android:1.7.0 -androidx.compose.animation:animation-core-android:1.7.0 -androidx.compose.animation:animation-core:1.7.0 -androidx.compose.animation:animation:1.7.0 -androidx.compose.foundation:foundation-android:1.7.0 -androidx.compose.foundation:foundation-layout-android:1.7.0 -androidx.compose.foundation:foundation-layout:1.7.0 -androidx.compose.foundation:foundation:1.7.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.5 +androidx.compose.animation:animation-core-android:1.7.5 +androidx.compose.animation:animation-core:1.7.5 +androidx.compose.animation:animation:1.7.5 +androidx.compose.foundation:foundation-android:1.7.5 +androidx.compose.foundation:foundation-layout-android:1.7.5 +androidx.compose.foundation:foundation-layout:1.7.5 +androidx.compose.foundation:foundation:1.7.5 androidx.compose.material3.adaptive:adaptive-android: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-icons-core-android:1.7.0 -androidx.compose.material:material-icons-core:1.7.0 -androidx.compose.material:material-icons-extended-android:1.7.0 -androidx.compose.material:material-icons-extended:1.7.0 -androidx.compose.material:material-ripple-android:1.7.0 -androidx.compose.material:material-ripple:1.7.0 -androidx.compose.runtime:runtime-android:1.7.0 -androidx.compose.runtime:runtime-saveable-android:1.7.0 -androidx.compose.runtime:runtime-saveable:1.7.0 -androidx.compose.runtime:runtime:1.7.0 -androidx.compose.ui:ui-android:1.7.0 -androidx.compose.ui:ui-geometry-android:1.7.0 -androidx.compose.ui:ui-geometry:1.7.0 -androidx.compose.ui:ui-graphics-android:1.7.0 -androidx.compose.ui:ui-graphics:1.7.0 -androidx.compose.ui:ui-text-android:1.7.0 -androidx.compose.ui:ui-text:1.7.0 -androidx.compose.ui:ui-tooling-preview-android:1.7.0 -androidx.compose.ui:ui-tooling-preview:1.7.0 -androidx.compose.ui:ui-unit-android:1.7.0 -androidx.compose.ui:ui-unit:1.7.0 -androidx.compose.ui:ui-util-android:1.7.0 -androidx.compose.ui:ui-util:1.7.0 -androidx.compose.ui:ui:1.7.0 -androidx.compose:compose-bom:2024.09.00 +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-icons-core-android:1.7.5 +androidx.compose.material:material-icons-core:1.7.5 +androidx.compose.material:material-icons-extended-android:1.7.5 +androidx.compose.material:material-icons-extended:1.7.5 +androidx.compose.material:material-ripple-android:1.7.5 +androidx.compose.material:material-ripple:1.7.5 +androidx.compose.runtime:runtime-android:1.7.5 +androidx.compose.runtime:runtime-saveable-android:1.7.5 +androidx.compose.runtime:runtime-saveable:1.7.5 +androidx.compose.runtime:runtime:1.7.5 +androidx.compose.ui:ui-android:1.7.5 +androidx.compose.ui:ui-geometry-android:1.7.5 +androidx.compose.ui:ui-geometry:1.7.5 +androidx.compose.ui:ui-graphics-android:1.7.5 +androidx.compose.ui:ui-graphics:1.7.5 +androidx.compose.ui:ui-text-android:1.7.5 +androidx.compose.ui:ui-text:1.7.5 +androidx.compose.ui:ui-tooling-preview-android:1.7.5 +androidx.compose.ui:ui-tooling-preview:1.7.5 +androidx.compose.ui:ui-unit-android:1.7.5 +androidx.compose.ui:ui-unit:1.7.5 +androidx.compose.ui:ui-util-android:1.7.5 +androidx.compose.ui:ui-util:1.7.5 +androidx.compose.ui:ui:1.7.5 +androidx.compose:compose-bom:2024.11.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.13.1 androidx.core:core:1.13.1 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4fc2ea36c..5434df8c2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -114,6 +114,7 @@ dependencies { kspTest(libs.hilt.compiler) testImplementation(projects.core.dataTest) + testImplementation(projects.core.datastoreTest) testImplementation(libs.hilt.android.testing) testImplementation(projects.sync.syncTest) testImplementation(libs.kotlin.test) @@ -122,7 +123,6 @@ dependencies { testDemoImplementation(libs.roborazzi) testDemoImplementation(projects.core.screenshotTesting) - androidTestImplementation(kotlin("test")) androidTestImplementation(projects.core.testing) androidTestImplementation(projects.core.dataTest) androidTestImplementation(projects.core.datastoreTest) @@ -130,6 +130,7 @@ dependencies { androidTestImplementation(libs.androidx.navigation.testing) androidTestImplementation(libs.androidx.compose.ui.test) androidTestImplementation(libs.hilt.android.testing) + androidTestImplementation(libs.kotlin.test) baselineProfile(projects.benchmarks) } diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index 3001a1eff..4a3ed7de5 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -1,6 +1,6 @@ -androidx.activity:activity-compose:1.9.2 -androidx.activity:activity-ktx:1.9.2 -androidx.activity:activity:1.9.2 +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.8.1 androidx.annotation:annotation:1.8.1 @@ -10,55 +10,55 @@ androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.8.0 -androidx.collection:collection-jvm:1.4.2 -androidx.collection:collection-ktx:1.4.2 -androidx.collection:collection:1.4.2 -androidx.compose.animation:animation-android:1.7.0 -androidx.compose.animation:animation-core-android:1.7.0 -androidx.compose.animation:animation-core:1.7.0 -androidx.compose.animation:animation:1.7.0 -androidx.compose.foundation:foundation-android:1.7.0 -androidx.compose.foundation:foundation-layout-android:1.7.0 -androidx.compose.foundation:foundation-layout:1.7.0 -androidx.compose.foundation:foundation:1.7.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.5 +androidx.compose.animation:animation-core-android:1.7.5 +androidx.compose.animation:animation-core:1.7.5 +androidx.compose.animation:animation:1.7.5 +androidx.compose.foundation:foundation-android:1.7.5 +androidx.compose.foundation:foundation-layout-android:1.7.5 +androidx.compose.foundation:foundation-layout:1.7.5 +androidx.compose.foundation:foundation:1.7.5 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-navigation-android:1.0.0 androidx.compose.material3.adaptive:adaptive-navigation: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-window-size-class-android:1.3.0 -androidx.compose.material3:material3-window-size-class:1.3.0 -androidx.compose.material3:material3:1.3.0 -androidx.compose.material:material-icons-core-android:1.7.0 -androidx.compose.material:material-icons-core:1.7.0 -androidx.compose.material:material-icons-extended-android:1.7.0 -androidx.compose.material:material-icons-extended:1.7.0 -androidx.compose.material:material-ripple-android:1.7.0 -androidx.compose.material:material-ripple:1.7.0 -androidx.compose.runtime:runtime-android:1.7.1 -androidx.compose.runtime:runtime-saveable-android:1.7.1 -androidx.compose.runtime:runtime-saveable:1.7.1 -androidx.compose.runtime:runtime-tracing:1.0.0-beta01 -androidx.compose.runtime:runtime:1.7.1 -androidx.compose.ui:ui-android:1.7.0 -androidx.compose.ui:ui-geometry-android:1.7.0 -androidx.compose.ui:ui-geometry:1.7.0 -androidx.compose.ui:ui-graphics-android:1.7.0 -androidx.compose.ui:ui-graphics:1.7.0 -androidx.compose.ui:ui-text-android:1.7.0 -androidx.compose.ui:ui-text:1.7.0 -androidx.compose.ui:ui-tooling-preview-android:1.7.0 -androidx.compose.ui:ui-tooling-preview:1.7.0 -androidx.compose.ui:ui-unit-android:1.7.0 -androidx.compose.ui:ui-unit:1.7.0 -androidx.compose.ui:ui-util-android:1.7.0 -androidx.compose.ui:ui-util:1.7.0 -androidx.compose.ui:ui:1.7.0 -androidx.compose:compose-bom:2024.09.00 +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-window-size-class-android:1.3.1 +androidx.compose.material3:material3-window-size-class:1.3.1 +androidx.compose.material3:material3:1.3.1 +androidx.compose.material:material-icons-core-android:1.7.5 +androidx.compose.material:material-icons-core:1.7.5 +androidx.compose.material:material-icons-extended-android:1.7.5 +androidx.compose.material:material-icons-extended:1.7.5 +androidx.compose.material:material-ripple-android:1.7.5 +androidx.compose.material:material-ripple:1.7.5 +androidx.compose.runtime:runtime-android:1.7.5 +androidx.compose.runtime:runtime-saveable-android:1.7.5 +androidx.compose.runtime:runtime-saveable:1.7.5 +androidx.compose.runtime:runtime-tracing:1.7.5 +androidx.compose.runtime:runtime:1.7.5 +androidx.compose.ui:ui-android:1.7.5 +androidx.compose.ui:ui-geometry-android:1.7.5 +androidx.compose.ui:ui-geometry:1.7.5 +androidx.compose.ui:ui-graphics-android:1.7.5 +androidx.compose.ui:ui-graphics:1.7.5 +androidx.compose.ui:ui-text-android:1.7.5 +androidx.compose.ui:ui-text:1.7.5 +androidx.compose.ui:ui-tooling-preview-android:1.7.5 +androidx.compose.ui:ui-tooling-preview:1.7.5 +androidx.compose.ui:ui-unit-android:1.7.5 +androidx.compose.ui:ui-unit:1.7.5 +androidx.compose.ui:ui-util-android:1.7.5 +androidx.compose.ui:ui-util:1.7.5 +androidx.compose.ui:ui:1.7.5 +androidx.compose:compose-bom:2024.11.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.13.1 androidx.core:core-splashscreen:1.0.1 diff --git a/app/prodRelease-badging.txt b/app/prodRelease-badging.txt index 21b36a7fb..9908e775a 100644 --- a/app/prodRelease-badging.txt +++ b/app/prodRelease-badging.txt @@ -105,9 +105,9 @@ 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' -uses-library-not-required:'android.ext.adservices' feature-group: label='' uses-feature: name='android.hardware.faketouch' uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps' diff --git a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt index b15024cc7..54053a1bb 100644 --- a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt +++ b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt @@ -16,13 +16,16 @@ package com.google.samples.apps.nowinandroid.ui +import androidx.compose.ui.semantics.SemanticsActions.ScrollBy import androidx.compose.ui.test.assertCountEquals import androidx.compose.ui.test.assertIsOn import androidx.compose.ui.test.assertIsSelected import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onAllNodesWithTag import androidx.compose.ui.test.onAllNodesWithText +import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText @@ -32,10 +35,10 @@ import androidx.test.espresso.Espresso import androidx.test.espresso.NoActivityResumedException import com.google.samples.apps.nowinandroid.MainActivity import com.google.samples.apps.nowinandroid.R +import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPermissionRule -import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import kotlinx.coroutines.flow.first @@ -43,7 +46,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import javax.inject.Inject import com.google.samples.apps.nowinandroid.feature.bookmarks.R as BookmarksR import com.google.samples.apps.nowinandroid.feature.foryou.R as FeatureForyouR @@ -62,29 +64,24 @@ class NavigationTest { @get:Rule(order = 0) val hiltRule = HiltAndroidRule(this) - /** - * Create a temporary folder used to create a Data Store file. This guarantees that - * the file is removed in between each test, preventing a crash. - */ - @BindValue - @get:Rule(order = 1) - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - /** * Grant [android.Manifest.permission.POST_NOTIFICATIONS] permission. */ - @get:Rule(order = 2) + @get:Rule(order = 1) val postNotificationsPermission = GrantPostNotificationsPermissionRule() /** * Use the primary activity to initialize the app normally. */ - @get:Rule(order = 3) + @get:Rule(order = 2) val composeTestRule = createAndroidComposeRule() @Inject lateinit var topicsRepository: TopicsRepository + @Inject + lateinit var newsRepository: NewsRepository + // The strings used for matching in these tests private val navigateUp by composeTestRule.stringResource(FeatureForyouR.string.feature_foryou_navigate_up) private val forYou by composeTestRule.stringResource(FeatureForyouR.string.feature_foryou_title) @@ -277,4 +274,44 @@ class NavigationTest { onNodeWithTag("topic:${topic.id}").assertExists() } } + + @Test + fun navigatingToTopicFromForYou_showsTopicDetails() { + composeTestRule.apply { + // Get the first news resource + val newsResource = runBlocking { + newsRepository.getNewsResources().first().first() + } + + // Get its first topic and follow it + val topic = newsResource.topics.first() + onNodeWithText(topic.name).performClick() + + // Get the news feed and scroll to the news resource + // Note: Possible flakiness. If the content of the news resource is long then the topic + // tag might not be visible meaning it cannot be clicked + onNodeWithTag("forYou:feed") + .performScrollToNode(hasTestTag("newsResourceCard:${newsResource.id}")) + .fetchSemanticsNode() + .apply { + val newsResourceCardNode = onNodeWithTag("newsResourceCard:${newsResource.id}") + .fetchSemanticsNode() + config[ScrollBy].action?.invoke( + 0f, + // to ensure the bottom of the card is visible, + // manually scroll the difference between the height of + // the scrolling node and the height of the card + (newsResourceCardNode.size.height - size.height).coerceAtLeast(0).toFloat(), + ) + } + + // Click the first topic tag + onAllNodesWithTag("topicTag:${topic.id}", useUnmergedTree = true) + .onFirst() + .performClick() + + // Verify that we're on the correct topic details screen + onNodeWithTag("topic:${topic.id}").assertExists() + } + } } diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt index f878c003b..e079c98f4 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt @@ -20,10 +20,12 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.bookmarksScreen -import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouRoute -import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouScreen +import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouBaseRoute +import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouSection import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterests import com.google.samples.apps.nowinandroid.feature.search.navigation.searchScreen +import com.google.samples.apps.nowinandroid.feature.topic.navigation.navigateToTopic +import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicScreen import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination.INTERESTS import com.google.samples.apps.nowinandroid.ui.NiaAppState import com.google.samples.apps.nowinandroid.ui.interests2pane.interestsListDetailScreen @@ -44,10 +46,18 @@ fun NiaNavHost( val navController = appState.navController NavHost( navController = navController, - startDestination = ForYouRoute, + startDestination = ForYouBaseRoute, modifier = modifier, ) { - forYouScreen(onTopicClick = navController::navigateToInterests) + forYouSection( + onTopicClick = navController::navigateToTopic, + ) { + topicScreen( + showBackButton = true, + onBackClick = navController::popBackStack, + onTopicClick = navController::navigateToTopic, + ) + } bookmarksScreen( onTopicClick = navController::navigateToInterests, onShowSnackbar = onShowSnackbar, diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt index 815061273..429e626ff 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import com.google.samples.apps.nowinandroid.R import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.BookmarksRoute +import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouBaseRoute import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouRoute import com.google.samples.apps.nowinandroid.feature.interests.navigation.InterestsRoute import kotlin.reflect.KClass @@ -29,9 +30,18 @@ import com.google.samples.apps.nowinandroid.feature.foryou.R as forYouR import com.google.samples.apps.nowinandroid.feature.search.R as searchR /** - * Type for the top level destinations in the application. Each of these destinations - * can contain one or more screens (based on the window size). Navigation from one screen to the - * next within a single destination will be handled directly in composables. + * Type for the top level destinations in the application. Contains metadata about the destination + * that is used in the top app bar and common navigation UI. + * + * @param selectedIcon The icon to be displayed in the navigation UI when this destination is + * selected. + * @param unselectedIcon The icon to be displayed in the navigation UI when this destination is + * not selected. + * @param iconTextId Text that to be displayed in the navigation UI. + * @param titleTextId Text that is displayed on the top app bar. + * @param route The route to use when navigating to this destination. + * @param baseRoute The highest ancestor of this destination. Defaults to [route], meaning that + * there is a single destination in that section of the app (no nested destinations). */ enum class TopLevelDestination( val selectedIcon: ImageVector, @@ -39,6 +49,7 @@ enum class TopLevelDestination( @StringRes val iconTextId: Int, @StringRes val titleTextId: Int, val route: KClass<*>, + val baseRoute: KClass<*> = route, ) { FOR_YOU( selectedIcon = NiaIcons.Upcoming, @@ -46,6 +57,7 @@ enum class TopLevelDestination( iconTextId = forYouR.string.feature_foryou_title, titleTextId = R.string.app_name, route = ForYouRoute::class, + baseRoute = ForYouBaseRoute::class, ), BOOKMARKS( selectedIcon = NiaIcons.Bookmarks, diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt index 6cdc32bb0..640b22e83 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt @@ -152,7 +152,7 @@ internal fun NiaApp( appState.topLevelDestinations.forEach { destination -> val hasUnread = unreadDestinations.contains(destination) val selected = currentDestination - .isRouteInHierarchy(destination.route) + .isRouteInHierarchy(destination.baseRoute) item( selected = selected, onClick = { appState.navigateToTopLevelDestination(destination) }, diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt index 75a294c01..249f07590 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt @@ -90,7 +90,7 @@ class NiaAppState( val currentTopLevelDestination: TopLevelDestination? @Composable get() { return TopLevelDestination.entries.firstOrNull { topLevelDestination -> - currentDestination?.hasRoute(route = topLevelDestination.route) ?: false + currentDestination?.hasRoute(route = topLevelDestination.route) == true } } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 5a3dc450f..2b8c739cd 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -15,9 +15,6 @@ limitations under the License. --> - - #4D000000 - #000000 #FCFCFC diff --git a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/InterestsListDetailScreenTest.kt b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/InterestsListDetailScreenTest.kt index a5b243537..1062c7e56 100644 --- a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/InterestsListDetailScreenTest.kt +++ b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/InterestsListDetailScreenTest.kt @@ -31,7 +31,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.ui.interests2pane.InterestsListDetailScreen import com.google.samples.apps.nowinandroid.uitesthiltmanifest.HiltComponentActivity -import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication @@ -40,7 +39,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @@ -60,11 +58,7 @@ class InterestsListDetailScreenTest { @get:Rule(order = 0) val hiltRule = HiltAndroidRule(this) - @BindValue @get:Rule(order = 1) - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - - @get:Rule(order = 2) val composeTestRule = createAndroidComposeRule() @Inject diff --git a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt index 1cca5a13a..e84b96b73 100644 --- a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt +++ b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt @@ -38,7 +38,6 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor 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.uitesthiltmanifest.HiltComponentActivity -import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication @@ -47,7 +46,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @@ -74,18 +72,10 @@ class NiaAppScreenSizesScreenshotTests { @get:Rule(order = 0) val hiltRule = HiltAndroidRule(this) - /** - * Create a temporary folder used to create a Data Store file. This guarantees that - * the file is removed in between each test, preventing a crash. - */ - @BindValue - @get:Rule(order = 1) - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - /** * Use a test activity to set the content on. */ - @get:Rule(order = 2) + @get:Rule(order = 1) val composeTestRule = createAndroidComposeRule() @Inject diff --git a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarInsetsScreenshotTests.kt b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarInsetsScreenshotTests.kt index b9970effd..2ef0d3e4f 100644 --- a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarInsetsScreenshotTests.kt +++ b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarInsetsScreenshotTests.kt @@ -69,7 +69,6 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor 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.uitesthiltmanifest.HiltComponentActivity -import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication @@ -80,7 +79,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @@ -107,18 +105,10 @@ class SnackbarInsetsScreenshotTests { @get:Rule(order = 0) val hiltRule = HiltAndroidRule(this) - /** - * Create a temporary folder used to create a Data Store file. This guarantees that - * the file is removed in between each test, preventing a crash. - */ - @BindValue - @get:Rule(order = 1) - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - /** * Use a test activity to set the content on. */ - @get:Rule(order = 2) + @get:Rule(order = 1) val composeTestRule = createAndroidComposeRule() @Inject diff --git a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarScreenshotTests.kt b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarScreenshotTests.kt index 6f12dd620..fe2e98452 100644 --- a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarScreenshotTests.kt +++ b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/SnackbarScreenshotTests.kt @@ -42,7 +42,6 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor 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.uitesthiltmanifest.HiltComponentActivity -import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication @@ -53,7 +52,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @@ -80,18 +78,10 @@ class SnackbarScreenshotTests { @get:Rule(order = 0) val hiltRule = HiltAndroidRule(this) - /** - * Create a temporary folder used to create a Data Store file. This guarantees that - * the file is removed in between each test, preventing a crash. - */ - @BindValue - @get:Rule(order = 1) - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - /** * Use a test activity to set the content on. */ - @get:Rule(order = 2) + @get:Rule(order = 1) val composeTestRule = createAndroidComposeRule() @Inject diff --git a/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png index 912fca4c7..2f2254310 100644 Binary files a/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png and b/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png differ diff --git a/app/src/testDemo/screenshots/compactWidth_expandedHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/compactWidth_expandedHeight_showsNavigationBar.png index e052b5920..36079dcf1 100644 Binary files a/app/src/testDemo/screenshots/compactWidth_expandedHeight_showsNavigationBar.png and b/app/src/testDemo/screenshots/compactWidth_expandedHeight_showsNavigationBar.png differ diff --git a/app/src/testDemo/screenshots/compactWidth_mediumHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/compactWidth_mediumHeight_showsNavigationBar.png index 668d69146..237d6d5b3 100644 Binary files a/app/src/testDemo/screenshots/compactWidth_mediumHeight_showsNavigationBar.png and b/app/src/testDemo/screenshots/compactWidth_mediumHeight_showsNavigationBar.png differ diff --git a/app/src/testDemo/screenshots/expandedWidth_compactHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/expandedWidth_compactHeight_showsNavigationBar.png index 1daf5ec34..24a4fe157 100644 Binary files a/app/src/testDemo/screenshots/expandedWidth_compactHeight_showsNavigationBar.png and b/app/src/testDemo/screenshots/expandedWidth_compactHeight_showsNavigationBar.png differ diff --git a/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png b/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png index 53bf6f3c5..7f983c424 100644 Binary files a/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png and b/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png differ diff --git a/app/src/testDemo/screenshots/expandedWidth_mediumHeight_showsNavigationRail.png b/app/src/testDemo/screenshots/expandedWidth_mediumHeight_showsNavigationRail.png index c5b7fe883..1f1db205c 100644 Binary files a/app/src/testDemo/screenshots/expandedWidth_mediumHeight_showsNavigationRail.png and b/app/src/testDemo/screenshots/expandedWidth_mediumHeight_showsNavigationRail.png differ diff --git a/app/src/testDemo/screenshots/insets_snackbar_compact_medium.png b/app/src/testDemo/screenshots/insets_snackbar_compact_medium.png index aae785a47..b7cee54bd 100644 Binary files a/app/src/testDemo/screenshots/insets_snackbar_compact_medium.png and b/app/src/testDemo/screenshots/insets_snackbar_compact_medium.png differ diff --git a/app/src/testDemo/screenshots/insets_snackbar_compact_medium_noSnackbar.png b/app/src/testDemo/screenshots/insets_snackbar_compact_medium_noSnackbar.png index d37f02c65..fa334578b 100644 Binary files a/app/src/testDemo/screenshots/insets_snackbar_compact_medium_noSnackbar.png and b/app/src/testDemo/screenshots/insets_snackbar_compact_medium_noSnackbar.png differ diff --git a/app/src/testDemo/screenshots/insets_snackbar_expanded_expanded.png b/app/src/testDemo/screenshots/insets_snackbar_expanded_expanded.png index 3d2c79256..3f185dd62 100644 Binary files a/app/src/testDemo/screenshots/insets_snackbar_expanded_expanded.png and b/app/src/testDemo/screenshots/insets_snackbar_expanded_expanded.png differ diff --git a/app/src/testDemo/screenshots/insets_snackbar_medium_medium.png b/app/src/testDemo/screenshots/insets_snackbar_medium_medium.png index 3e7171bf4..514f5f000 100644 Binary files a/app/src/testDemo/screenshots/insets_snackbar_medium_medium.png and b/app/src/testDemo/screenshots/insets_snackbar_medium_medium.png differ diff --git a/app/src/testDemo/screenshots/mediumWidth_compactHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/mediumWidth_compactHeight_showsNavigationBar.png index 4bc5d2b1c..624d588e8 100644 Binary files a/app/src/testDemo/screenshots/mediumWidth_compactHeight_showsNavigationBar.png and b/app/src/testDemo/screenshots/mediumWidth_compactHeight_showsNavigationBar.png differ diff --git a/app/src/testDemo/screenshots/mediumWidth_expandedHeight_showsNavigationRail.png b/app/src/testDemo/screenshots/mediumWidth_expandedHeight_showsNavigationRail.png index 3e38938d6..7d7d697e7 100644 Binary files a/app/src/testDemo/screenshots/mediumWidth_expandedHeight_showsNavigationRail.png and b/app/src/testDemo/screenshots/mediumWidth_expandedHeight_showsNavigationRail.png differ diff --git a/app/src/testDemo/screenshots/mediumWidth_mediumHeight_showsNavigationRail.png b/app/src/testDemo/screenshots/mediumWidth_mediumHeight_showsNavigationRail.png index f914a0454..887213791 100644 Binary files a/app/src/testDemo/screenshots/mediumWidth_mediumHeight_showsNavigationRail.png and b/app/src/testDemo/screenshots/mediumWidth_mediumHeight_showsNavigationRail.png differ diff --git a/app/src/testDemo/screenshots/snackbar_compact_medium.png b/app/src/testDemo/screenshots/snackbar_compact_medium.png index 7676de40a..f29835e64 100644 Binary files a/app/src/testDemo/screenshots/snackbar_compact_medium.png and b/app/src/testDemo/screenshots/snackbar_compact_medium.png differ diff --git a/app/src/testDemo/screenshots/snackbar_compact_medium_noSnackbar.png b/app/src/testDemo/screenshots/snackbar_compact_medium_noSnackbar.png index ff9ed7669..9602e2a4d 100644 Binary files a/app/src/testDemo/screenshots/snackbar_compact_medium_noSnackbar.png and b/app/src/testDemo/screenshots/snackbar_compact_medium_noSnackbar.png differ diff --git a/app/src/testDemo/screenshots/snackbar_expanded_expanded.png b/app/src/testDemo/screenshots/snackbar_expanded_expanded.png index 4997a83af..1a26bc96d 100644 Binary files a/app/src/testDemo/screenshots/snackbar_expanded_expanded.png and b/app/src/testDemo/screenshots/snackbar_expanded_expanded.png differ diff --git a/app/src/testDemo/screenshots/snackbar_medium_medium.png b/app/src/testDemo/screenshots/snackbar_medium_medium.png index 36fffa9c6..f50dfd9f2 100644 Binary files a/app/src/testDemo/screenshots/snackbar_medium_medium.png and b/app/src/testDemo/screenshots/snackbar_medium_medium.png differ diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 71d818c0c..2a10901fb 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -53,8 +53,8 @@ class AndroidLibraryConventionPlugin : Plugin { disableUnnecessaryAndroidTests(target) } dependencies { - add("androidTestImplementation", kotlin("test")) - add("testImplementation", kotlin("test")) + add("androidTestImplementation", libs.findLibrary("kotlin.test").get()) + add("testImplementation", libs.findLibrary("kotlin.test").get()) add("implementation", libs.findLibrary("androidx.tracing.ktx").get()) } diff --git a/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt index a8228e5af..f49366f75 100644 --- a/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt @@ -26,7 +26,13 @@ class HiltConventionPlugin : Plugin { pluginManager.apply("com.google.devtools.ksp") dependencies { add("ksp", libs.findLibrary("hilt.compiler").get()) - add("implementation", libs.findLibrary("hilt.core").get()) + } + + // Add support for Jvm Module, base on org.jetbrains.kotlin.jvm + pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { + dependencies { + add("implementation", libs.findLibrary("hilt.core").get()) + } } /** Add support for Android modules, based on [AndroidBasePlugin] */ diff --git a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt index 35932c835..afe47eeee 100644 --- a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt @@ -15,8 +15,11 @@ */ import com.google.samples.apps.nowinandroid.configureKotlinJvm +import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.kotlin class JvmLibraryConventionPlugin : Plugin { override fun apply(target: Project) { @@ -26,6 +29,9 @@ class JvmLibraryConventionPlugin : Plugin { apply("nowinandroid.android.lint") } configureKotlinJvm() + dependencies { + add("testImplementation", libs.findLibrary("kotlin.test").get()) + } } } } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidInstrumentedTests.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidInstrumentedTests.kt index d0c26e4e6..c51dac5c9 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidInstrumentedTests.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidInstrumentedTests.kt @@ -30,6 +30,6 @@ import org.gradle.api.Project internal fun LibraryAndroidComponentsExtension.disableUnnecessaryAndroidTests( project: Project, ) = beforeVariants { - it.enableAndroidTest = it.enableAndroidTest + it.androidTest.enable = it.androidTest.enable && project.projectDir.resolve("src/androidTest").exists() } diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts index de9224e22..b359a5207 100644 --- a/build-logic/settings.gradle.kts +++ b/build-logic/settings.gradle.kts @@ -16,7 +16,13 @@ dependencyResolutionManagement { repositories { - google() + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } mavenCentral() } versionCatalogs { diff --git a/build.gradle.kts b/build.gradle.kts index dffc0c0dd..9a8652956 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,7 +16,13 @@ buildscript { repositories { - google() + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } mavenCentral() // Android Build Server @@ -30,7 +36,13 @@ buildscript { } -// Lists all plugins used throughout the project +/* + * By listing all the plugins used throughout all subprojects in the root project build script, it + * ensures that the build script classpath remains the same for all projects. This avoids potential + * problems with mismatching versions of transitive plugin dependencies. A subproject that applies + * an unlisted plugin will have that plugin and its dependencies _appended_ to the classpath, not + * replacing pre-existing dependencies. + */ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false diff --git a/compose_compiler_config.conf b/compose_compiler_config.conf index d47946206..4337c04cb 100644 --- a/compose_compiler_config.conf +++ b/compose_compiler_config.conf @@ -1,5 +1,5 @@ // This file contains classes (with possible wildcards) that the Compose Compiler will treat as stable. -// It allows us to define classes that our not part of our codebase without wrapping them in a stable class. +// It allows us to define classes that are not part of our codebase without wrapping them in a stable class. // For more information, check https://developer.android.com/jetpack/compose/performance/stability/fix#configuration-file // We always use immutable classes for our data model, to avoid running the Compose compiler diff --git a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeNewsRepository.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeNewsRepository.kt index 0cdec6090..da90eae61 100644 --- a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeNewsRepository.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeNewsRepository.kt @@ -17,16 +17,13 @@ package com.google.samples.apps.nowinandroid.core.data.test.repository import com.google.samples.apps.nowinandroid.core.data.Synchronizer -import com.google.samples.apps.nowinandroid.core.data.model.asEntity +import com.google.samples.apps.nowinandroid.core.data.model.asExternalModel import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery -import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity -import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.demo.DemoNiaNetworkDataSource -import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow @@ -48,9 +45,11 @@ class FakeNewsRepository @Inject constructor( query: NewsResourceQuery, ): Flow> = flow { + val newsResources = datasource.getNewsResources() + val topics = datasource.getTopics() + emit( - datasource - .getNewsResources() + newsResources .filter { networkNewsResource -> // Filter out any news resources which don't match the current query. // If no query parameters (filterTopicIds or filterNewsIds) are specified @@ -64,8 +63,7 @@ class FakeNewsRepository @Inject constructor( ) .all(true::equals) } - .map(NetworkNewsResource::asEntity) - .map(NewsResourceEntity::asExternalModel), + .map { it.asExternalModel(topics) }, ) }.flowOn(ioDispatcher) diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt index c3ad91dfe..01d0905f0 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt @@ -19,8 +19,10 @@ package com.google.samples.apps.nowinandroid.core.data.model import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceTopicCrossRef import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity +import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource -import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResourceExpanded +import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic +import com.google.samples.apps.nowinandroid.core.network.model.asExternalModel fun NetworkNewsResource.asEntity() = NewsResourceEntity( id = id, @@ -32,16 +34,6 @@ fun NetworkNewsResource.asEntity() = NewsResourceEntity( type = type, ) -fun NetworkNewsResourceExpanded.asEntity() = NewsResourceEntity( - id = id, - title = title, - content = content, - url = url, - headerImageUrl = headerImageUrl, - publishDate = publishDate, - type = type, -) - /** * A shell [TopicEntity] to fulfill the foreign key constraint when inserting * a [NewsResourceEntity] into the DB @@ -65,3 +57,17 @@ fun NetworkNewsResource.topicCrossReferences(): List topicId = topicId, ) } + +fun NetworkNewsResource.asExternalModel(topics: List) = + NewsResource( + id = id, + title = title, + content = content, + url = url, + headerImageUrl = headerImageUrl, + publishDate = publishDate, + type = type, + topics = topics + .filter { networkTopic -> this.topics.contains(networkTopic.id) } + .map(NetworkTopic::asExternalModel), + ) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityKtTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityKtTest.kt deleted file mode 100644 index 7dd251a99..000000000 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityKtTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * 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. - */ - -package com.google.samples.apps.nowinandroid.core.data.model - -import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource -import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResourceExpanded -import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic -import kotlinx.datetime.Instant -import org.junit.Test -import kotlin.test.assertEquals - -class NetworkEntityKtTest { - - @Test - fun network_topic_can_be_mapped_to_topic_entity() { - val networkModel = NetworkTopic( - id = "0", - name = "Test", - shortDescription = "short description", - longDescription = "long description", - url = "URL", - imageUrl = "image URL", - ) - val entity = networkModel.asEntity() - - assertEquals("0", entity.id) - assertEquals("Test", entity.name) - assertEquals("short description", entity.shortDescription) - assertEquals("long description", entity.longDescription) - assertEquals("URL", entity.url) - assertEquals("image URL", entity.imageUrl) - } - - @Test - fun network_news_resource_can_be_mapped_to_news_resource_entity() { - val networkModel = - NetworkNewsResource( - id = "0", - title = "title", - content = "content", - url = "url", - headerImageUrl = "headerImageUrl", - publishDate = Instant.fromEpochMilliseconds(1), - type = "Article 📚", - ) - val entity = networkModel.asEntity() - - assertEquals("0", entity.id) - assertEquals("title", entity.title) - assertEquals("content", entity.content) - assertEquals("url", entity.url) - assertEquals("headerImageUrl", entity.headerImageUrl) - assertEquals(Instant.fromEpochMilliseconds(1), entity.publishDate) - assertEquals("Article 📚", entity.type) - - val expandedNetworkModel = - NetworkNewsResourceExpanded( - id = "0", - title = "title", - content = "content", - url = "url", - headerImageUrl = "headerImageUrl", - publishDate = Instant.fromEpochMilliseconds(1), - type = "Article 📚", - ) - - val entityFromExpanded = expandedNetworkModel.asEntity() - - assertEquals("0", entityFromExpanded.id) - assertEquals("title", entityFromExpanded.title) - assertEquals("content", entityFromExpanded.content) - assertEquals("url", entityFromExpanded.url) - assertEquals("headerImageUrl", entityFromExpanded.headerImageUrl) - assertEquals(Instant.fromEpochMilliseconds(1), entityFromExpanded.publishDate) - assertEquals("Article 📚", entityFromExpanded.type) - } -} diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityTest.kt new file mode 100644 index 000000000..52dbe5117 --- /dev/null +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityTest.kt @@ -0,0 +1,140 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * 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. + */ + +package com.google.samples.apps.nowinandroid.core.data.model + +import com.google.samples.apps.nowinandroid.core.model.data.NewsResource +import com.google.samples.apps.nowinandroid.core.model.data.Topic +import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource +import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic +import com.google.samples.apps.nowinandroid.core.network.model.asExternalModel +import kotlinx.datetime.Instant +import org.junit.Test +import kotlin.test.assertEquals + +class NetworkEntityTest { + + @Test + fun networkTopicMapsToDatabaseModel() { + val networkModel = NetworkTopic( + id = "0", + name = "Test", + shortDescription = "short description", + longDescription = "long description", + url = "URL", + imageUrl = "image URL", + ) + val entity = networkModel.asEntity() + + assertEquals("0", entity.id) + assertEquals("Test", entity.name) + assertEquals("short description", entity.shortDescription) + assertEquals("long description", entity.longDescription) + assertEquals("URL", entity.url) + assertEquals("image URL", entity.imageUrl) + } + + @Test + fun networkNewsResourceMapsToDatabaseModel() { + val networkModel = + NetworkNewsResource( + id = "0", + title = "title", + content = "content", + url = "url", + headerImageUrl = "headerImageUrl", + publishDate = Instant.fromEpochMilliseconds(1), + type = "Article 📚", + ) + val entity = networkModel.asEntity() + + assertEquals("0", entity.id) + assertEquals("title", entity.title) + assertEquals("content", entity.content) + assertEquals("url", entity.url) + assertEquals("headerImageUrl", entity.headerImageUrl) + assertEquals(Instant.fromEpochMilliseconds(1), entity.publishDate) + assertEquals("Article 📚", entity.type) + } + + @Test + fun networkTopicMapsToExternalModel() { + val networkTopic = NetworkTopic( + id = "0", + name = "Test", + shortDescription = "short description", + longDescription = "long description", + url = "URL", + imageUrl = "imageUrl", + ) + + val expected = Topic( + id = "0", + name = "Test", + shortDescription = "short description", + longDescription = "long description", + url = "URL", + imageUrl = "imageUrl", + ) + + assertEquals(expected, networkTopic.asExternalModel()) + } + + @Test + fun networkNewsResourceMapsToExternalModel() { + val networkNewsResource = NetworkNewsResource( + id = "0", + title = "title", + content = "content", + url = "url", + headerImageUrl = "headerImageUrl", + publishDate = Instant.fromEpochMilliseconds(1), + type = "Article 📚", + topics = listOf("1", "2"), + ) + + val networkTopics = listOf( + NetworkTopic( + id = "1", + name = "Test 1", + shortDescription = "short description 1", + longDescription = "long description 1", + url = "url 1", + imageUrl = "imageUrl 1", + ), + NetworkTopic( + id = "2", + name = "Test 2", + shortDescription = "short description 2", + longDescription = "long description 2", + url = "url 2", + imageUrl = "imageUrl 2", + ), + ) + + val expected = NewsResource( + id = "0", + title = "title", + content = "content", + url = "url", + headerImageUrl = "headerImageUrl", + publishDate = Instant.fromEpochMilliseconds(1), + type = "Article 📚", + topics = networkTopics.map(NetworkTopic::asExternalModel), + ) + assertEquals(expected, networkNewsResource.asExternalModel(networkTopics)) + } +} diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt index 47c3996c4..01111013f 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt @@ -32,7 +32,8 @@ import com.google.samples.apps.nowinandroid.core.database.model.PopulatedNewsRes import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource -import com.google.samples.apps.nowinandroid.core.datastore.test.testUserPreferencesDataStore +import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences +import com.google.samples.apps.nowinandroid.core.datastore.test.InMemoryDataStore import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.network.model.NetworkChangeList @@ -43,9 +44,7 @@ import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -67,14 +66,9 @@ class OfflineFirstNewsRepositoryTest { private lateinit var synchronizer: Synchronizer - @get:Rule - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - @Before fun setup() { - niaPreferencesDataSource = NiaPreferencesDataSource( - tmpFolder.testUserPreferencesDataStore(testScope), - ) + niaPreferencesDataSource = NiaPreferencesDataSource(InMemoryDataStore(UserPreferences.getDefaultInstance())) newsResourceDao = TestNewsResourceDao() topicDao = TestTopicDao() network = TestNiaNetworkDataSource() diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt index 3bd314eae..d32f424d8 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt @@ -25,7 +25,8 @@ import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource -import com.google.samples.apps.nowinandroid.core.datastore.test.testUserPreferencesDataStore +import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences +import com.google.samples.apps.nowinandroid.core.datastore.test.InMemoryDataStore import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic import kotlinx.coroutines.flow.first @@ -33,9 +34,7 @@ import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import kotlin.test.assertEquals class OfflineFirstTopicsRepositoryTest { @@ -52,16 +51,11 @@ class OfflineFirstTopicsRepositoryTest { private lateinit var synchronizer: Synchronizer - @get:Rule - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - @Before fun setup() { topicDao = TestTopicDao() network = TestNiaNetworkDataSource() - niaPreferences = NiaPreferencesDataSource( - tmpFolder.testUserPreferencesDataStore(testScope), - ) + niaPreferences = NiaPreferencesDataSource(InMemoryDataStore(UserPreferences.getDefaultInstance())) synchronizer = TestSynchronizer(niaPreferences) subject = OfflineFirstTopicsRepository( diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt index 422e2cfb7..8860a6b35 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt @@ -18,7 +18,8 @@ package com.google.samples.apps.nowinandroid.core.data.repository import com.google.samples.apps.nowinandroid.core.analytics.NoOpAnalyticsHelper import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource -import com.google.samples.apps.nowinandroid.core.datastore.test.testUserPreferencesDataStore +import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences +import com.google.samples.apps.nowinandroid.core.datastore.test.InMemoryDataStore import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand import com.google.samples.apps.nowinandroid.core.model.data.UserData @@ -28,9 +29,7 @@ import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -45,14 +44,9 @@ class OfflineFirstUserDataRepositoryTest { private val analyticsHelper = NoOpAnalyticsHelper() - @get:Rule - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - @Before fun setup() { - niaPreferencesDataSource = NiaPreferencesDataSource( - tmpFolder.testUserPreferencesDataStore(testScope), - ) + niaPreferencesDataSource = NiaPreferencesDataSource(InMemoryDataStore(UserPreferences.getDefaultInstance())) subject = OfflineFirstUserDataRepository( niaPreferencesDataSource = niaPreferencesDataSource, diff --git a/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/InMemoryDataStore.kt b/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/InMemoryDataStore.kt new file mode 100644 index 000000000..f1da66dd0 --- /dev/null +++ b/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/InMemoryDataStore.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * 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. + */ + +package com.google.samples.apps.nowinandroid.core.datastore.test + +import androidx.datastore.core.DataStore +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.updateAndGet + +class InMemoryDataStore(initialValue: T) : DataStore { + override val data = MutableStateFlow(initialValue) + override suspend fun updateData( + transform: suspend (it: T) -> T, + ) = data.updateAndGet { transform(it) } +} diff --git a/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt b/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt index 295b2978a..5cc48af12 100644 --- a/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt +++ b/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt @@ -17,17 +17,13 @@ package com.google.samples.apps.nowinandroid.core.datastore.test import androidx.datastore.core.DataStore -import androidx.datastore.core.DataStoreFactory import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer import com.google.samples.apps.nowinandroid.core.datastore.di.DataStoreModule -import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope import dagger.Module import dagger.Provides import dagger.hilt.components.SingletonComponent import dagger.hilt.testing.TestInstallIn -import kotlinx.coroutines.CoroutineScope -import org.junit.rules.TemporaryFolder import javax.inject.Singleton @Module @@ -36,26 +32,9 @@ import javax.inject.Singleton replaces = [DataStoreModule::class], ) internal object TestDataStoreModule { - @Provides @Singleton fun providesUserPreferencesDataStore( - @ApplicationScope scope: CoroutineScope, - userPreferencesSerializer: UserPreferencesSerializer, - tmpFolder: TemporaryFolder, - ): DataStore = - tmpFolder.testUserPreferencesDataStore( - coroutineScope = scope, - userPreferencesSerializer = userPreferencesSerializer, - ) -} - -fun TemporaryFolder.testUserPreferencesDataStore( - coroutineScope: CoroutineScope, - userPreferencesSerializer: UserPreferencesSerializer = UserPreferencesSerializer(), -) = DataStoreFactory.create( - serializer = userPreferencesSerializer, - scope = coroutineScope, -) { - newFile("user_preferences_test.pb") + serializer: UserPreferencesSerializer, + ): DataStore = InMemoryDataStore(serializer.defaultValue) } diff --git a/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt b/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt index 433812808..433bbb5ea 100644 --- a/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt +++ b/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt @@ -16,15 +16,13 @@ package com.google.samples.apps.nowinandroid.core.datastore -import com.google.samples.apps.nowinandroid.core.datastore.test.testUserPreferencesDataStore +import com.google.samples.apps.nowinandroid.core.datastore.test.InMemoryDataStore import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.rules.TemporaryFolder import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -34,14 +32,9 @@ class NiaPreferencesDataSourceTest { private lateinit var subject: NiaPreferencesDataSource - @get:Rule - val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() - @Before fun setup() { - subject = NiaPreferencesDataSource( - tmpFolder.testUserPreferencesDataStore(testScope), - ) + subject = NiaPreferencesDataSource(InMemoryDataStore(UserPreferences.getDefaultInstance())) } @Test diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png index 67cafa03d..1b8487b8b 100644 Binary files a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png index 3f187d9d2..768b278fe 100644 Binary files a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png index ebcf62c08..ea2af8163 100644 Binary files a/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png index 7f910a34b..84dcfe3e6 100644 Binary files a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png index 912480c6a..55551f5cf 100644 Binary files a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png index a9b2c8694..a346576ea 100644 Binary files a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png index f88a672c4..ff9584511 100644 Binary files a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png index ebcf62c08..ea2af8163 100644 Binary files a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png index 6fef6436a..65fab36f9 100644 Binary files a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png index e619f1332..a162fe3d0 100644 Binary files a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png index cf0656fbd..d73b2992e 100644 Binary files a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png index 9514112f1..08319f0c7 100644 Binary files a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png index 7774a18bc..ac4c4c234 100644 Binary files a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png index 8858fb493..121a71a98 100644 Binary files a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png index a5d3d4a3d..3c2da608e 100644 Binary files a/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png index 01538b44b..cc0bd5fcf 100644 Binary files a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png index cd0c07df1..84aa59b05 100644 Binary files a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png index ab113beec..2e63f3058 100644 Binary files a/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png index fdbbb820d..aa7a82e62 100644 Binary files a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png index b567adf84..3ae722ba8 100644 Binary files a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png index a9ba099c0..aeb57a8b2 100644 Binary files a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png index 6fce27976..4d2bc5e50 100644 Binary files a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png index ce30b66ba..2a455faea 100644 Binary files a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png index bb6aa592f..fef62e4d7 100644 Binary files a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png index c18a86878..d87c4c19b 100644 Binary files a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png index d2059e4d7..13792665b 100644 Binary files a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png index 5881f76b7..85a215412 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png index 4b5c91914..9381f22ab 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png index f2e863865..1873be71b 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png index 1e3b04e50..25f14ba48 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png index 865368ca1..2a60bba9b 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png index be73f060d..e1ce90025 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png index 364f59a47..7016cf9e0 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png index 8f90977fd..7d777e9c2 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png index 5303eb64e..2bda37bd0 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png index 2dc430ca8..6a2286403 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png index fadd074d8..d65be724c 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png index 2f3749cf3..0fcf31aa8 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png index 0cfaaefae..0dc1958fc 100644 Binary files a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png index a1512fa75..7bfc9db14 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png index fe4b54ae2..8be9289be 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png index f912ce3c1..cf236ccc6 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png index 339479779..c2e73ebcd 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png index 92079273a..1806016d4 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png index 24580adf2..a04a52dd4 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png index ce2cdf804..8d26654a3 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png index ce2cdf804..8d26654a3 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png index ce2cdf804..8d26654a3 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png index ce2cdf804..8d26654a3 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png index ce2cdf804..8d26654a3 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png index ce2cdf804..8d26654a3 100644 Binary files a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png index 450d55a09..3388670d1 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png index 5aa1eb89a..c1cd57e02 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png index 74309056f..5ec625a8f 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png index 03bf6709e..051715376 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png index cf35893fd..e6171872d 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png index 013aac763..55dd863dd 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png index 19265495c..3123ab438 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png index 156fc1983..f04e7cbba 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png index 36d79ab6c..0dcc25a80 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png index 89ea5e37c..79b982f4f 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png index 022ea15eb..2b4050b99 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png index 0a7be72c2..f4f478ccc 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png index ddc43ab6a..a516a5589 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png index 071ab0a04..cea88ddd4 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png index 7170dec31..2a5d017a7 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png index 6829b0f78..5b0b9a1b7 100644 Binary files a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png index b2a0fb99c..70a9cdf06 100644 Binary files a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png index 8836faebc..ca35ee3df 100644 Binary files a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png index a4abd2d5b..13f887e37 100644 Binary files a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png index 97bbb0892..469e070cb 100644 Binary files a/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png and b/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png index a526e36c7..3858cd12a 100644 Binary files a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png index 5e27d2497..4049f8c90 100644 Binary files a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png index f5671cb14..a3be52a80 100644 Binary files a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png index bdf5d18f3..ee19e0d0c 100644 Binary files a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png index 15cb061a0..1bbfd6218 100644 Binary files a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png index 074f3dc8c..8f56f13f0 100644 Binary files a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png index f62ea3ced..547788564 100644 Binary files a/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png and b/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png index 5c38870dc..dde09305e 100644 Binary files a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png index 0564b3881..9af3202ec 100644 Binary files a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png index 759641c93..2df7822b9 100644 Binary files a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png index 522dcd301..a2c979061 100644 Binary files a/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png index 13345c365..210d6c96d 100644 Binary files a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png index d6cfb48d0..55fe716df 100644 Binary files a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png b/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png index 475707556..a7c5bb8d0 100644 Binary files a/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png and b/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png index 38ebe8b42..7d93422fd 100644 Binary files a/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png index 00144ba15..b085ad53e 100644 Binary files a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png index 53b1da266..63347e1eb 100644 Binary files a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png index 753c13605..b4157fc79 100644 Binary files a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png index 1c2d9b3ec..24b53763b 100644 Binary files a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png index 1baa2362c..cea432900 100644 Binary files a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png index 234304db1..d497ed77d 100644 Binary files a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png index 7c0348b04..c998e25de 100644 Binary files a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png index fbf61adc4..f063b0cd6 100644 Binary files a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png index 078378bea..ca5c4e912 100644 Binary files a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png differ diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt index 89af19c99..7b66af796 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt @@ -34,18 +34,3 @@ data class NetworkNewsResource( val type: String, val topics: List = listOf(), ) - -/** - * Network representation of [NewsResource] when fetched from /newsresources/{id} - */ -@Serializable -data class NetworkNewsResourceExpanded( - val id: String, - val title: String, - val content: String, - val url: String, - val headerImageUrl: String, - val publishDate: Instant, - val type: String, - val topics: List = listOf(), -) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt index e1043938f..0d21c09e7 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt @@ -32,3 +32,13 @@ data class NetworkTopic( val imageUrl: String = "", val followed: Boolean = false, ) + +fun NetworkTopic.asExternalModel(): Topic = + Topic( + id = id, + name = name, + shortDescription = shortDescription, + longDescription = longDescription, + url = url, + imageUrl = imageUrl, + ) diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/InterestsItem.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/InterestsItem.kt index 28cd8d938..c74a21ed5 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/InterestsItem.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/InterestsItem.kt @@ -54,7 +54,7 @@ fun InterestsItem( ) { ListItem( leadingContent = { - InterestsIcon(topicImageUrl, iconModifier.size(64.dp)) + InterestsIcon(topicImageUrl, iconModifier.size(48.dp)) }, headlineContent = { Text(text = name) diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 7c41d74d0..2395eb156 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -56,6 +56,7 @@ import androidx.compose.ui.draganddrop.DragAndDropTransferData import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription @@ -116,9 +117,11 @@ fun NewsResourceCardExpanded( colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), // Use custom label for accessibility services to communicate button's action to user. // Pass null for action to only override the label and not the actual action. - modifier = modifier.semantics { - onClick(label = clickActionLabel, action = null) - }, + modifier = modifier + .semantics { + onClick(label = clickActionLabel, action = null) + } + .testTag("newsResourceCard:${userNewsResource.id}"), ) { Column { if (!userNewsResource.headerImageUrl.isNullOrEmpty()) { @@ -336,9 +339,11 @@ fun NewsResourceTopics( } Text( text = followableTopic.topic.name.uppercase(Locale.getDefault()), - modifier = Modifier.semantics { - this.contentDescription = contentDescription - }, + modifier = Modifier + .semantics { + this.contentDescription = contentDescription + } + .testTag("topicTag:${followableTopic.topic.id}"), ) }, ) diff --git a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 40f54e4a7..dd01b84c9 100644 --- a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -18,7 +18,6 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks import androidx.activity.ComponentActivity import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.test.assertCountEquals import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.filter @@ -33,6 +32,7 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollToNode import androidx.lifecycle.Lifecycle +import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.testing.TestLifecycleOwner import com.google.samples.apps.nowinandroid.core.testing.data.userNewsResourcesTestData import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState diff --git a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt index 9d98f1618..b77ce72a0 100644 --- a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt +++ b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt @@ -20,30 +20,46 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import androidx.navigation.compose.navigation import androidx.navigation.navDeepLink import com.google.samples.apps.nowinandroid.core.notifications.DEEP_LINK_URI_PATTERN import com.google.samples.apps.nowinandroid.feature.foryou.ForYouScreen import kotlinx.serialization.Serializable -@Serializable data object ForYouRoute +@Serializable data object ForYouRoute // route to ForYou screen + +@Serializable data object ForYouBaseRoute // route to base navigation graph fun NavController.navigateToForYou(navOptions: NavOptions) = navigate(route = ForYouRoute, navOptions) -fun NavGraphBuilder.forYouScreen(onTopicClick: (String) -> Unit) { - composable( - deepLinks = listOf( - navDeepLink { - /** - * This destination has a deep link that enables a specific news resource to be - * opened from a notification (@see SystemTrayNotifier for more). The news resource - * ID is sent in the URI rather than being modelled in the route type because it's - * transient data (stored in SavedStateHandle) that is cleared after the user has - * opened the news resource. - */ - uriPattern = DEEP_LINK_URI_PATTERN - }, - ), - ) { - ForYouScreen(onTopicClick) +/** + * The ForYou section of the app. It can also display information about topics. + * This should be supplied from a separate module. + * + * @param onTopicClick - Called when a topic is clicked, contains the ID of the topic + * @param topicDestination - Destination for topic content + */ +fun NavGraphBuilder.forYouSection( + onTopicClick: (String) -> Unit, + topicDestination: NavGraphBuilder.() -> Unit, +) { + navigation(startDestination = ForYouRoute) { + composable( + deepLinks = listOf( + navDeepLink { + /** + * This destination has a deep link that enables a specific news resource to be + * opened from a notification (@see SystemTrayNotifier for more). The news resource + * ID is sent in the URI rather than being modelled in the route type because it's + * transient data (stored in SavedStateHandle) that is cleared after the user has + * opened the news resource. + */ + uriPattern = DEEP_LINK_URI_PATTERN + }, + ), + ) { + ForYouScreen(onTopicClick) + } + topicDestination() } } diff --git a/feature/foryou/src/test/screenshots/ForYouScreenLoading_foldable.png b/feature/foryou/src/test/screenshots/ForYouScreenLoading_foldable.png index f362c445d..56b0f5a2e 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenLoading_foldable.png and b/feature/foryou/src/test/screenshots/ForYouScreenLoading_foldable.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenLoading_phone.png b/feature/foryou/src/test/screenshots/ForYouScreenLoading_phone.png index 8d02e5985..5a7abf9da 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenLoading_phone.png and b/feature/foryou/src/test/screenshots/ForYouScreenLoading_phone.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenLoading_tablet.png b/feature/foryou/src/test/screenshots/ForYouScreenLoading_tablet.png index e6f6a527a..005957228 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenLoading_tablet.png and b/feature/foryou/src/test/screenshots/ForYouScreenLoading_tablet.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png index f5ca39c3a..fd9fd6875 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png index 7a3f99d7c..96cc8ca9a 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone_dark.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone_dark.png index 3a14048b5..13233bc93 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone_dark.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone_dark.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png index 97458f73b..bf0c2b4b6 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png index 0b539aeca..67112f6d1 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_phone.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_phone.png index b19c8d708..ffb09165c 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_phone.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_phone.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_tablet.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_tablet.png index bdf44b2a3..37dbe6e92 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_tablet.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_tablet.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png index b095c1a7a..9c8263d08 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png index 140fa8d6d..0f01ae89a 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone_dark.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone_dark.png index 5d90732a0..1fe072ccf 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone_dark.png and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone_dark.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png index 3dd62e765..a3d03661b 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png differ diff --git a/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index 13fbab784..8ef0d786d 100644 --- a/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -71,7 +71,7 @@ import com.google.samples.apps.nowinandroid.core.ui.userNewsResourceCardItems import com.google.samples.apps.nowinandroid.feature.topic.R.string @Composable -internal fun TopicScreen( +fun TopicScreen( showBackButton: Boolean, onBackClick: () -> Unit, onTopicClick: (String) -> Unit, @@ -212,7 +212,7 @@ private fun TopicHeader(name: String, description: String, imageUrl: String) { contentDescription = null, modifier = Modifier .align(Alignment.CenterHorizontally) - .size(216.dp) + .size(132.dp) .padding(bottom = 12.dp), ) Text(name, style = MaterialTheme.typography.displayMedium) diff --git a/gradle.properties b/gradle.properties index 7594c8ce1..e2d6e0903 100644 --- a/gradle.properties +++ b/gradle.properties @@ -38,7 +38,7 @@ org.gradle.configureondemand=false org.gradle.caching=true # Enable configuration caching between builds. -org.gradle.configuration-cache=false +org.gradle.configuration-cache=true # This option is set because of https://github.com/google/play-services-plugins/issues/246 # to generate the Configuration Cache regardless of incompatible tasks. # See https://github.com/android/nowinandroid/issues/1022 before using it. diff --git a/gradle/init.gradle.kts b/gradle/init.gradle.kts index fe79fa01e..44dc41200 100644 --- a/gradle/init.gradle.kts +++ b/gradle/init.gradle.kts @@ -14,10 +14,10 @@ * limitations under the License. */ -val ktlintVersion = "1.0.1" +val ktlintVersion = "1.4.0" initscript { - val spotlessVersion = "6.23.3" + val spotlessVersion = "6.25.0" repositories { mavenCentral() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cc523eb64..3269e2cf1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,26 +3,26 @@ accompanist = "0.34.0" androidDesugarJdkLibs = "2.0.4" # AGP and tools should be updated together androidGradlePlugin = "8.6.1" -androidTools = "31.6.1" -androidxActivity = "1.9.2" +androidTools = "31.7.2" +androidxActivity = "1.9.3" androidxAppCompat = "1.7.0" androidxBrowser = "1.8.0" -androidxComposeBom = "2024.09.00" -androidxComposeRuntimeTracing = "1.0.0-beta01" +androidxComposeBom = "2024.11.00" +androidxComposeRuntimeTracing = "1.7.5" androidxCore = "1.13.1" androidxCoreSplashscreen = "1.0.1" androidxDataStore = "1.1.1" -androidxEspresso = "3.5.1" +androidxEspresso = "3.6.1" androidxHiltNavigationCompose = "1.2.0" androidxLifecycle = "2.8.6" androidxMacroBenchmark = "1.3.0" androidxMetrics = "1.0.0-beta01" androidxNavigation = "2.8.0" androidxProfileinstaller = "1.3.1" -androidxTestCore = "1.5.0" +androidxTestCore = "1.6.1" androidxTestExt = "1.2.1" androidxTestRules = "1.6.1" -androidxTestRunner = "1.5.2" +androidxTestRunner = "1.6.2" androidxTracing = "1.3.0-alpha02" androidxUiAutomator = "2.3.0" androidxWindowManager = "1.3.0" @@ -37,7 +37,7 @@ googleOss = "17.1.0" googleOssPlugin = "0.10.6" hilt = "2.52" hiltExt = "1.2.0" -jacoco = "0.8.7" +jacoco = "0.8.12" junit4 = "4.13.2" kotlin = "2.0.20" kotlinxCoroutines = "1.9.0" @@ -50,7 +50,7 @@ protobuf = "4.28.2" protobufPlugin = "0.9.4" retrofit = "2.11.0" retrofitKotlinxSerializationJson = "1.0.0" -robolectric = "4.12.2" +robolectric = "4.11.1" roborazzi = "1.7.0" room = "2.6.1" secrets = "2.0.1" @@ -114,7 +114,6 @@ firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.r firebase-cloud-messaging = { group = "com.google.firebase", name = "firebase-messaging" } firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics" } firebase-performance = { group = "com.google.firebase", name = "firebase-perf" } -firebase-performance-gradle = { group = "com.google.firebase", name = "perf-plugin", version.ref = "firebasePerfPlugin" } google-oss-licenses = { group = "com.google.android.gms", name = "play-services-oss-licenses", version.ref = "googleOss" } google-oss-licenses-plugin = { group = "com.google.android.gms", name = "oss-licenses-plugin", version.ref = "googleOssPlugin" } hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } diff --git a/lint/build.gradle.kts b/lint/build.gradle.kts index cfda9d64d..f1722fa78 100644 --- a/lint/build.gradle.kts +++ b/lint/build.gradle.kts @@ -15,7 +15,6 @@ */ import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { `java-library` @@ -39,7 +38,7 @@ kotlin { dependencies { compileOnly(libs.kotlin.stdlib) compileOnly(libs.lint.api) + testImplementation(libs.kotlin.test) testImplementation(libs.lint.checks) testImplementation(libs.lint.tests) - testImplementation(kotlin("test")) } diff --git a/settings.gradle.kts b/settings.gradle.kts index c90c1a24a..2b8c6e45c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,7 +17,13 @@ pluginManagement { includeBuild("build-logic") repositories { - google() + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } mavenCentral() gradlePluginPortal() } @@ -26,7 +32,13 @@ pluginManagement { dependencyResolutionManagement { repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS repositories { - google() + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } mavenCentral() } } @@ -63,3 +75,11 @@ include(":lint") include(":sync:work") include(":sync:sync-test") include(":ui-test-hilt-manifest") + +check(JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { + """ + Now in Android requires JDK 17+ but it is currently using JDK ${JavaVersion.current()}. + Java Home: [${System.getProperty("java.home")}] + https://developer.android.com/build/jdks#jdk-config-in-studio + """.trimIndent() +}